ホームページ > 運用・保守 > 窓の運用と保守 > Win32 SDK の基礎 (10) いくつかの一般的な Windows メッセージ処理サンプル コードの詳細な説明

Win32 SDK の基礎 (10) いくつかの一般的な Windows メッセージ処理サンプル コードの詳細な説明

黄舟
リリース: 2017-06-06 10:07:47
オリジナル
3139 人が閲覧しました

はじめに

この記事では、主にいくつかの一般的な Windows メッセージの処理を紹介します。「Win32 SDK の基礎 (8) - Windows メッセージの仕組み」では、ウィンドウを作成する前に、WM_CREATE メッセージの処理を紹介しました。これに基づいて、この記事では、WM_DESTROY、WM_SYSCOMMAND、WM_QUIT、WM_SIZE およびその他の一般的な Windows メッセージを紹介します。まずご紹介するのは、 SDK の基礎 (8) - Windows メッセージ メカニズム」が記事内のコードであり、以降の実験はこのコードに基づいています。

#include "stdafx.h"
#include "MessageTs.h"

HINSTANCE g_hInstance = 0;  
//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break; 
	case  WM_CREATE:
		MessageBox(NULL,"WM_CREATE消息被处理了","消息处理",MB_OK);
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}  
//注册窗口类  
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)  
{  
	WNDCLASSEX wce = { 0 };  
	wce.cbSize = sizeof(wce);  
	wce.cbClsExtra = 0;  
	wce.cbWndExtra = 0;  
	wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);  
	wce.hCursor = NULL;  
	wce.hIcon = NULL;  
	wce.hIconSm = NULL;  
	wce.hInstance = g_hInstance;  
	wce.lpfnWndProc = wndProc;  
	wce.lpszClassName = lpClassName;  
	wce.lpszMenuName = NULL;  
	wce.style = CS_HREDRAW | CS_VREDRAW;  
	ATOM nAtom = RegisterClassEx(&wce);  
	if (nAtom == 0)  
		return FALSE;  
	return true;  

}  
//创建主窗口  
HWND CreateMain(LPSTR lpClassName, LPSTR lpWndName)  
{  
	HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName,  
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, NULL);  
	return hWnd;  
}  
//显示窗口  
void Display(HWND hWnd)  
{  
	ShowWindow(hWnd, SW_SHOW);  
	UpdateWindow(hWnd);  
}  
//消息循环  
void Message()  
{  
	MSG nMsg = { 0 };  
	while (GetMessage(&nMsg, NULL, 0, 0))  
	{  
		TranslateMessage(&nMsg);  
		DispatchMessage(&nMsg);  
	}  
}  
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,  
	_In_opt_ HINSTANCE hPrevInstance,  
	_In_ LPWSTR    lpCmdLine,  
	_In_ int       nCmdShow)  
{  
	// TODO: Place code here.  

	g_hInstance = hInstance;  
	BOOL nRet = Register("Main", WndProc);  
	if (!nRet)  
	{  
		MessageBox(NULL, "注册失败", "Infor", MB_OK);  
		return 0;  
	}  
	HWND hWnd = CreateMain("Main", "window");  
	Display(hWnd);  
	Message();  
	return 0;  
}
ログイン後にコピー
2. WM_CREATE メッセージ WM_CREATE メッセージについても紹介したいと思います。前回の記事では、メッセージ ボックスをポップアップ表示して WM_CREATE メッセージのタイミングを検証しただけで、その他の非常に重要なコンポーネントである WPARAM パラメーターと LPARAM パラメーターについては紹介しなかったためです。メッセージを送信するとき、多くの場合、これら 2 つのパラメーターを通じて何らかの情報を伝えることができます。 WM_CREATE メッセージは、ウィンドウの作成時にシステムによって自動的に送信されるメッセージであり、これら 2 つのパラメーターは情報を伝えるためにも使用されます。 LPARAM は、WPARAM を使用せずに作成したときの CreateWindowEx の 12 個のパラメータ情報を保持します。次に、WM_CREATE メッセージを処理するときに、ポップアップ ダイアログ ボックスにウィンドウ クラスとウィンドウ名を表示します。

//窗口处理函数  
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break; 
	case  WM_CREATE:
		{
			CREATESTRUCT crt = *((CREATESTRUCT*)lParam);
			char buf[256] = {0};
			sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName);
			MessageBox(NULL, buf, "消息处理", MB_OK);
		}
		
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}
ログイン後にコピー

プログラムを実行すると、ウィンドウが作成される前に、登録されているウィンドウのクラス名とウィンドウ名が正常にキャプチャされ、ダイアログ ボックスに表示されていることがわかりました。

3. WM_DESTROY メッセージ

これメッセージは前の記事にありましたが、実際にはすでに解決しています。 Windowsウィンドウを閉じるときに送信されるメッセージです。簡単に言うと、Windowsウィンドウの閉じるボタン

をクリックすると、このメッセージが送信されます。前のコードでは、このメッセージを処理する操作は PostQuitMessage(0) でした。これは実際には、次に導入される WM_QUIT メッセージを送信してプログラム プロセスを終了することを意味します。 WM_DESTORY メッセージの LPARAM も WPARAM も使用されません。通常、ウィンドウを閉じる前にリソースのリサイクルとメモリの解放を行うために使用されます。PostQuitMessage(0) は非常に一般的な使用法です。

4. WM_QUIT メッセージ

すでに紹介したように、これはプログラムのプロセスを終了するために PostQuitMessage(0) を使用して送信するメッセージです。その WMPARAM は PostQuitMessage で渡されるパラメーターであり、LPARAM パラメーターは使用されません。通常、WM_QUIT を送信すると、メッセージ ループ内の GetMessage 関数が戻り、プロセスが終了します。 WM_QUIT メッセージを独自のウィンドウ処理関数に渡すことはできません。しかし、そのようなメッセージがあることを側から確認できます。まず、コードに WM_QUIT メッセージの処理を追加します。

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
	switch (uMsg)  
	{  
	case WM_DESTROY:  
		PostQuitMessage(0);//可以使GetMessage返回0  
		break; 
	case  WM_CREATE:
	{
		CREATESTRUCT crt = *((CREATESTRUCT*)lParam);
		char buf[256] = {0};
		sprintf(buf,"创建的窗口类名称是%s,窗口名称是%s",crt.lpszClass,crt.lpszName);
		MessageBox(NULL, buf, "消息处理", MB_OK);
	}
	case WM_QUIT:
	{
		int param = (int)wParam;
		char buf[256];
		sprintf(buf, "进程退出,退出码:%d", param);
		MessageBox(NULL, buf, "消息处理", MB_OK);
	}
	default:  
		break;  
	}  
	return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}
ログイン後にコピー
プログラムを実行すると、WM_CREATE メッセージを処理するためのダイアログ ボックスを閉じた後、WM_QUIT メッセージを確認するためのダイアログ ボックスがポップアップ表示されることがわかりました。

これは、WM_CREATE メッセージを処理するためにポップアップする MessageBox もウィンドウですが、私たちのプロセスに属しているためです。各ウィンドウにはメッセージ ループがありますが、メッセージ キューはプロセスごとに 1 つだけです。MessageBox ウィンドウが閉じられると、そのウィンドウ処理関数も PostQuitMessage(0) を呼び出して WM_QUIT メッセージを送信します。メッセージ ループでは、GetMessage は WM_QUIT メッセージを受信した後に戻り、終了します。このメッセージはメッセージ ループによってキャプチャされますが、ウィンドウによって送信されたメッセージではないため、ループを終了するために GetMessage が返されることはなく、代わりに渡されたウィンドウ処理関数によって要約されて処理されます。上のスクリーンショットに示すダイアログ ボックスが表示されます。 5. WM_SYSCOMMAND メッセージ

システム コマンド メッセージ。このメッセージは、最大化、最小化、および閉じるコマンドをクリックするとトリガーされます (したがって、閉じるボタンをクリックすると、WM_DESTROY メッセージと WM_SYSCOMMAND メッセージの両方が同時にトリガーされます)。その wParam パラメータには特定のウィンドウ操作が含まれます:

Close:

SC_CLOSE

Maximize:

SC_MAXIMIZE

Minimize: SC_MINIMIZE

这里只列举了三种常见的WM_SYSCOMMAND携带的参数宏,其它的可以参照MSDN。WM_SYSCOMMAND的lParam携带的是产生该消息的鼠标的位置,位置的X和Y坐标分别被存放在lParam的低位和高位字中,我们用下面的代码来验证在窗口最大化时,我们鼠标的位置:

case WM_SYSCOMMAND:
	{
		if (wParam == SC_MAXIMIZE)
		{
			short x = LOWORD(lParam);
			short y = HIWORD(lParam);
			char buf[256];
			sprintf(buf, "窗口最大化,x坐标:%d,y坐标:%d", x,y);
			MessageBox(NULL, buf, "消息处理", MB_OK);
		}
	}
ログイン後にコピー

当我们点击窗口的最大化按钮时,出现下面的提示:



六 WM_SIZE消息

每当我们调整窗口的大小时,都会触发WM_SIZE消息。它的wParam参数携带的是该消息产生的原因:

SIZE_RESTORED —— 重新调整窗口大小

SIZE_MAXIMIZED —— 最大化显示

SIZE_ MINIMIZED —— 最小化显示

其他参数宏详见MSDN

它的lParam参数携带的是重新调整大小后的窗口的高和宽,其中低字节代表宽,高字节代表高,这里我们通过代码验证,当窗口最大化后窗口的高和宽:

case WM_SIZE:
	{
		if (wParam == SIZE_MAXIMIZED)
		{
			short width = LOWORD(lParam);
			short hight = HIWORD(lParam);
			char buf[256];
			sprintf(buf, "窗口最大化,高度:%d,宽度:%d", hight, width);
			MessageBox(NULL, buf, "消息处理", MB_OK);
		}
	}
ログイン後にコピー

        运行程序,最大化时可以显示最大化后的窗口高度和宽度:


以上がWin32 SDK の基礎 (10) いくつかの一般的な Windows メッセージ処理サンプル コードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート