接:Windows --- 常用消息以及消息附加参数_小雪菜本菜的博客-CSDN博客_windows 常用消息
如果处理了,一般情况下返回值要返回 0,如果 return 0;都将会交给系统,最终系统还会给你处理一遍(不管你是怎么处理的)
你处理的它会给你显示,你处理完之后,系统内部可能还有一些其他情况要处理
一般处理完后必须 return 0;系统还会给你处理
如果 return1;告诉系统你已经处理了,系统不会给你再处理
直接 return 0;也会调用系统的默认处理:关闭的过程中,没有调用 DestroyWindow 发出 WM_DESTROY 信息,系统会帮你自动调用
PostQuitMessage(0);发出一个退出消息 WM_QUIT→ 传入 0 正常退出
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//窗口关闭消息
case WM_CLOSE:
if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
{
//销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
//DestroyWindow(hWnd);
//最终系统都会给你处理一遍
return 0;
}
else
{ //如果不执行break
break;
}
break;
//窗口销毁消息
case WM_DESTROY:
//发出一个退出消息 WM_QUIT-> 传入0正常退出
PostQuitMessage(0);
break;
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
没有发出 WM_QUIT 消息,窗口销毁了,但是程序进程没有退出
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//窗口关闭消息
case WM_CLOSE:
if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
{
//销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
DestroyWindow(hWnd);
//最终系统都会给你处理一遍
return 0;
}
else
{ //如果不执行break
break;
}
break;
//窗口销毁消息
case WM_DESTROY:
//我已经处理了,不需要你再处理了 导致下面没有发出 WM_QUIT 消息
return 1;
//发出一个退出消息 WM_QUIT-> 传入0正常退出 要让程序退出必须调用 PostQuitMessage(0)
PostQuitMessage(0);
break;
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
鼠标点击消息
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//鼠标左键按下
case WM_LBUTTONDOWN:
{
SetWindowText(hWnd,L"鼠标左键按下了");
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//鼠标左键按下
case WM_LBUTTONDOWN:
{
//字符串
wchar_t szText[100] = {0};
//注意不能用等号的方式:应该用& 由于按下的时候,可能同时按下几个键:按ctrl、shift键...
//鼠标左键按下 + Ctrl键
if(wParam & MK_CONTROL)
{
//窄字符:strcat
//宽字符:wcscat
wcscat(szText,L"鼠标左键+Ctrl键按下");
}
//SetWindowText(hWnd,szText);
//鼠标左键按下 + Shift键
if(wParam & MK_SHIFT)
{
wcscat(szText,L"鼠标左键+Shift键按下");
}
//鼠标左键按下
if(wParam & MK_LBUTTON)
{
wcscat(szText,L"鼠标左键按下");
}
//鼠标右键按下
if(wParam & MK_RBUTTON)
{
wcscat(szText,L"鼠标右键按下");
}
//鼠标中键按下
if(wParam & MK_MBUTTON)
{
wcscat(szText,L"鼠标中键按下");
}
SetWindowText(hWnd,szText);
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
如果 Ctrl 键和 Shift 键都按下,那么两个都有
注意:左键按下只有一瞬间,应该先按下右键 / 中间键,再按下左键,否则出不来
按下和抬起是一个连续的过程,有按下就有一个抬起(除非你不抬起)
wParam:按键的状态值
lParam:鼠标的坐标值
注意:需要包含头文件 <Windowsx.h>
#include <Windowsx.h>
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//鼠标左键按下
case WM_LBUTTONDOWN:
{
int x = GET_X_LPARAM(Iparam);
int y = GET_Y_LPARAM(Iparam);
//字符串
wchar_t szText[100] = {0};
//格式化
wsprintf(szText,"当前鼠标坐标:(%d,%d)",x,y);
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
鼠标的坐标系是一个客户区坐标系
当然,除此之外还有一个宏不用包含头文件 <Windowsx.h>:低位字 LOWORD,高位字 HIWORD
int x = LOWORD(Iparam);
int y = HIWORD(Iparam);
#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff))
#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
高位和低位的实质是移位操作
低位字代表 x 坐标、高位字代表 y 坐标
WM_LBUTTONDOWN消息 (Winuser.h) - Win32 apps | Microsoft Docs
鼠标左键抬起:WM_LBUTTONUP
鼠标右键按下:WM_RBUTTONDOWN
鼠标右键抬起:WM_RBUTTONUP
和鼠标左键按下基本是一样的,这里不再演示
鼠标移动消息
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//鼠标移动消息
case WM_MOUSEMOVE:
{
//使用方式与鼠标左键按下基本是一样的,这里不再演示
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
WM_MOUSEMOVE消息 (Winuser.h) - Win32 apps | Microsoft Docs
键盘消息
wParam:虚拟键值
lParam:包含了一个 32 位的按键的其他信息(按下还是抬起. . .)
0 ~ 15位:响应当前重复的次数、你按了几次
16 ~23位:键盘的扫描码,由键盘的产商决定,生产商给你设定的一个值,不需要考虑
24位:拓展键:ALT 键、CTRL 键,如果按下拓展键,值为 1,如果没按拓展键,值为 0
25 ~ 28位:保留,没有使用
29位:上下文代号,经常用于判断是否按下 Alt 键,如果按下,值就是 1,没有按下,值就是 0
30位:当前按键的状态值,如果在按下这个键之前,再次被发送了这个消息,这个值就是 1,否则就是 0
31位:表示状态的变化,在原来没有按下之前,如果正在按下,这个值就是 0,如果没有按下,这个值就是 1
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//键盘按下
case WM_KEYDOWN:
{
switch(wParam)
{
//回车
case VK_RETURN:
MessageBox(hWnd,"按下了回车符",L"提示",MB_OK);
break;
//空格
case VK_SPACE:
SetWindowText(hWnd,L"按下了空格键");
break;
//按下ESC键
case VK_ESCAPE:
SetWindowText(hWnd,L"按下了ESC键");
break;
//按下SHIFT键
case VK_SHIFT:
SetWindowText(hWnd,L"按下了Shift键");
break;
//按下F1键
case VK_F1:
SetWindowText(hWnd,L"按下了F1键");
break;
//注意按下字母键的区别
//按下A键
case 0x41:
SetWindowText(hWnd,L"按下了A键");
break;
//数字分为字母上边的数字和小键盘的数字
//按下数字0 字母上边的数字
case 0x30:
SetWindowText(hWnd,L"按下了字母上边数字0键");
break;
//按下数字0 小键盘的数字
case VK_NUMPAD0:
SetWindowText(hWnd,L"按下了小键盘数字0键");
break;
}
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
下面给出虚拟键码:
虚拟键码 (Winuser.h) - Win32 apps | Microsoft Docs
WM_KEYDOWN 只能截获你当前按下的一个按键
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//键盘按下
case WM_KEYDOWN:
{
switch(wParam)
{
if (wParam == VK_F3)
{
SetWindowText(hWnd, L"按了F3");
}
if (((lParam >> 24) & 1) == 1)
{
SetWindowText(hWnd, L"按了Ctrl");
}
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
WM_SYSKEYDOWN 系统按键:都是截获同一瞬间、同一时刻的按键,按哪个键就发出哪个键,不能出现组合键,和 WM_KEYDOWN 一样
WM_KEYUP:键盘按键抬起(和按键按下是一样的,什么按键按下,什么按键抬起)
字符消息
TranslateMessage(&msg) 将按下和抬起组合形成 WM_CHAR,如果把这段代码去掉就不会形成 WM_CHAR
大写字母、小写字母、数字. . .
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//字符消息
case WM_CHAR:
{
//想知道它按下什么键
//需要格式化
wchar_t szText[50];
wsprintf(szText,L"字符:%c",(char)wParam);
SetWindowText(hWnd, szText);
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
MSG msg;
//不断从消息队列中获取消息,把获取到的消息保存到 GetMessage
//消息编号是一个编号 0,1,2,3...一般所有消息都要获取
while(GetMessage(&msg,NULL,0,0))
{
//将虚拟键消息转为字符消息
//当在键盘上按下某个字符,比如按下A,产生按下消息和抬起消息,把这两个消息转为字母 A 需要通过以下函数
TranslateMessage(&msg);
//将虚拟键消息分发给窗口处理函数
DispatchMessage(&msg);
}
绘图消息
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//绘图消息
case WM_PAINT:
{
//绘图结构体
PAINTSTRUCT ps;
//开启绘图 要画哪个窗口把窗口句柄拿过来
HDC hDC = BeginPaint(hWnd, &ps);
//绘图的过程
//绘制矩形和正方形
//Rectangle(hDC, 20, 20, 100, 60);//80 * 40
Rectangle(hDC, 20, 20, 100, 100); //80 * 80
//绘制圆和椭圆 矩形的内切圆
//Ellipse(hDC, 20, 20, 100, 60);
Ellipse(hDC, 20, 20, 100, 100);
//输出文字
wchar_t szText[100]=L"你好,Baby";
//位置 第5个参数是字符的长度
TextOut(hDC, 200, 100, szText, wcslen(szText));
//结束绘图 释放ps
EndPaint(hWnd, &ps);
break;
}
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}