文章目录
第一步:定义你的窗口是什么样的?(创建,初始化,注册窗口类)
窗口的类名:
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);
}