メッセージの共有
プロセス間メッセージ通信
アプリケーションが、自分自身のために独自のメッセージを送信する場合は
Windows が標準で定義しているメッセージの値と衝突しなければ何でも良いと考えられます
しかし、プロセス間で特定の独自メッセージを共有したい場合は異なります
そのアプリケーションは、あなたが定義した独自メッセージをすでに使っているかもしれません
アプリケーションを特定せず、グローバルにメッセージをやり取りする場合
静的な定数ではなく、動的にシステムが使用していない一意の値を取得する必要があります
このような場合は RegisterWindowMessage() 関数を使います
この関数は、指定した文字列に基いてシステムが一意のメッセージ値を返します
UINT RegisterWindowMessage(LPCTSTR lpString);
lpString には、登録するメッセージを格納する文字列へのポインタを指定します
成功すれば、システムがまだ用いていないメッセージ値、失敗すれば 0 が返ります
lpString に、既存のメッセージ文字列を指定すれば、同じ値が返ります
つまり、プロセスが同一のメッセージ文字列をこの関数に渡すことによって
互いに、保証されたメッセージの値を受け取り、通信し合うことができるようになるのです
例えば、DLL にウィンドウのハンドルを登録することによって
DLL が何らかのイベントを処理し、メッセージを返すなどの利用が考えられます
モードレスダイアログボックスとメインウィンドウが通信するときにも使えるでしょう
#include <windows.h>
#define TITLE TEXT("Kitty on your lap")
LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
HDC hdc;
PAINTSTRUCT ps;
TCHAR strText[256];
static UINT uMessage , uCount = 0;
if (msg == uMessage) {
uCount = (UINT)wp;
InvalidateRect(hWnd , NULL , TRUE);
return 0;
}
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CREATE:
uMessage = RegisterWindowMessage(TITLE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd , &ps);
wsprintf(strText , TEXT("Count = %d") , uCount);
TextOut(hdc , 0 , 0 , strText , lstrlen(strText));
EndPaint(hWnd , &ps);
return 0;
case WM_LBUTTONUP:
PostMessage(HWND_BROADCAST , uMessage , ++uCount , 0);
return 0;
}
return DefWindowProc(hWnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow ) {
HWND hwnd;
MSG msg;
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hIcon = LoadIcon(NULL , IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL , IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpszClassName = TEXT("KITTY");
if (!RegisterClass(&winc)) return -1;
hwnd = CreateWindow(
TEXT("KITTY") , TITLE ,
WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
CW_USEDEFAULT , CW_USEDEFAULT ,
CW_USEDEFAULT , CW_USEDEFAULT ,
NULL , NULL ,
hInstance , NULL
);
if (hwnd == NULL) return -1;
while(GetMessage(&msg , NULL , 0 , 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
このプログラムは、クライアント領域を左クリックすると
静的な共有カウントが、独自のメッセージとして全てのウィンドウに通知されます
プロセスに関係なく、このメッセージを処理すればカウントを取得することができます
うえの図は、同じプログラムを2つ同時に起動しているときのものです
片方をクリックすれば、もう片方もメッセージを処理するので、カウントが同期しています
RegisterWindowMessage()
UINT RegisterWindowMessage(LPCTSTR lpString);
システムが、まだ割り当てていない一意のメッセージ値を返します
lpString - 登録するメッセージを格納する文字列へのポインタを指定します
戻り値 - システムがまだ用いていないメッセージ値、失敗すれば 0