文章目录
参考
窗口
GUI程序中用于用户直接交互的基本元素
如:QQ的登录窗口
消息
一个消息,是系统定义的一个32位的值,它唯一地定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息可以由系统或者应用程序产生。系统在发生输入事件时产生消息。举个例子, 当用户敲键, 移动鼠标或者单击控件。系统也产生消息以响应由应用程序带来的变化, 比如应用程序改变系统字体改变窗体大小。应用程序可以产生消息使窗体执行任务,或者与其他应用程序中的窗口通讯
消息映射
MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。
例如:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()
在BEGIN_MESSAG_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项
消息分类
系统消息
1.标准Windows消息。除WM_COMMAND外以WM_开头的消息是标准消息。例如,WM_CREATE、WM_CLOSE。
2.命令消息。消息名为WM_COMMAND,消息中附带了标识符ID来区分是来自哪个菜单、工具栏按钮或加速键的消息。
3.通知消息。通知消息一般由列表框等子窗口发送给父窗口,消息名也是WM_COMMAND,其中附带了控件通知码来区分控件。
用户定义消息
用户自定义消息实际上就是用户定义一个宏作为消息,此宏的值应该大于等于WM_USER,然后此宏就可以跟系统消息一样使用,窗口类中可以定义它的处理函数。
句柄
Windows平台有许多基本对象:窗口、文件、socket等等,为了操作这些对象,我们需要一个能引用这些对象的东西,这个东西就是句柄。句柄于资源好比遥控器于电视机。
如读文件函数ReadFile,第一个参数就是一个文件的句柄
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
窗口类名
windows程序注册窗口时内部用于标识该窗口特性的名字。一个应用程序在创建某个类型的窗口前,必须首先注册该“窗口类”。RegisterClass把窗口过程、窗口类型以及其他类型信息和要登记的窗口类关联起来。
窗口标题
窗体标题栏上显示的文本,如“无标题-记事本”
窗口过程
一个处理所有发送到某个类的所有窗口的消息的函数。窗口的外观和行为的各个方面都依赖于窗口过程对消息的反应。
每个窗口都是某个窗口类的成员。窗口类决定了用来处理消息的默认窗口过程。所有属于同一个类的窗口使用相同的默认窗口过程
窗口应用程序的主函数WinMain
hInstance
:应用程序的实例句柄
hPrevInstace
:Win16下使用,32弃用
lpCmdLine
:程序启动时给进程传递参数
nCmdShow
:进程显示方式(最大化、最小化、隐藏等)
Windows应用程序执行原理
Hello World
#include <windows.h>
// 声明窗口过程函数
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
// 主函数
// 参数为:当前实例的句柄、win32下的无用参数、主函数的参数、进程显示方式
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
static TCHAR szAppName[] = TEXT ("BossJue");
HWND hwnd;
MSG msg;
// 填充结构体为0
WNDCLASSEX wndclassex = {0};
// 结构体成员赋值
wndclassex.cbSize = sizeof(WNDCLASSEX); // 结构体大小
wndclassex.style = CS_HREDRAW | CS_VREDRAW; // 风格
wndclassex.lpfnWndProc = WndProc; // 窗口过程的地址(重要)
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance; // 实例句柄
wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION); // 图标句柄
wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW); //鼠标句柄
wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); //窗口类的背景色
wndclassex.lpszMenuName = NULL;
wndclassex.lpszClassName = szAppName; // 窗口类的类名
wndclassex.hIconSm = wndclassex.hIcon;
// 一、用wndclassex注册窗口类
if (!RegisterClassEx (&wndclassex)){
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
return 0;
}
// 二、创建窗口
hwnd = CreateWindowEx (
WS_EX_OVERLAPPEDWINDOW,
szAppName, // 已经注册过的类名
TEXT ("WindowTitle"), // 窗口名
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance, // 实例句柄
NULL
);
// 显示窗口
ShowWindow (hwnd, iCmdShow);
// 更新窗口
UpdateWindow (hwnd);
// 获取消息
while (GetMessage (&msg, NULL, 0, 0)){
TranslateMessage (&msg);
// 派发到窗口过程,由窗口过程进行处理
DispatchMessage (&msg);
}
return msg.wParam;
}
// 三、消息处理函数(窗口过程函数)
/* 由操作系统进行调用,而非主函数
* 注册窗口类时指定了窗口过程的地址
* 即 wndclassex.lpfnWndProc = WndProc;
* */
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
static const LPTSTR text = TEXT("Hello,World");
HDC hdc;
PAINTSTRUCT ps;
switch (message){
case WM_CREATE:
return (0);
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
TextOut (hdc, 0, 0, text, lstrlen(text));
EndPaint (hwnd, &ps);
return (0);
case WM_DESTROY:
PostQuitMessage (0);
return (0);
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
运行结果如下
开发基本步骤
注册窗口类
创建窗口
编写消息响应函数(重要)
客户区和非客户区
API
FindWindow
用法:
SendMessage
用法:
GetMessage
用于获取属于hwnd的消息,并填充到MSG结构体中
用法:
MSG结构体如下
TranslateMessage
用于处理键盘消息,即将虚拟码消息转为字符消息
DispatchMessage
将消息分发到窗口中
消息类型
特例
WM_PAINT, WM_TIMER, WM_QUIT会被放在消息队列尾
WM_CLOSE
WM_SETTEXT
WM_GETTEXT
杂
LRESULT
LRESULT就是long,也就是长整形。L即long,result表示结果。
CALLBACK
修饰符,表示此函数将作为参数,被别的函数调用
HWND
Handle of WiNDow,窗口句柄
LPARAM、WPARAM
wParam 通常用来存储小段信息,如,标志
lParam 通常用于存储消息所需的对象
HDC
设备上下文句柄
PAINTSTRUCT
一种包含了某应用程序用来绘制它所拥有的窗口客户区所需要的信息的结构体,简单讲:绘窗口需要的信息在里面存着。