Jadual Kandungan
一 引言
 二、WM_CREATE消息
三、WM_DESTROY消息
四、WM_QUIT消息
五、WM_SYSCOMMAND消息
六 WM_SIZE消息
Rumah Operasi dan penyelenggaraan operasi dan penyelenggaraan tingkap Win32 SDK基础(十)之详解几种常见的Windows消息处理的示例代码

Win32 SDK基础(十)之详解几种常见的Windows消息处理的示例代码

Jun 06, 2017 am 10:07 AM

一 引言

        本文主要介绍几种Windows常见的消息的处理,在《Win32 SDK基础(8)—— Windows消息机制》中,我们介绍了WM_CREATE消息的处理,在窗口创建之前,我们利用消息处理函数弹出了一个MessageBox,本文在此基础之上,介绍WM_DESTROY、WM_SYSCOMMAND、WM_QUIT、WM_SIZE等其它常见的Windows消息。首先,我们引入在《Win32 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;  
}
Salin selepas log masuk

二、WM_CREATE消息

我们还是要再介绍下WM_CREATE消息。因为在上一文中我们只通过弹出MessageBox验证了WM_CREATE消息的产生时机,却没有介绍它另外一个很重要的构成——WPARAM和LPARAM参数。我们在发送消息时,往往可以通过这两个参数携带一些信息。WM_CREATE消息是我们在创建窗口时由系统自动发送的消息,同样也会利用这两个参数携带信息。LPARAM携带了我们创建窗口的CreateWindowEx的12个参数信息,WPARAM没有被使用,下面我们在处理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);  
}
Salin selepas log masuk

运行程序,我们发现在窗口创建之前我们成功捕获了窗口的注册窗口类名称和窗口名称,并在对话框上显示出来:

三、WM_DESTROY消息

这个消息在之前的文章中我们其实早已经解除过。他是Windows窗口关闭时发送的一个消息,简单点说就是,当你点击Windows窗口的关闭按钮时,会发出这个消息。我们在之前的代码中,处理这个消息的操作是PostQuitMessage(0),这其实是我们发送了一个接下来要介绍的WM_QUIT消息用来结束程序的进程。WM_DESTORY消息的LPARAM和WPARAM都没被使用,它一般被用来做一些窗口关闭前资源的回收和内存的释放工作等等,我们调用的PostQuitMessage(0)就是一个很常见的用法。

四、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);  
}
Salin selepas log masuk

运行程序,在关闭处理WM_CREATE消息的对话框后,发现弹出了我们验证WM_QUIT消息的对话框。

这是因为,弹出的处理WM_CREATE消息MessageBox也是一个窗口,但它属于我们的进程。每个窗口都有一个消息循环,但是消息队列一个进程却只有一个,当MessageBox的窗口关闭时,它的窗口处理函数也调用PostQuitMessage(0)发送了一个WM_QUIT消息。它的消息循环中GetMessage接收到WM_QUIT消息后返回并退出。而这个消息又会被我们的消息循环捕获到,但是由于它不是我们的窗口发出的消息,所以不会导致我们的GetMessage返回结束循环,反而被传给我们的窗口处理函数汇总进行处理,所以出现了上面截图显示的对话框。

五、WM_SYSCOMMAND消息

系统命令消息,当我们点击最大化、最小化和关闭命令时会触发这个消息(这么说来点击关闭按钮时会同时触发WM_DESTROY和WM_SYSCOMMAND两个消息哦)。它的wParam参数携带了具体的窗口操作:

关闭:SC_CLOSE

最大化:SC_MAXIMIZE

最小化: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);
		}
	}
Salin selepas log masuk

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



六 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);
		}
	}
Salin selepas log masuk

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


Atas ialah kandungan terperinci Win32 SDK基础(十)之详解几种常见的Windows消息处理的示例代码. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bolehkah saya memasang mysql pada windows 7 Bolehkah saya memasang mysql pada windows 7 Apr 08, 2025 pm 03:21 PM

Ya, MySQL boleh dipasang pada Windows 7, dan walaupun Microsoft telah berhenti menyokong Windows 7, MySQL masih serasi dengannya. Walau bagaimanapun, perkara berikut harus diperhatikan semasa proses pemasangan: Muat turun pemasang MySQL untuk Windows. Pilih versi MySQL yang sesuai (komuniti atau perusahaan). Pilih direktori pemasangan yang sesuai dan set aksara semasa proses pemasangan. Tetapkan kata laluan pengguna root dan simpan dengan betul. Sambung ke pangkalan data untuk ujian. Perhatikan isu keserasian dan keselamatan pada Windows 7, dan disyorkan untuk menaik taraf ke sistem operasi yang disokong.

Bagaimana untuk mempercepatkan kelajuan pemuatan PS? Bagaimana untuk mempercepatkan kelajuan pemuatan PS? Apr 06, 2025 pm 06:27 PM

Menyelesaikan masalah Permulaan Photoshop Perlahan memerlukan pendekatan berbilang arah, termasuk: menaik taraf perkakasan (memori, pemacu keadaan pepejal, CPU); menyahpasang pemalam yang sudah lapuk atau tidak serasi; membersihkan sampah sistem dan program latar belakang yang berlebihan dengan kerap; menutup program yang tidak relevan dengan berhati -hati; Mengelakkan membuka sejumlah besar fail semasa permulaan.

Cara menyelesaikan MySQL tidak dapat menyambung ke tuan rumah tempatan Cara menyelesaikan MySQL tidak dapat menyambung ke tuan rumah tempatan Apr 08, 2025 pm 02:24 PM

Sambungan MySQL mungkin disebabkan oleh sebab -sebab berikut: Perkhidmatan MySQL tidak dimulakan, firewall memintas sambungan, nombor port tidak betul, nama pengguna atau kata laluan tidak betul, alamat pendengaran di my.cnf dikonfigurasi dengan tidak wajar, dan lain -lain. Langkah -langkah penyelesaian masalah termasuk: 1. 2. Laraskan tetapan firewall untuk membolehkan MySQL mendengar port 3306; 3. Sahkan bahawa nombor port adalah konsisten dengan nombor port sebenar; 4. Periksa sama ada nama pengguna dan kata laluan betul; 5. Pastikan tetapan alamat mengikat di my.cnf betul.

Penyelesaian kepada kesilapan yang dilaporkan oleh MySQL pada versi sistem tertentu Penyelesaian kepada kesilapan yang dilaporkan oleh MySQL pada versi sistem tertentu Apr 08, 2025 am 11:54 AM

Penyelesaian kepada ralat pemasangan MySQL adalah: 1. Berhati -hati memeriksa persekitaran sistem untuk memastikan keperluan perpustakaan ketergantungan MySQL dipenuhi. Sistem operasi dan keperluan versi yang berbeza adalah berbeza; 2. Berhati -hati membaca mesej ralat dan mengambil langkah -langkah yang sepadan mengikut arahan (seperti fail perpustakaan yang hilang atau kebenaran yang tidak mencukupi), seperti memasang kebergantungan atau menggunakan arahan sudo; 3 Jika perlu, cuba pasang kod sumber dan periksa dengan teliti log kompilasi, tetapi ini memerlukan pengetahuan dan pengalaman Linux tertentu. Kunci untuk menyelesaikan masalah akhirnya adalah dengan teliti memeriksa persekitaran sistem dan maklumat ralat, dan merujuk kepada dokumen rasmi.

Cara menarik garis rujukan menegak PS Cara menarik garis rujukan menegak PS Apr 06, 2025 pm 08:18 PM

Tarik panduan menegak di Photoshop: Membolehkan pandangan penguasa (Lihat & gt; penguasa). Tuding tetikus di atas pinggir menegak penguasa, dan kemudian kursor menjadi garis menegak dengan anak panah berganda dan tahan dan seret tetikus untuk mengeluarkan garisan rujukan. Klik Padam dengan menyeret panduan, atau melayang ke salib.

Mysql tidak dapat dipasang setelah memuat turun Mysql tidak dapat dipasang setelah memuat turun Apr 08, 2025 am 11:24 AM

Sebab utama kegagalan pemasangan MySQL adalah: 1. Isu kebenaran, anda perlu menjalankan sebagai pentadbir atau menggunakan perintah sudo; 2. Ketergantungan hilang, dan anda perlu memasang pakej pembangunan yang relevan; 3. Konflik pelabuhan, anda perlu menutup program yang menduduki port 3306 atau mengubah suai fail konfigurasi; 4. Pakej pemasangan adalah korup, anda perlu memuat turun dan mengesahkan integriti; 5. Pembolehubah persekitaran dikonfigurasikan dengan salah, dan pembolehubah persekitaran mesti dikonfigurasi dengan betul mengikut sistem operasi. Selesaikan masalah ini dan periksa dengan teliti setiap langkah untuk berjaya memasang MySQL.

Tidak dapat mengakses MySQL dari terminal Tidak dapat mengakses MySQL dari terminal Apr 08, 2025 pm 04:57 PM

Tidak dapat mengakses MySQL dari terminal mungkin disebabkan oleh: perkhidmatan MySQL tidak berjalan; ralat perintah sambungan; kebenaran yang tidak mencukupi; sambungan blok firewall; Ralat fail konfigurasi MySQL.

Cara menyalin dan tampal mysql Cara menyalin dan tampal mysql Apr 08, 2025 pm 07:18 PM

Salin dan tampal di MySQL termasuk langkah -langkah berikut: Pilih data, salin dengan Ctrl C (Windows) atau Cmd C (Mac); Klik kanan di lokasi sasaran, pilih Paste atau gunakan Ctrl V (Windows) atau CMD V (MAC); Data yang disalin dimasukkan ke dalam lokasi sasaran, atau menggantikan data sedia ada (bergantung kepada sama ada data sudah ada di lokasi sasaran).

See all articles