■仕組み

 これから制作されるプログラムからどのような仕組みでステージリンクやステージ装置等を制御するかを下図を参照しながら説明します。
 

 お客さまが制作されるユーザープログラムとステージリンクとは、プロセス間でデータをやり取りできる仕組みメッセージキューを利用しており、ユーザープログラムからステージリンクへ要求メッセージを送信したりステージリンクからの応答メッセージを受信することができます。
 ステージリンクプロセスに送信できる要求メッセージには、外部で処理するものと内部で処理するものに別れ、それによって要求メッセージの流れが変わります。
 外部で処理する要求メッセージの先頭には、"#EXTERNAL#"が付いています。このメッセージを外部コマンドとして外付けのステージ装置電子顕微鏡装置にメッセージを送信し、装置からの返答を送り元のユーザープログラムに送信します。"#EXTERNAL#"が付いていないメッセージを内部コマンドとしてステージリンク内部で処理され返答メッセージを送り元のユーザープログラムに送信します。
 外部コマンドや内部コマンドの詳細は、下記の該当する見出しをご覧ください。

 ・■内部コマンドの詳細
 ・■外部コマンドの詳細


 具体的なメッセージのやり取り手順は下記をご覧ください。

 1.ユニークなメッセージIDを生成する。
   WinAPIのRegisterWindowMessage関数でシステムで唯一のメッセージIDを生成します。
   この関数の引数に "GWM_SL2008ControlAPI" を指定してください。

 2.ステージリンクのウィンドウハンドルを要求する。
   上記で生成したメッセージIDをつぎのWinAPI関数を使ってすべてのウィンドウプログラムに送信します。

 SendMessage( HWND_BROADCAST, g_uiGWM, SL_GET_HWND, (LPARAM)hWnd );

 引数名  内容
 ------------------------------------------------------------------------------------------------------
 g_uiGWM  ユニークなメッセージID
 SL_GET_HWND  WPARAM値、100を指定してください。(ウィンドウハンドルの要求)
 hWnd  自分のウィンドウハンドル

   ステージリンクでも同じメッセージIDを生成していますのでこのメッセージIDを受けとるとステージリンクのウィンドウハンドルを送信元に通知します。受けとったウィンドウハンドルを使って以降の要求/応答メッセージのやり取りが可能になります。

 3.ステージリンクへ要求メッセージを送信する。
      要求メッセージの送信は、WinAPIのWM_COPYDATAで行います。WM_COPYDATAは、WinAPIのSendMessage関数でつぎの書式を指定してステージリンクに送信します。

 SendMessage( g_hWndSL, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&stCopyData );

 引数名  内容
 ------------------------------------------------------------------------------------------------------
 g_hWndSL  ステージリンクのウィンドウハンドル
 hWnd  自分のウィンドウハンドル
 stCopyData  COPYDATASTRUCT構造体 
   stCopyData.dwData = 0;  受け取り側アプリケーションに渡す最大32ビットまでのデータを指定します。0を指定してください。
   stCopyData.cbData = strlen(szData); lpDataメンバが指すデータのサイズをバイト単位で指定します。
   stCopyData.lpData = szData; 受け取り側アプリケーションに渡すデータを指すポインタです。
 szData[20+1+500+1]; CHAR型データ配列  このエリアに内部コマンドや外部コマンドの文字列を格納します。

 送信できるコマンド文字列の最大文字数と書式はつぎのとおりです。

 ・COMMAND部の最大文字数は、20バイトまでです。
 ・PARAMETER部の最大文字数は、500バイトまでです。
 ・COMMAND部とPARAMETER部の間に一つの ' '(空白文字)が必要です。
 ・コマンド文字列の終端は、NULLが必要です。

 例:sprintf( szData, "%s %s", "COMMAND", "PARAMETER" );

   ※つぎの応答メッセージの受信処理が完了するとSendMessage関数から制御が戻ります。
   ※要求/応答メッセージの処理で時間がかかるような場合は、SendMessageTimeout関数をお試しください。

 4.ステージリンクから応答メッセージを受信する。
   上記の要求メッセージがステージリンクに届くと、要求された内部コマンドまたは外部コマンドを処理しその結果がWM_COPYDATAメッセージで通知されます。lParam(LPARAM)にセットされているCOPYDATASTRUCT構造体のlpDataメンバを参照して処理結果を確認します。

   ※応答メッセージ受信処理内で要求メッセージの送信処理は行わないでください。



#define SL_GET_HWND 100 // ウィンドウハンドル要求・ウィンドウハンドル通知
UINT g_uiGWM = 0; // プロセス間メッセージID
HWND g_hWndSL = 0; // ステージリンクのウィンドウハンドル

// ウィンドウプロシージャー
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

 switch( message)
 {
 case WM_CREATE:
  // 1.ユニークなメッセージIDを生成する。
  g_uiGWM = RegisterWindowMessage( "GWM_SL2008ControlAPI" );
  if (g_uiGWM)
  { // 2−1.ウィンドウハンドルの要求
   SendMessage( HWND_BROADCAST, g_uiGWM, SL_GET_HWND, (LPARAM)hWnd );
  }
  break;

 case WM_COMMAND: // アクション
  if (g_hWndSL)
  { // 3.要求メッセージの送信
   COPYDATASTRUCT stCopyData;
   CHAR  szData[20+1+500+1];

   // 例:sprintf( szData, "%s %s", "COMMAND", "PARAMETER" );

   stCopyData.dwData = 0;
   stCopyData.cbData = strlen(szData);
   stCopyData.lpData = szData;
   SendMessage( g_hWndSL, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&stCopyData );
  }
  break;

 case WM_COPYDATA:
  if ((HWND)wParam == g_hWndSL)
  { // 4.応答メッセージの受信
   HWND  hSendWnd    = (HWND)wParam;
   COPYDATASTRUCT* pstCopyData = (COPYDATASTRUCT*)lParam;

   // コマンド処理結果が、stCopyData.lpDataに格納されています。

   return TRUE;
  }
  break;

 default:
  if (message == g_uiGWM && (HWND)lParam != hWnd && wParam == SL_GET_HWND)
  { // 2−2.ウィンドウハンドルを取得
   g_hWndSL = (HWND)lParam;
  }
  break;
 }

 return DefWindowProc( hWnd, message, wParam, lParam );
}