Maison  >  Article  >  Opération et maintenance  >  Bases du SDK Win32 (10) Explication détaillée de plusieurs exemples de codes courants de traitement des messages Windows

Bases du SDK Win32 (10) Explication détaillée de plusieurs exemples de codes courants de traitement des messages Windows

黄舟
黄舟original
2017-06-06 10:07:473000parcourir

Introduction

Cet article présente principalement le traitement de plusieurs messages courants sous Windows. Dans "Win32 SDK Basics (8) - Windows Message Mechanism", nous avons introduit le traitement des messages WM_CREATE, dans la création de fenêtres. Auparavant, nous avons utilisé la fonction de traitement des messages pour faire apparaître une MessageBox. Sur cette base, cet article présente WM_DESTROY, WM_SYSCOMMAND, WM_QUIT, WM_SIZE et d'autres autres messages Windows courants. Tout d'abord, nous introduisons le SDK Basics (8) - Windows Message Mechanism" est le code de l'article, et les expériences ultérieures sont basées sur ce code.

#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. Message WM_CREATE

Nous souhaitons toujours introduire le message WM_CREATE. Parce que dans l'article précédent, nous avons uniquement vérifié le timing du message WM_CREATE en faisant apparaître la MessageBox, mais nous n'avons pas introduit ses autres paramètres de composants très importants : WPARAM et LPARAM. Lorsque nous

envoyons un message, nous pouvons souvent transporter certaines informations via ces deux paramètres. Le message WM_CREATE est un message envoyé automatiquement par le système lorsque l'on crée une fenêtre, et ces deux paramètres servent également à véhiculer des informations. LPARAM transporte les 12 informations de paramètres de CreateWindowEx lorsque nous avons créé la fenêtre. WPARAM n'est pas utilisé. Ensuite, lorsque nous traiterons le message WM_CREATE, nous afficherons la classe de fenêtre et le nom de la fenêtre dans la boîte de dialogue contextuelle.

//窗口处理函数  
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);  
}
En exécutant le programme, nous avons constaté que nous avions réussi à capturer le nom de classe de fenêtre enregistré et le nom de la fenêtre avant la création de la fenêtre, et à l'afficher dans la boîte de dialogue :

3. Message WM_DESTROY

Nous avons déjà résolu ce message dans l'article précédent. Il s'agit d'un message envoyé lorsque la fenêtre Windows est fermée. Pour faire simple, lorsque vous cliquez sur le bouton de fermeture

de la fenêtre Windows, ce message sera envoyé. Dans notre code précédent, l'opération pour traiter ce message était PostQuitMessage(0). Cela signifie en fait que nous avons envoyé un message WM_QUIT à introduire ensuite pour terminer le processus du programme. Ni LPARAM ni WPARAM du message WM_DESTORY ne sont utilisés pour effectuer un recyclage de ressources et une libération de mémoire avant la fermeture de la fenêtre. Le PostQuitMessage(0) que nous appelons est une utilisation très courante.

4. Message WM_QUIT

Comme nous l'avons déjà présenté, il s'agit d'un message que nous envoyons en utilisant PostQuitMessage(0) pour terminer le processus du programme. Son WMPARAM est le paramètre passé dans PostQuitMessage , le LPARAM. Le paramètre n’est pas utilisé. Normalement, après avoir envoyé WM_QUIT, la fonction GetMessage dans la boucle de messages sera renvoyée, provoquant la sortie du processus

. Le message WM_QUIT ne peut pas être transmis à notre propre fonction de traitement de fenêtre. Mais nous pouvons vérifier qu'il existe un tel message de côté : Nous ajoutons d'abord le traitement du message WM_QUIT dans le code.

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);  
}
Exécutez le programme. Après avoir fermé la boîte de dialogue de traitement du message WM_CREATE, nous avons constaté que la boîte de dialogue permettant de vérifier le message WM_QUIT est apparue.

En effet, la MessageBox qui apparaît pour traiter le message WM_CREATE est également une fenêtre, mais elle appartient à notre processus. Chaque fenêtre a une boucle de messages, mais il n'y a qu'une seule

file d'attente de messages par processus. Lorsque la fenêtre MessageBox est fermée, sa fonction de traitement de fenêtre appelle également PostQuitMessage(0) pour envoyer un message WM_QUIT. Dans sa boucle de messages, GetMessage revient et se termine après avoir reçu le message WM_QUIT. Ce message sera capturé par notre boucle de messages, mais comme il ne s'agit pas d'un message envoyé par notre fenêtre, il ne provoquera pas le retour de notre GetMessage pour terminer la boucle, mais sera résumé et traité par la fonction de traitement de fenêtre transmise. nous, ainsi il apparaît. La boîte de dialogue affichée dans la capture d'écran ci-dessus apparaît.

5. Message WM_SYSCOMMAND

Message de commande système, ce message sera déclenché lorsque nous cliquons sur les commandes maximiser, minimiser et fermer (donc lorsque nous cliquons sur le bouton de fermeture, WM_DESTROY et WM_SYSCOMMAND seront déclenchés en même temps Deux nouvelles). Son paramètre wParam effectue des opérations de fenêtre spécifiques :

Fermer : SC_CLOSE

Maximiser : SC_MAXIMIZE

Réduire : 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);
		}
	}

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


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn