深入详解Windows消息机制(2012年某公司实习生招聘面试试题)
来源:互联网 发布:mysql 加几天 编辑:程序博客网 时间:2024/05/20 19:28
我们首先来看看用户是如何和应用软件打交道的,如图:
上图就是用户与应用软件交互的一个逻辑图,我们在用Word等软件时,就是这种模型。从用户的感觉来看,用户是在与应用软件对应的窗口打交道,用户感觉离应用软件很近很近。真的很近么?非也!虽然用户在逻辑上离应用软件的确很近,但在物理上,用户离应用软件却是相对较远的。下面,我们来看看,用户究竟是如何与应用软件打交道的(用户不需要知道这个具体过程,但应用软件的开发人员必须知道),如下图所示:
从上图可以看到:在物理上,离用户最近的实际上是输入输出设备,下面我们看看上图中1-6这六个步骤分别表示什么意思(为了简便,在叙述时,我们的标号没有用圆圈):
1. 用户点击鼠标或者键盘;
2. Windows感觉到了鼠标或键盘的动作;
3. Windows把这个消息告诉应用程序;
4. 应用程序告诉Windows去做事,实际上就是应用程序调用Windows的API函数;
5. Windows让输出设备做事;
6. 用户获得输出。
对用户来说,没有必要了解输入输出设备和Windows的相关知识。对程序员(写应用程序的人)来说,没有必要了解输入输出设备,但是必须了解Windows的基本知识。在下面的叙述中,我们就不管输入输出设备了。
上面的过程还是很笼统,为了弄得更清楚,我们有必要了解Windows的消息机制,如图:
下面,我们来慢慢描述(上图中的虚线表示消息的流程):
step0: 程序员编程,把WinMain函数和窗口回调函数写好;
step1: Windows调用WinMain函数,启动应用程序,Windows会建立一个消息队列,用来存储消息。
step2: WinMain函数调用Windows的API函数,比如调用CreateWindow和ShowWindow, 从而生成并显示一个窗口。在调用CreateWindow函数时,会产生一个消息,这个消息并不进入消息队列,但窗口的回调函数仍然会处理,在此,我们不讨论非队列消息。
step3: WinMain函数调用Windows的API函数,比如调用GetMessage来从消息队列中取出消息。假设用户这个时候在窗口中点击鼠标,那么Windows会把这个事件包装成消息,投到消息队列中,GetMessage会取出这个消息,通过DispatchMessage送到Windows;
step4: Windows进而会将该消息发送到窗口的回调函数,并对该函数进行调用;
step5:窗口的回调函数可以对这个消息进行相应处理,这个处理的具体方法由程序员自己决定,通常是调用Windows的API函数来实现处理。
下面,我们来看看具体程序:
#include <windows.h>// 回调函数LRESULT CALLBACK MyFun(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam ){switch(uMsg){case WM_CLOSE:if(IDYES == MessageBox(hwnd, "真的要关闭么?", "message", MB_YESNO)){DestroyWindow(hwnd);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, uMsg, wParam, lParam);}return 0;}int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ){WNDCLASS wnd;wnd.cbClsExtra = 0;wnd.cbWndExtra = 0;wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wnd.hCursor = LoadCursor(NULL, IDC_CROSS);wnd.hIcon = LoadIcon(NULL, IDI_ERROR);wnd.hInstance = hInstance; wnd.lpfnWndProc = MyFun; // 指定回调函数wnd.lpszClassName = "ClassName"; wnd.lpszMenuName = NULL;wnd.style = CS_HREDRAW | CS_VREDRAW;RegisterClass(&wnd);HWND hwnd;hwnd = CreateWindow("ClassName", "温馨提示:", WS_OVERLAPPEDWINDOW, 500, 500, 200, 200, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, SW_SHOWNORMAL);MSG msg;while(GetMessage(&msg, NULL, 0, 0)) // 从消息队列中循环地抓取消息{// 可以调用TranslateMessage函数来产生新的消息,并投到消息队列中DispatchMessage(&msg); // 把消息给Windows}return msg.wParam;}
总之,在设计Windows应用程序时,需要把握两个形容词:event-driven和message-based.
- 深入详解Windows消息机制(2012年某公司实习生招聘面试试题)
- 求数组a[N]中第i(1<=i<=n)小的数(2012年某公司实习生招聘面试试题)
- 构造函数可以是虚函数吗? 为什么?(某公司实习生招聘面试试题)
- 如何在VC++6.0中设置条件断点?--- 某公司实习生招聘面试试题
- Little's Law(利特尔法则)的简要证明和重要应用(2012年某公司实习生招聘笔试试题)
- Little's Law(利特尔法则)的简要证明和重要应用(2012年某公司实习生招聘笔试试题)
- 判断单链表是否带环(某公司实习生招聘笔试试题)
- 任务调度时间 (某公司实习生招聘笔试试题)
- 某公司实习生招聘笔试题
- 某公司招聘试题(java)
- 字符串的大小比较(某公司校园招聘面试试题)
- 简单详解:x^6+4x^4+2x^3+x+1 至少要需要多少次乘法? (某公司实习生招聘笔试试题)
- 用递归方法对二叉树进行层次遍历(某公司实习生招聘笔试试题)
- 聊聊这个与代码优化有关的选择题 (某公司实习生招聘笔试试题)
- 再谈IPC之共享内存 (某公司实习生招聘笔试试题)
- 又见组合数, 好亲切! (某公司实习生招聘笔试试题)
- 数据库表删除之drop table xxx (某公司实习生招聘笔试试题)
- 聊聊这个与代码优化有关的选择题 (某公司实习生招聘笔试试题)
- PHP SOCKET编程
- 生成Android证书(开发ane需要的证书)
- 博客链接
- Windows EXE文件关联
- PHP输入流php://input
- 深入详解Windows消息机制(2012年某公司实习生招聘面试试题)
- PHP函数的实现原理及性能分析
- 正则验证汉字
- Apache运行机制剖析
- win7 局域网共享设置
- PHP运行模式
- hdu 4548
- poj_1543 Perfect Cubes
- 如何让服务器更加安全