Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Win32 SDK-Grundlagen (10) Detaillierte Erläuterung mehrerer gängiger Beispielcodes für die Windows-Nachrichtenverarbeitung

Win32 SDK-Grundlagen (10) Detaillierte Erläuterung mehrerer gängiger Beispielcodes für die Windows-Nachrichtenverarbeitung

黄舟
黄舟Original
2017-06-06 10:07:473062Durchsuche

Einführung

In diesem Artikel wird hauptsächlich die Verarbeitung mehrerer allgemeiner Nachrichten in Windows vorgestellt. In „Win32 SDK Basics (8) – Windows Message Mechanism“ haben wir die Verarbeitung von WM_CREATE-Nachrichten bei der Fenstererstellung eingeführt. Wir haben die Nachrichtenverarbeitungsfunktion verwendet, um eine MessageBox anzuzeigen. Auf dieser Grundlage werden in diesem Artikel WM_DESTROY, WM_SYSCOMMAND, WM_QUIT, WM_SIZE und andere andere gängige Windows-Nachrichten vorgestellt. Zuerst stellen wir vor „SDK-Grundlagen (8) – Windows-Nachrichtenmechanismus“ ist der Code im Artikel, und nachfolgende Experimente basieren auf diesem Code.

2. WM_CREATE-Nachricht
#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;  
}

Wir möchten noch die WM_CREATE-Nachricht einführen. Denn im vorherigen Artikel haben wir nur das Timing der WM_CREATE-Nachricht überprüft, indem wir die MessageBox geöffnet haben, aber die anderen sehr wichtigen Komponentenparameter WPARAM und LPARAM nicht eingeführt. Wenn wir

eine Nachricht senden

, können wir oft einige Informationen über diese beiden Parameter übertragen. Die WM_CREATE-Nachricht ist eine Nachricht, die vom System automatisch gesendet wird, wenn wir ein Fenster erstellen. Diese beiden Parameter werden auch zum Übertragen von Informationen verwendet. LPARAM trägt die 12 Parameterinformationen von CreateWindowEx, als wir das Fenster erstellt haben. Wenn wir als Nächstes die WM_CREATE-Nachricht verarbeiten, zeigen wir die Fensterklasse und den Fensternamen im Popup-Dialogfeld an.

Beim Ausführen des Programms haben wir festgestellt, dass wir den registrierten Fensterklassennamen und den Fensternamen des Fensters vor der Erstellung des Fensters erfolgreich erfasst und im Dialogfeld angezeigt haben:
//窗口处理函数  
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-Meldung

Diese Meldung haben wir bereits im vorherigen Artikel gelöst. Es handelt sich um eine Nachricht, die gesendet wird, wenn das Windows-Fenster geschlossen wird. Vereinfacht gesagt wird diese Nachricht gesendet, wenn Sie auf die Schaltfläche „Schließen“

des Windows-Fensters klicken. In unserem vorherigen Code war die Operation zum Verarbeiten dieser Nachricht PostQuitMessage(0). Dies bedeutet tatsächlich, dass wir eine WM_QUIT-Nachricht gesendet haben, die als nächstes eingeführt werden soll, um den Programmprozess zu beenden. Weder LPARAM noch WPARAM der WM_DESTORY-Nachricht werden verwendet, um vor dem Schließen des Fensters einige Ressourcen zu recyceln und Speicher freizugeben. Der von uns aufgerufene PostQuitMessage(0) ist eine sehr häufige Verwendung.

4. WM_QUIT-Nachricht

Wie wir bereits vorgestellt haben, ist dies eine Nachricht, die wir mit PostQuitMessage(0) senden, um den Programmprozess zu beenden. Ihr WMPARAM ist der in PostQuitMessage übergebene Parameter Parameter wird nicht verwendet. Normalerweise führt das Senden von WM_QUIT dazu, dass die GetMessage-Funktion in der Nachrichtenschleife zurückkehrt, wodurch der Prozess

beendet wird

. Die WM_QUIT-Nachricht kann nicht an unsere eigene Fensterverarbeitungsfunktion übergeben werden. Aber wir können von außen überprüfen, dass es eine solche Nachricht gibt: Wir fügen zunächst die Verarbeitung der WM_QUIT-Nachricht in den Code ein.

Führen Sie das Programm aus. Nachdem wir das Dialogfeld zur Verarbeitung der WM_CREATE-Nachricht geschlossen hatten, wurde das Dialogfeld zur Überprüfung der WM_QUIT-Nachricht angezeigt.

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);  
}

Dies liegt daran, dass die MessageBox, die zum Verarbeiten der WM_CREATE-Nachricht angezeigt wird, ebenfalls ein Fenster ist, aber zu unserem Prozess gehört. Jedes Fenster verfügt über eine Nachrichtenschleife, es gibt jedoch nur eine Nachrichten-

-Warteschlange

pro Prozess. Wenn das MessageBox-Fenster geschlossen wird, ruft seine Fensterverarbeitungsfunktion auch PostQuitMessage(0) auf, um eine WM_QUIT-Nachricht zu senden. In seiner Nachrichtenschleife kehrt GetMessage nach dem Empfang der WM_QUIT-Nachricht zurück und wird beendet. Diese Nachricht wird von unserer Nachrichtenschleife erfasst, aber da es sich nicht um eine von unserem Fenster gesendete Nachricht handelt, führt sie nicht dazu, dass unsere GetMessage zurückkehrt, um die Schleife zu beenden. Stattdessen wird sie zur Zusammenfassungsverarbeitung an unsere Fensterverarbeitungsfunktion übergeben. Es erscheint also das im Screenshot oben gezeigte Dialogfeld.

5. WM_SYSCOMMAND-Meldung

Systembefehlsmeldung, diese Meldung wird ausgelöst, wenn wir auf die Befehle „Maximieren“, „Minimieren“ und „Schließen“ klicken (wenn wir also auf die Schaltfläche „Schließen“ klicken, werden WM_DESTROY und WM_SYSCOMMAND ausgelöst gleichzeitig) Zwei Neuigkeiten). Sein wParam-Parameter trägt spezifische Fensteroperationen:

Schließen:

SC_CLOSE

Maximieren:

SC_MAXIMIZE

Minimieren:

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);
		}
	}

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


Das obige ist der detaillierte Inhalt vonWin32 SDK-Grundlagen (10) Detaillierte Erläuterung mehrerer gängiger Beispielcodes für die Windows-Nachrichtenverarbeitung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn