| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> 应用开发 >> vc >> 平台系统 >> 文章正文
深入剖析MFC中Windows消息处理、运行机制        【字体:
深入剖析MFC中Windows消息处理、运行机制
作者:-    文章来源:-    点击数:    更新时间:2006-4-20

序:
本人对Windows系统、MFC谈不上有深入的了解,但对MFC本身包装API的机制很有兴趣,特别是读了候老师的《深入浅出MFC》后,感觉到VISUAL C++的Application FrameWork十分精制[不敢用“完美”一词]。在以前,我对SDI结构处理消息有一定的认识,但对于模式对话框的消息机制不了解,读了《深入》一书也没能得到解决,近日,通过在CSDN上网友的帮助,和查阅MSDN,自认为已经了解。一时兴起,写下这些文字,没有其它目的,只是希望让后来者少走弯路,也希望和我一样喜欢“钻牛角尖”的人共同讨论、学习。如果你是牛人,那么你现在要慎重考虑有没有充足的时间读这些幼稚文字[何出此言?请大家看一下:http://www.csdn.net/expert/topic/13/13451.xml的相关评论]。本文中有些“理论”是我自己胡乱猜测,还请大家指正.[文中内容有些不可避免的会和《深入》一书某些内容重复]。

正文:

Windows程序和DOS程序的主要不同点之一是:Windows程序是以事件为驱动、消息机制为基础。如何理解?
举了例子,当你CLICK Windows “开始”BUTTON时,为什么就会弹出一个菜单呢?
当你单击鼠标左键时,操作系统中与MOUSE相关的驱动程序在第一时间内得到这个信号[LBUTTONDOWN],然后它通知操作系统―――“嗨,鼠标左键被单击了!”,操作系统得到这一信号后,马上要判断――用户单击鼠标左键,这是针对哪个窗口呢?如何判断?这很简单!当前状态中,具有焦点的窗口[或控件]就是了[这里当然是“开始”BUTTON了]。然后操作系统马上向这个窗口发送一条消息到这个窗口所在进程的消息队列,消息内容应是消息本身的代号、附加参数、窗口句柄…等等了。那么,只有操作系统才有资格发送消息至某一窗口的消息队列吗?不然,其它程序也有资格。你可以在你的程序中调用:SendMessage 、PostMessage。这样,被单击的窗口得到了一条由操作系统发送的包含CLICK的消息,操作系统已经暂时不再管窗口的任何事,因为它还要忙于处理其它事务。你的程序得到一条消息后如何做呢?Windows对于你在“开始”BUTTON上的单击事件做出如下反映:弹出一菜单。可是,得到消息到做出反映这一过程是如何实现的呢?这就是本文讨论的主要内容[当然只是针对MFC了]。
我首先简要谈一下SDI,然后会花更多文字描述模式对话框。
对于SDI窗口,你的应用程序类的InitInstance()大约如下:
BOOL CEx06aApp::InitInstance()
{ ……………
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CEx06aDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CEx06aView));
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
完成一些如动态生成相关文档、视,显示主框架窗口、处理参数行信息等工作。这些都是显示在你工程中的“明码”。我们现在把断点设置到return TRUE;一句,跟入MFC源码中,看看到底MFC内部做了什么。
程序进入SRC\WinMain.cpp,下一个大动作应是:
nReturnCode = pThread->Run();
各位看官注意了,重点来了。F11进入
int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
AfxPostQuitMessage(0);
}
return CWinThread::Run();
}
再次F11进入:
int CWinThread::Run()
{
ASSERT_VALID(this);

// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;

// acquire and dispatch messages until a WM_QU99v message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}

// phase2: pump messages while available
do
{
// pump message, but quit on WM_QU99v
if (!PumpMessage())
return ExitInstance();

// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}

} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}

ASSERT(FALSE); // not reachable
}

BOOL CWinThread::IsIdleMessage(MSG* pMsg)
{
// Return FALSE if the message just dispatched should _not_
// cause OnIdle to be run. Messages which do not usually
// affect the state of the user interface and happen very
// often are checked for.

// redundant WM_MOUSEMOVE and WM_NCMOUSEMOVE
if (pMsg->message == WM_MOUSEMOVE || pMsg->message == WM_NCMOUSEMOVE)

[1] [2] [3] [4] 下一页  

文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • 利用底层键盘钩子屏蔽任意按…

  • VC++中进程与多进程管理的方…

  • Window 消息大全使用详解

  • 关于键盘输入

  • Windows多线程多任务设计初步

  • VC++实现Win2000下直接读写磁…

  • 多进程编程的相关知识总结(…

  • 图形显示CPU内存利用率

  • Win32环境下dll编程原理

  • Linux环境进程间通信(二):…

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |