Windows程序内部运行机制
ü 关键概念
1、句柄
句柄是整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。
2、消息与消息队列
windows程序设计是种事件驱动方式的程序设计,主要基于消息的。例如,当用户在窗口中华图时,按下鼠标左键,此时os会感知到这一事件,于是将此事件包装成一个消息,投递到应用程序的消息队列中,最后应用程序从消息队列中取走消息并进行响应。
3、Winmain函数
WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。
4、创建窗口的步骤
1)设计一个窗口类。如:WNDCLASS wndcls。
2)注册窗口类。如:RegisterClass(&wndcls)。
3)创建窗口。如:CreateWindow(),CreateWindowEX();
4)显示及更新窗口。如:ShowWindow(),UpdateWindow();
ü 代码
1、消息
struct tagMSG { // msg
HWND hwnd; //接收消息的窗口句柄。和哪个窗口相关联。
UINT message; //消息标识。消息本身是什么。
WPARAM wParam; //消息的附加信息。具体取决于消息本身。
LPARAM lParam;
DWORD time; //消息投递时间。
POINT pt; //消息投递时,光标在屏幕上的位置。
} MSG;
2、Winmain函数
int WINAPI WinMain(
HINSTANCE hInstance, // 当前事例句柄。
HINSTANCE hPrevInstance, // 先前事例句柄。32位系统中此值都为NULL
LPSTR lpCmdLine, // 命令行指针
int nCmdShow // (窗口)显示的状态
);
要带参调用WinMain,类似于命令行的功能,在ProjectèsettingèDebug页èProgram arguments项填写参数
3、窗口类
typedef struct _WNDCLASS {
UINT style; //窗口的类型
WNDPROC lpfnWndProc; //窗口过程函数指针(回调函数)
int cbClsExtra; //窗口类附加字节,为该类窗口所共享。通常0。
int cbWndExtra; //窗口附加字节。通常设为0。
HANDLE hInstance; //当前应用程序事例句柄。
HICON hIcon; //图标句柄 LoadIcon();
HCURSOR hCursor; //光标句柄 LoadCursor();
HBRUSH hbrBackground; //画刷句柄 (HBRUSH)GetStockObject();
LPCTSTR lpszMenuName; //菜单名字
LPCTSTR lpszClassName; //类的名字
} WNDCLASS;
注:
- 回调函数
在特定时间或条件下由另外一方调用,用于对事件或条件进行响应,而不是由该函数的实现方调用。
eg:
LRESULT CALLBACK WindowProc( //这里WindowProc是个代号名字。
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
- 两种函数调用约定(__stdcall 和 _cdecl)
#define CALLBACK __stdcall
#define WINAPIV __cdecl
__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,由调用者负责把参数压入栈, 最后也是由调用者负责清除栈的内容,一般来说,这是 C/C++ 的默认调用函数的规则,MS VC 编译器采用的规则则是这种规则2. __stdcall
_stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,由调用者负责把参数压入栈,最后由被调用者负责清除栈的内容,Windows API 所采用的函数调用规则则是这种规则
另外,采用 __cdecl 和 __stdcall 不同规则的函数所生成的修饰名也各为不同,相同点则是生成的函数修饰名前缀都带有下划线,不同的则是后缀部分,当然,这两者最大的不同点就在于恢复栈的方式不同,而且这点亦是最为重要的。
4、注册窗口类
ATOM
RegisterClass(CONST
WNDCLASS *lpWndClass);
5取出消息和消息循环
- GetMessage函数声明
BOOL GetMessage(
LPMSG lpMsg, //指向一个消息结构体(MSG),取出的消息
HWND hWnd,
//指定接收了哪个窗口的消息。通常设置为null,用于接收所有窗口的消息。
UINT wMsgFilterMin, //获取消息的最小值,一般为0
UINT wMsgFilterMax //获取消息的最大值
);
- 消息循环
MSG msg;
while(GetMessage(&msg,...)) //从消息队列中取出一条消息
{
TranslateMessage(&msg); //进行消息转换
DispatchMessage(&msg); //分派消息到窗口的回调函数处理,(OS调用窗口回调函数进行处理)。
6、创建、更新和显示窗口
ü
总结:Windows消息处理机制