My First Window构造过程,SendMessage同步,PostMessage异步

第一步:定义你的窗口是什么样的?(创建,初始化,注册窗口类)

窗口的类名:

PSTR classname = (PSTR)"My First Window";

创建窗口类的对象:

WNDCLASS  wndclass = {
    
     0 };		//一定要将所有值赋值

wndclass.hbrBackground = (HBRUSH)COLOR_MENU;//窗口背景色

wndclass.lpfnWndProc = WindowProc;//窗口过程函数(注册回调函数)

wndclass.lpszClassName = classname;//窗口类的名字

wndclass.hInstance = hInstance;//定义窗口类 的应用程序的实例句柄



//注册窗口类
//参见MSDN文档RegisterClass-->Parameters
//You must fill the structure with appropriate class attributes
//before passing it to the function

RegisterClass(&wndclass);

第二步:创建并显示窗口

HWND hwnd = CreateWindow(
		classname,//类名
		"我的第一个窗口",//窗口标题
		WS_OVERLAPPEDWINDOW,//窗口外观样式
		10,//相对于父窗口的x坐标
		10,//相对于父窗口的y坐标
		800,//窗口的宽度
		400,//窗口的高度
		NULL,//父窗口句柄
		NULL,//菜单句柄
		hInstance,//当前应用程序句柄
		NULL);//附加数据,一般为MULL


	//显示窗口
	ShowWindow(hwnd, SW_SHOW);

第三步:接收消息并处理(处理的话也就是完成回调函数初始化)

MSG msg;

	while (GetMessage(&msg, NULL, 0, 0)) {
    
    
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

回调函数初始化:

LRESULT  CALLBACK WindowProc(
	IN  HWND hwnd,
	IN	UINT uMsg,
	IN	WPARAM	wParan,
	IN	LPARAM	lParam
) {
    
    
	//获取dialog句柄
	TCHAR szBuff[0x20];
	GetClassName(hwnd, szBuff, 0x20);

	WNDCLASS wc;

	GetClassInfo(hAppInstance, szBuff, &wc);

	//PDWORD addr=(PDWORD)wc.IpfnWndProc;

	DWORD addr = GetWindowLong(hwnd, GWL_WNDPROC);

	DWORD error = GetLastError();

	//获取线程ID
	DWORD dwThreadId = GetCurrentThreadId();

	switch (uMsg)
	{
    
    

	case WM_DESTROY:
	{
    
    
		PostQuitMessage(0);
		return 0;
	}
	case 0x401:
	{
    
    
		strcpy_s(szBuff, "接到其它程序发送的消息!!!");
		MessageBox(hwnd, szBuff, "--", MB_OK);
		return 0;

	}

	/*case WM_KEYDOWN:
	{
		sprintf_s(szBuff, "你按下了%d键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;
	}*/

	case WM_CHAR:
		sprintf_s(szBuff, "你按下了%c键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;

	default:
		break;
	}

	return DefWindowProc(hwnd, uMsg, wParan, lParam);
}

前面已经解释过,这个DispatchMessage(&msg);GetMessage(&msg, NULL, 0, 0),这里就来解释一下TranslateMessage(&msg);,这个API主要针对WM_CHAR这个键盘消息的,

TranslateMessage(&msg);

处理键盘消息(WM_CHAR),这个消息进行字符转换的,(把键盘上的65转换为字符a,仅此而已,也就对键盘消息进行键盘消息加工作用

举例:

保留着TranslateMessage(&msg);接收消息用代码

case WM_CHAR:
		sprintf_s(szBuff, "你按下了%c键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;

运行截图如下:
在这里插入图片描述
注释掉TranslateMessage(&msg);接收消息用代码

case WM_CHAR:
		sprintf_s(szBuff, "你按下了%c键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;

运行截图如下,没反应,是因为回调函数没有接收到消息吗?那接下来我们来验证一下
在这里插入图片描述
注释掉TranslateMessage(&msg);接收消息用代码

case WM_KEYDOWN:
	{
    
    
		sprintf_s(szBuff, "你按下了%d键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;

运行截图如下:
在这里插入图片描述
好了,现在大家心里都清楚了吧

默认的消息处理函数:

 DefWindowProc(hwnd, uMsg, wParan, lParam);

对其它我们不需要关注的消息进行处理

SendMessage同步

在这里插入图片描述
当我们未点击确定时,发送消息的程序未退出,需要点击确定后,发送消息的程序收到返回消息,它才会自行退出。这也就是SendMessage的同步问题

PostMessage异步

在这里插入图片描述
PostMessage发送完消息后,程序即刻退出,并不会等待处理结果,这也就是PostMessage发送消息异步问题

窗口完整代码


#include "framework.h"
#include "窗口过程.h"
#include<stdio.h>
HINSTANCE hAppInstance;
#define MAX_LOADSTRING 100

LRESULT  CALLBACK WindowProc(
	IN  HWND hwnd,
	IN	UINT uMsg,
	IN	WPARAM	wParan,
	IN	LPARAM	lParam
);
void CreateButton(HWND hwnd);


int APIENTRY WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR	IpCmdLine,
	int		nCmdShow) {
    
    

	//把这个参数变为全局的,下面的函数会用到
	hAppInstance = hInstance;

	//窗口的类名
	PSTR classname = (PSTR)"My First Window";

	//创建窗口类的对象
	WNDCLASS  wndclass = {
    
     0 };		//一定要将所有值赋值
	wndclass.hbrBackground = (HBRUSH)COLOR_MENU;//窗口背景色

	wndclass.hCursor = LoadCursor(NULL, IDC_APPSTARTING);

	wndclass.lpfnWndProc = WindowProc;//窗口过程函数

	wndclass.lpszClassName = classname;//窗口类的名字

	wndclass.hInstance = hInstance;//定义窗口类的应用程序的实例句柄

	//注册窗口类
	//参见MSDN文档RegisterClass-->Parameters
	//You must fill the structure with appropriate class attributes
	//before passing it to the function

	RegisterClass(&wndclass);
  
	//创建窗口
	HWND hwnd = CreateWindow(
		classname,//类名
		"我的第一个窗口",//窗口标题
		WS_OVERLAPPEDWINDOW,//窗口外观样式
		10,//相对于父窗口的x坐标
		10,//相对于父窗口的y坐标
		800,//窗口的宽度
		400,//窗口的高度
		NULL,//父窗口句柄
		NULL,//菜单句柄
		hInstance,//当前应用程序句柄
		NULL);//附加数据,一般为MULL

	if (hwnd == NULL) {
    
    

		OutputDebugString("输出错误");
	}

	//显示窗口
	ShowWindow(hwnd, SW_SHOW);

	MSG msg;

	while (GetMessage(&msg, NULL, 0, 0)) {
    
    
		//TranslateMessage(&msg);
		//DispatchMessage(&msg);
	}
	return 0;
	
}
LRESULT  CALLBACK WindowProc(
	IN  HWND hwnd,
	IN	UINT uMsg,
	IN	WPARAM	wParan,
	IN	LPARAM	lParam
) {
    
    
	//获取dialog句柄
	TCHAR szBuff[0x20];
	GetClassName(hwnd, szBuff, 0x20);

	WNDCLASS wc;

	GetClassInfo(hAppInstance, szBuff, &wc);

	//PDWORD addr=(PDWORD)wc.IpfnWndProc;

	DWORD addr = GetWindowLong(hwnd, GWL_WNDPROC);

	DWORD error = GetLastError();

	//获取线程ID
	DWORD dwThreadId = GetCurrentThreadId();

	switch (uMsg)
	{
    
    

	case WM_DESTROY:
	{
    
    
		PostQuitMessage(0);
		return 0;
	}
	case 0x401:
	{
    
    
		strcpy_s(szBuff, "接到其它程序发送的消息!!!");
		MessageBox(hwnd, szBuff, "--", MB_OK);
		return 0;

	}
	case WM_KEYDOWN:
	{
    
    
		sprintf_s(szBuff, "你按下了%d,%d键", wParan, lParam);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;
	}

	/*case WM_CHAR:
		sprintf_s(szBuff, "你按下了%c键", wParan);
		MessageBox(hwnd, szBuff, "---", 0);
		return 0;
		*/
	default:
		break;
	}

	return DefWindowProc(hwnd, uMsg, wParan, lParam);
}

运行截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CSNN2019/article/details/113832586
今日推荐