2008年12月7日星期日

Windows消息

上大学的时候,我没学过VB,但我一直很鄙视VB这门语言。我觉得学着简单,没有用处,而且,你会他也会,看不出什么高深的东西在里面。

自从上了班,开始接触Excel宏,发现在工作中用处很大,有时候你一天的活,写个简单的宏处理一下就完成了,我对VB有点心存感激。虽然宏用的VBA语言和VB在使用时有所不同,但我已经改变了对VB的看法。

昨天下载了吉大的VB视频教程,看样子这个视频已经很久远了,但还是认真的看了两课,有个惊喜的发现:Windows 消息。下面是我的理解。

Windows消息包含了所有的外部输入和内部管理的信息。例如,键盘的输入,鼠标的点击,屏幕的刷新等,如图1所示。









举个例子,如果键盘上K键被按了一下,这个动作触发的Windows消息不仅仅是一个电信号这个简单,他还包含许多信息,比如被按下的是K键,松开的是K键,当前的系统时间等等。Windows将这些信息发送给相应的应用程序,然后应用程序发送给相应的窗口,每个消息都是一个大的结构。

系统将会维护一个或多个消息队列,任何产生的消息都回被放 入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows能够同时进行多个任务。下面的代码演示了消息循环的机制。

int WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
WINDCLASSEX wndclass;
MSG msg;
HWND hwndMain;

// 初始化窗口类
wndclass.style = CS_HREDRAW|CS_VREDRAW;
...

// 注册窗口类
if (RegiserClassEx(wndclass) == 0) return false;

// 创建窗口
hwndMain = CreateWindow( lpszAppName, ...);
if (!hwndMain) return false;

// 显示窗口
ShowWindow(hwndMain, nCmdShow);

// 消息循环
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return (msg.wParam);
}

WinMain函数API

窗口函数,处理系统接收的输入消息和窗口管理消息,VB编写的就是case部分。
MainWndProc(hwnd, msg, wParam, lParam)
{
...
switch(msg)
{
...
case WM_DESTORY: PostQuitMessage(0);
break;
default: return (DefaultWindowProc(hwnd,...));
}
return NULL;
}

当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。在16位的系统中系统中只有一个消息队列,所以系统必须等待当前任务处理消息后才能够发送下一消息到相应程式,假如一个程序陷如死循环或是耗时操作时系统就会得不到控制权。这种多任务系统也就称为协同式的多任务系统。Windows3.X就是这种系统。而32位的系统中每一运行的程序都会有一个消息队列,所以系统能够在多个消息队列中转换而不必等待当前程式完成消息处理就能够得到控制权。这种多任务系统就称为抢先式的多任务系统。Windows95/NT/2000/XP就是这种系统。


未完...

没有评论: