旅游网站建设目的,个人网站可以做淘宝客网站吗,网站建设优化服务流程,做公司网站推广Windows窗口
Unit01注册窗口类
01窗口类的概念
窗口类是包括了窗口的各种参数信息的数据结构每个窗口都具有窗口类#xff0c;基于窗口类创建窗口每个窗口都具有一个名称#xff0c;使用前必须注册到系统
02窗口类的分类
系统窗口类 系统已经定义好的窗口类#xff0c;…Windows窗口
Unit01注册窗口类
01窗口类的概念
窗口类是包括了窗口的各种参数信息的数据结构每个窗口都具有窗口类基于窗口类创建窗口每个窗口都具有一个名称使用前必须注册到系统
02窗口类的分类
系统窗口类 系统已经定义好的窗口类所有应用程序都可以直接使用应用程序全局窗口类 由用户自己定义当前应用程序所有模块都可以使用应用程序局部窗口类 由用户自己定义当前应用程序中本模块可以使用
03系统窗口 不需要注册直接使用窗口类即可。系统已经注册好了 例如 按钮BUTTON编辑框EDIT 示例创建一个巨大的按钮
#include windows.h//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//在内存创建窗口HWND hWnd CreateWindow(Button,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}04全局及局部窗口类
注册窗口类的函数
ATON RegisterClass(CONST WNDCLASS *lpWndClass//窗口类的数据
);//注册成功后返回一个数字标识(返回0注册失败非0注册成功)注册窗口类的结构体
typedef struct _WNDCLASS{UINT style;//窗口类的风格WNDPROC lpfnWndProc;//窗口处理函数int cbClsExtra;//窗口类的附加数据buff的大小int cbWndExtra;//窗口的附加数据buff的大小HINSTANCE hInstance;//当前模块的实例句柄HICON hIcon;//窗口图标句柄HCURSOR hCursor,//鼠标的句柄HBRUSH hbrBackground,//绘制窗口背景的画刷句柄LPCTSTR lpszMenuName,//窗口菜单的资源ID字符串LPCTSTR lpszClassName//窗口类的名称
}WNDCLASS,*PWNDCLASS;style窗口类风格 应用程序全局窗口类的注册需要在窗口类的风格中增加CS_GLOBALCLASS 例如 WNDCLASS wce {0};
wce.style ...|CS_GLOBALCLASS;应用程序局部窗口类在注册窗口类时不添加CS_GLOBALCLASS风格其他窗口类风格 CS_HREDREAW当窗口水平发生变化时窗口重新绘制CS_VREDREAW当窗口垂直发生变化时窗口重新绘制CS_DBLCLKS允许窗口接收鼠标双击CS_NOCLOSE窗口没有关闭按钮
Unit02窗口创建
01窗口创建
CreateWindow/CreateWindowEx
HWND CreateWindowEx{DWORD dwExStyle,//窗口的扩建风格LPCTSTR lpClassName,//已经注册的窗口类名称LPCTSTR lpWindowName,//窗口标题栏的名字DWORD dwStyle,//窗口的基本风格int x,//窗口左上角水平坐标位置int y,//窗口左上角的垂直坐标位置int nWidth,//窗口的宽度int nHeight,//窗口的高度HWND hWndParent,//窗口的父窗口句柄HMENU hMenu,//窗口菜单句柄HINSTANCE hInstance,//应用程序实例句柄LPVOID lpParam//窗口创建时俯角参数
};//创建成功返回窗口句柄#include windows.h//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}02窗口创建执行过程
1.系统CreateWindowEx函数内部根据传入的窗口类名称在因用程序局部窗口类中查找如果找到执行第2步否则执行第3步2.比较局部窗口类与创建时传入的HINSTANCE变量。如果发现相等创建和注册的窗口类在同一模块创建窗口返回。如果不相等继续执行第3步3.在应用程序全局窗口类如果找到执行第4步否则执行第5步4.使用找到的窗口类的信息创建窗口返回5.在系统窗口类中查找如果找到创建窗口返回否则创建窗口失败 解决遗留问题点击窗口的关闭按钮可以完全退出进程不用在任务管理器中杀死进程
#include windows.h//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}03 子窗口创建
创建时要设置父窗口句柄创建风格要增加WS_CHILD|WS_VISIBLE
#include windows.h//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}Unit03消息基础
01消息的概念和作用
消息组成Windows平台下的消息 窗口句柄消息ID消息的两个参数两个附带信息消息的产生时间消息产生时的鼠标位置 消息的作用 当系统通知窗口工作时就采用消息的方式(DispatchMessage)派发给窗口的窗口处理函数
/** Message structure*/
typedef struct tagMSG {HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;
#ifdef _MACDWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;02窗口处理函数
每个窗口都必须具有窗口处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,//窗口句柄UINT uMsg,//消息IDWPARAM wParam,//消息参数LPARAM lParam//消息参数
);当系统通知窗口时会调用窗口处理函数同时将消息ID和消息参数床底给窗口处理函数。在窗口处理函数中不处理的消息使用缺省窗口处理函数。例如DefWindowProc
03 浅谈消息相关函数
GetMessage获取本进程的消息
BOOL GetMessage(LPMSG lpMsg,//存放获取到的消息BUFF//后面三个参数都是指定抓取消息的范围HWND hWnd,//窗口句柄如果指定为NULL表示抓取全部窗口的消息UINT wMsgFilterMin,//获取消息的最小IDUINT wMsgFilteMax//获取消息的最大ID
);
//lpMsg:当获取到消息后将消息的参数存放到MSG结构中
//hWnd:获取到hWnd所指定窗口的消息
//wMsgFilterMin和wMsgFilteMax:只能获取到由它们指定的消息范围内的消息如果都为0表示没有范围TranslateMessage翻译消息将按键消息翻译成字符消息 检查消息是否是按键的消息如果不是按键消息不做任何处理继续执行该函数只翻译可见字符的按键消息
BOOL TranslateMessage(const MSG* lpMsg//要翻译的消息地址
); DispatchMessage派发消息 将消息派发到该消息所属窗口的窗口处理函数上
LONG LONG DispatchMessage( const MSG* lpmsg //要派发的消息
);Unit04常见消息
01WM_DESTORY
产生时间窗口被销毁时的消息附带信息 wParam:0lParam:0 一般用法常用语在窗口销毁之前做相应的善后处理例如资源、内存的释放等
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
} 02WM_SYSCOMMAND
产生时间当点击窗口的最大化、最小化、关闭等附带信息 wParam具体点击的位置例如关闭SC_CLOSE等lParam鼠标光标的位置(使用一个long类型的高低位分别存储两个数使用下面的两个宏定义取出两个数) LOWORD(lParam);//水平位置HIWORD(lParam);//垂直位置 一般用法常用在窗口关闭时提示用户处理
#include windows.h//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:MessageBox(hWnd,02WM_SYSCOMMAND,Info,MB_OK);break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}#include windows.h//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}03WM_CREATE
产生时间在窗口创建成功但还没显示时附带信息 wParam0lParam为CREATESTRUCT类型的指针。通过这个指针获取CreateWindowEx中的全部12个参数的信息 一般用法常用于初始化窗口的参数、资源等等包括创建子窗口等
#include windows.hvoid onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc (CREATESTRUCT*)lParam;char* pszText (char*)psc-lpCreateParams;MessageBox(NULL, pszText,Info,MB_OK);//创建子窗口CreateWindowEx(0,EDIT,hello,WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_CREATE:onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText hello data;HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}04WM_SIZE
产生时间在窗口的大小发生变化附带信息 wParam窗口大小变化的原因lParam窗口变化后的大小 LOWORD(lParam);//水平位置HIWORD(lParam);//垂直位置 一般用法常用于窗口大小变化后调整窗口内各个部分的布局
#include windows.h
#include stdio.hHANDLE g_hOutput 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth LOWORD(lParam);short nHight HIWORD(lParam);char szText[256] {0};sprintf(szText, WM_SIZE宽%d高%d\n, nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc (CREATESTRUCT*)lParam;char* pszText (char*)psc-lpCreateParams;MessageBox(NULL, pszText,Info,MB_OK);//创建子窗口CreateWindowEx(0,EDIT,hello,WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText hello data;HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}return 0;
}05WM_QUIT
产生时间程序员发送附带信息 wParamPostQuitMessage函数传递参数lParam0 一般用法用于结束消息循环当GetMessage收到这个消息后会返回FALSE结束while处理退出消息循环
Unit05消息循环的原理
01消息循环的阻塞
GetMessage从系统获取消息将消息从系统中移除是一个阻塞函数。当系统无消息时会一直等待下一条消息的到来。PeekMessage以查看的方式从系统中获取消息可以不将消息从系统中移除是一个非阻塞函数。当系统无消息时返回FALSE继续执行后续程序相当于只负责侦查而不负责处理消息
BOOL PeekMessage( LPMSG lpMsg, //message informationHWND hWnd, //handle to windowUINT wMsgFilterMin, //first messageUINT wMsgFilterMax, //last messageUINT wRemoveMsg//移除标识赋值PM_NOREMOVE或PM_REMOVE); while(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);//将消息交给窗口处理函数来处理}
//将处理消息的while循环可以换一种高效的写法了while(1){if(PeekMessage(nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,OnIdle,strlen(OnIdle),NULL,NULL);}}示例
#include windows.h
#include stdio.hHANDLE g_hOutput 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth LOWORD(lParam);short nHight HIWORD(lParam);char szText[256] {0};sprintf(szText, WM_SIZE宽%d高%d\n, nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc (CREATESTRUCT*)lParam;char* pszText (char*)psc-lpCreateParams;MessageBox(NULL, pszText,Info,MB_OK);//创建子窗口CreateWindowEx(0,EDIT,hello,WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText hello data;HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(1){if(PeekMessage(nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,OnIdle,strlen(OnIdle),NULL,NULL);}}return 0;
}02 发送消息
消息的处理过程 SendMessage发送消息会等候消息处理的结果PostMessage投递消息消息发出后立即返回不等待消息执行结果
LRESULT SendMessage / PostMessage( HWND hWnd, //消息发送的目的窗口UINT Msg, //消息IDWPARAM wParam,//消息参数 LPARAM lParam //消息参数
); #include windows.h
#include stdio.hHANDLE g_hOutput 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth LOWORD(lParam);short nHight HIWORD(lParam);char szText[256] {0};sprintf(szText, WM_SIZE宽%d高%d\n, nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc (CREATESTRUCT*)lParam;char* pszText (char*)psc-lpCreateParams;MessageBox(NULL, pszText,Info,MB_OK);//创建子窗口CreateWindowEx(0,EDIT,hello,WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY://PostQuitMessage(0);//可以使GetMessage函数返回0//窗口能顺利关闭说明GetMessage能抓到PostMessage发送的消息PostMessage(hWnd, WM_QUIT, 0, 0);//PostQuitMessage内部调用此函数//窗口不能顺利关闭说明GetMessage不能抓到SendMessage发送的消息//SendMessage(hWnd, WM_QUIT, 0, 0);break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText hello data;HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(1){if(PeekMessage(nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,OnIdle,strlen(OnIdle),NULL,NULL);}}return 0;
}03消息分类
系统消息ID范围0-0x3FF由系统定义好的消息可以在程序中直接使用注意系统消息要么程序员只负责处理不负责发送如WM_SIZE要么只负责发送不负责处理如WM_QUIT用户自定义消息ID范围0x0400-0x7FFF(31743) 由用户自己定义满足用户自己的需求由用户自己发出消息并相应处理自定义消息宏WM_USER
自定义消息示例
#include windows.h
#include stdio.h
//自定义消息
#define WM_MYMESSAGE WM_USER1001HANDLE g_hOutput 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth LOWORD(lParam);short nHight HIWORD(lParam);char szText[256] {0};sprintf(szText, WM_SIZE宽%d高%d\n, nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc (CREATESTRUCT*)lParam;char* pszText (char*)psc-lpCreateParams;MessageBox(NULL, pszText,Info,MB_OK);//发送自定消息自己爱在哪里发送就写在哪里PostMessage(hWnd,WM_MYMESSAGE,1,2);//创建子窗口CreateWindowEx(0,EDIT,hello,WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}void onMyMessage(HWND hWnd, WPARAM wParam, LPARAM lParam){char szText[256] {0};sprintf(szText,自定义消息被处理wParam%d,lParam%d\n, wParam, lParam);MessageBox(hWnd, szText, Infor, MB_OK);
}
//窗口处理函数自定义处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_MYMESSAGE:onMyMessage(hWnd,wParam, lParam);break;case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY://PostQuitMessage(0);//可以使GetMessage函数返回0//窗口能顺利关闭说明GetMessage能抓到PostMessage发送的消息PostMessage(hWnd, WM_QUIT, 0, 0);//PostQuitMessage内部调用此函数//窗口不能顺利关闭说明GetMessage不能抓到SendMessage发送的消息//SendMessage(hWnd, WM_QUIT, 0, 0);break;case WM_SYSCOMMAND:if(wParam SC_CLOSE){MessageBox(hWnd,是否退出,Info,MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc {0};wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Main;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText hello data;HWND hWnd CreateWindowEx(0,Main,window,WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra 0;wc.cbWndExtra 0;wc.hbrBackground (HBRUSH)(COLOR_WINDOW1);wc.hCursor NULL;wc.hIcon NULL;wc.hInstance hIns;wc.lpfnWndProc WndProc;wc.lpszClassName Child;wc.lpszMenuName NULL;wc.style CS_HREDRAW|CS_VREDRAW;RegisterClass(wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 CreateWindowEx(0,Child,c1,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 CreateWindowEx(0,Child,cc,WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg {0};while(1){if(PeekMessage(nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(nMsg,NULL,0,0)){TranslateMessage(nMsg);DispatchMessage(nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,OnIdle,strlen(OnIdle),NULL,NULL);}}return 0;
}
文章转载自: http://www.morning.jpfpc.cn.gov.cn.jpfpc.cn http://www.morning.gqddl.cn.gov.cn.gqddl.cn http://www.morning.yqhdy.cn.gov.cn.yqhdy.cn http://www.morning.rnfwx.cn.gov.cn.rnfwx.cn http://www.morning.sqhlx.cn.gov.cn.sqhlx.cn http://www.morning.pmrlt.cn.gov.cn.pmrlt.cn http://www.morning.jwfkk.cn.gov.cn.jwfkk.cn http://www.morning.rzmkl.cn.gov.cn.rzmkl.cn http://www.morning.jpkk.cn.gov.cn.jpkk.cn http://www.morning.rqwmt.cn.gov.cn.rqwmt.cn http://www.morning.rfbpq.cn.gov.cn.rfbpq.cn http://www.morning.hgbzc.cn.gov.cn.hgbzc.cn http://www.morning.tbrnl.cn.gov.cn.tbrnl.cn http://www.morning.tsflw.cn.gov.cn.tsflw.cn http://www.morning.xgcwm.cn.gov.cn.xgcwm.cn http://www.morning.jbxfm.cn.gov.cn.jbxfm.cn http://www.morning.nzmqn.cn.gov.cn.nzmqn.cn http://www.morning.clnmf.cn.gov.cn.clnmf.cn http://www.morning.xrhst.cn.gov.cn.xrhst.cn http://www.morning.gfznl.cn.gov.cn.gfznl.cn http://www.morning.kxgn.cn.gov.cn.kxgn.cn http://www.morning.wgqtt.cn.gov.cn.wgqtt.cn http://www.morning.mtrfz.cn.gov.cn.mtrfz.cn http://www.morning.xcjbk.cn.gov.cn.xcjbk.cn http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn http://www.morning.hwnnm.cn.gov.cn.hwnnm.cn http://www.morning.hwhnx.cn.gov.cn.hwhnx.cn http://www.morning.qgbfx.cn.gov.cn.qgbfx.cn http://www.morning.mehrim.com.gov.cn.mehrim.com http://www.morning.lpcpb.cn.gov.cn.lpcpb.cn http://www.morning.rfbpq.cn.gov.cn.rfbpq.cn http://www.morning.psqs.cn.gov.cn.psqs.cn http://www.morning.mxftp.com.gov.cn.mxftp.com http://www.morning.tbzcl.cn.gov.cn.tbzcl.cn http://www.morning.qflcb.cn.gov.cn.qflcb.cn http://www.morning.pjtnk.cn.gov.cn.pjtnk.cn http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.mjtgt.cn.gov.cn.mjtgt.cn http://www.morning.mftdq.cn.gov.cn.mftdq.cn http://www.morning.fbnsx.cn.gov.cn.fbnsx.cn http://www.morning.jiuyungps.com.gov.cn.jiuyungps.com http://www.morning.xxrgt.cn.gov.cn.xxrgt.cn http://www.morning.hqllx.cn.gov.cn.hqllx.cn http://www.morning.bpmnq.cn.gov.cn.bpmnq.cn http://www.morning.qysnd.cn.gov.cn.qysnd.cn http://www.morning.ygxf.cn.gov.cn.ygxf.cn http://www.morning.benqc.com.gov.cn.benqc.com http://www.morning.drnfc.cn.gov.cn.drnfc.cn http://www.morning.pqqxc.cn.gov.cn.pqqxc.cn http://www.morning.gwsdt.cn.gov.cn.gwsdt.cn http://www.morning.mmqhq.cn.gov.cn.mmqhq.cn http://www.morning.ktrh.cn.gov.cn.ktrh.cn http://www.morning.wmpw.cn.gov.cn.wmpw.cn http://www.morning.ngzkt.cn.gov.cn.ngzkt.cn http://www.morning.mzkn.cn.gov.cn.mzkn.cn http://www.morning.rshijie.com.gov.cn.rshijie.com http://www.morning.dyxlj.cn.gov.cn.dyxlj.cn http://www.morning.pqqzd.cn.gov.cn.pqqzd.cn http://www.morning.drspc.cn.gov.cn.drspc.cn http://www.morning.prlgn.cn.gov.cn.prlgn.cn http://www.morning.qlbmc.cn.gov.cn.qlbmc.cn http://www.morning.wknj.cn.gov.cn.wknj.cn http://www.morning.sthp.cn.gov.cn.sthp.cn http://www.morning.sjsfw.cn.gov.cn.sjsfw.cn http://www.morning.blbys.cn.gov.cn.blbys.cn http://www.morning.synkr.cn.gov.cn.synkr.cn http://www.morning.dnpft.cn.gov.cn.dnpft.cn http://www.morning.wbrf.cn.gov.cn.wbrf.cn http://www.morning.qngcq.cn.gov.cn.qngcq.cn http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn http://www.morning.qnsmk.cn.gov.cn.qnsmk.cn http://www.morning.mbqyl.cn.gov.cn.mbqyl.cn http://www.morning.qstjr.cn.gov.cn.qstjr.cn http://www.morning.rynqh.cn.gov.cn.rynqh.cn http://www.morning.tslwz.cn.gov.cn.tslwz.cn http://www.morning.fygbq.cn.gov.cn.fygbq.cn http://www.morning.kjxgc.cn.gov.cn.kjxgc.cn http://www.morning.nqwz.cn.gov.cn.nqwz.cn http://www.morning.sskkf.cn.gov.cn.sskkf.cn http://www.morning.cjcry.cn.gov.cn.cjcry.cn