23win32编程基础——消息与消息队列
win32编程中一切都是消息。
当在windows中比如鼠标点下去或者移动等操作会产生一个动作,这个动作就是消息。
问题一:传递的消息里面应该包括哪些内容?
1、坐标,比如点击的问题
2、点击的对象,比如点击的是哪个窗体。
3、鼠标左键还是右键,消息的类型。
因此查看MSDN中的消息定义,可以知道:
typedef struct tagMSG { // msg
HWND hwnd; //窗口的句柄,相当于点击的哪个窗体,这个窗体接收点击的消息,然后进行反应。
UINT message; //消息ID,代表消息的类型,具体是哪种消息,点击,移动等
WPARAM wParam; //对消息进一步的说明,有的时候存储的消息内容很多,就需要这2个参数进行扩充存储消息的其他信息
LPARAM lParam; //对消息进一步的说明,有的时候存储的消息内容很多,就需要这2个参数进行扩充存储消息的其他信息
DWORD time; //点击的时间
POINT pt; //坐标 } MSG;
消息队列和消息处理的流程:

1、当按下键盘,就会产生一个动作,即消息MSG。
2、操作系统OS把这个消息,先保存到自己的消息队列中,os先保存起来,是为了后边的分发,这相当于1个中转站。
3、每个应用程序运行之后,会在内核中有个自己的消息队列,操作系统会把收到的消息分发给每个应用程序的消息队列中。
4、然后自己编写代码,应用程序中写一个死循环,就是从消息队列中不断取出来消息。
5、然后自己编代码,这些消息是不是自己要处理的消息,如果是自己要处理的,就写相应的消息处理函数进行处置。
6、如果不是自己关心的消息,再返回给操作系统进行处置。
以上就是整个消息处置的过程,因此后边的3条是我们自己写的:
消息循环,消息处置和默认操作系统处置。
我们先学会自己创建1个窗体的过程:
//MSDN告诉我们,在windows中,窗口类长下边这样,可以利用这个窗口类创建窗口对象。
typedef struct {
UINT style; //哪种格式的窗口,按钮还是下拉框、Edit等
WNDPROC lpfnWndProc; //回调函数
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance; //这个窗口属于哪个应用程序
HICON hIcon; //窗体的左上角的那个小图标
HCURSOR hCursor; //鼠标是什么形状
HBRUSH hbrBackground; //背景色
LPCTSTR lpszMenuName; //如果有菜单的话,菜单的名字
LPCTSTR lpszClassName; //窗体类的名字
} WNDCLASS, *PWNDCLASS
//并且需要使用RegisterClass进行注册。
代码如下:
要了解整个代码的流程:
// 20C++Win32CreateWind.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "20C++Win32CreateWind.h"
#include "OutPut.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
//不用系统以及准备好的窗口类,我们自己创建1个窗口类
TCHAR className[] = L"My Windows";
//WNDCLASS wndclas;小bug
WNDCLASS wndclas={0}; //这个用之前必须先初始化。
wndclas.lpszClassName = className; //别人用的时候,根据这个类名使用
wndclas.hbrBackground = HBRUSH(COLOR_GRAYTEXT); //窗口背景
wndclas.lpfnWndProc =WndProc ; //回调函数
wndclas.hInstance = hInstance; //应用程序句柄,哪个应用程序创建的这个窗口类
//注册,告诉操作系统有这么1个窗体类长这样,别的地方可以使用了。
RegisterClass(&wndclas);
//创建
HWND hwnd = CreateWindow(
className, //用我自己定义的窗体类,不用windows里面已经创建好的窗口类
TEXT("窗口的标题"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口外观样式
10,20, //坐标
300,600, //大小
NULL, //父窗口句柄,第一个窗口,目前没有父窗口
NULL, //菜单句柄,不带菜单栏
hInstance, //当前应用程序的句柄
NULL); //附加数据
//显示窗口
ShowWindow(hwnd,SW_SHOW);
//消息循环
MSG msg;
int bRet = 0;
while( (bRet = GetMessage( &msg, hwnd, 0, 0 )) != 0)//不停的取消息
{
if (bRet == -1)
{
// handle the error and possibly exit
OutputDebugStringF("%d\n",GetLastError());
}
else
{
TranslateMessage(&msg); //翻译成更具体的消息
DispatchMessage(&msg); //再传递给操作系统,然后操作系统自动调用回调函数。
}
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
//我不关系的消息,操作系统自己去处理
return DefWindowProc(hWnd, message, wParam, lParam);
}

浙公网安备 33010602011771号