设为首页 加入收藏

TOP

Visual C++模态对话框消息处理机制的分析(二)
2012-11-04 15:30:28 来源: 作者: 【 】 浏览:438
Tags:Visual 模态 对话 消息 处理 机制 分析
  二、模态对话框的消息处理

  由上面我们看到,Windows是一个巨大的消息驱动结构,由用户发出消息,系统响应处理。非模态对话框是响应一个消息,系统处理一个消息,处理完毕后返回控制权给Windows。文档/视图框架结构与其类似。模态对话框在对话框创建后,挂起外部的消息,只是响应对话框内部的消息,而外部消息则全部"过滤"掉了,直到系统接收到WM_DESTROY或WM_CLOSE后,系统返回控制权给模态对话框创建前的线程,继续模态对话框创建前的线程将执行下面的代码。

  让我们看看下面的对话框DoModal实现代码:

{
 … …
 // Disable 父窗口 (在创建对话框前)
 HWND hWndParent = PreModal();
 AfxUnhookWindowCreate();
 BOOL bEnableParent = FALSE;
 if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
 {
  ::EnableWindow(hWndParent, FALSE);
  bEnableParent = TRUE;
 }
 TRY
 {
  // 创建模态对话框
  AfxHookWindowCreate(this);
  if (CreateDlgIndirect(lpDialogTemplate,CWnd::FromHandle(hWndParent), hInst))
  {
   if (m_nFlags & WF_CONTINUEMODAL)
   {
    // 进入模式循环
    DWORD dwFlags = MLF_SHOWONIDLE;
    if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG;
      VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
   }
  }
 }
 CATCH_ALL(e)
 {
  DELETE_EXCEPTION(e);
  m_nModalResult = -1;
 }
 END_CATCH_ALL
 file://Enable 父窗口
 if (bEnableParent)
  ::EnableWindow(hWndParent, TRUE);
  if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
   ::SetActiveWindow(hWndParent);
   // 删除对话框
   DestroyWindow();
   PostModal();
   … …
 }

  可以看到,在此实现代码中,并没有开辟新的线程。系统是在RunModalLoop()中进行消息循环。当 m_nFlags 为 WF_CONTINUEMODAL时,系统继续模式状态。RunModalLoop()函数实际上也是一for(;;)循环,控制重新分派Windows消息。直到ContinueModal()返回FALSE,而当调用EndModalLoop()时,ContinueModal()返回FALSE。此时,标志着模态显示的结束。因此,实现模态对话框消息处理的核心部分为RunModalLoop()和EndModalLoop()函数。

  三、以模态的形式显示应用到文档/视图框架结构实例

  (1)新建一工程文件:ModeFrame,选取MFC AppWizard(exe)。

  (2)第二步选取Single document(单文档)。

  (3)其余几步均为缺省值。

  (4)用ClassWizard添加一新类CSubModeFrame,以CFrameWnd为基类。

  (5)添加CsubModeFrame的实现函数DoMode();

int CsubModeFrame::DoModal()
{
 HWND hWndParent = m_hWndPrt;
 CRect rc(0,0,400,400);
 CWnd *pParent = CWnd::FromHandle(hWndParent);
 DWORD dwStyle=WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_THICKFRAME |  WS_VISIBLE | WS_SYSMENU | WS_CAPTION;
 if(!Create(NULL,"模态文档/试图框架 ",dwStyle,rc,pParent,NULL)) return FALSE;
  BOOL bEnableParent = FALSE;
  if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
  {
   ::EnableWindow(hWndParent,FALSE);
   ::EnableWindow(m_hWnd,TRUE);
   bEnableParent = TRUE;
  }
  CenterWindow();
  TRY
  {
   // enter modal loop
   DWORD dwFlags = MLF_SHOWONIDLE;
   if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG;
    VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
  }
  CATCH_ALL(e)
  {
   DELETE_EXCEPTION(e);
   m_nModalResult = -1;
  }
  END_CATCH_ALL
 
 if (bEnableParent)
  ::EnableWindow(hWndParent, TRUE);
  if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
   ::SetActiveWindow(hWndParent);
   // destroy modal window
   DestroyWindow();
   return m_nModalResult;
 }

  (6)添加CsubModeFrame的实现函数EndMode()

void CSubFrame::EndModal(){
 ASSERT(::IsWindow(m_hWnd));
 if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) {
  EndModalLoop(1);
 }
}

  (7)添加CModeFrameView的实现函数OnLButtonDblClk()

  在此函数的消息处理中:可以象显示对话框一样处理CsubModeFrame类。

CSubModeFrame SubModeFrame;
If(SubModeFrame.DoMode()){ MessageBox("Mode Ok");}

  (8)编译运行工程,双击视图,就会弹出模态的子文档/视图框架结构

  结论: 通过上面的分析和实例可以看出,深入研究了解Windows的消息处理机制,可利用消息对Windows的事件进行任意的定制和处理,不用拘泥于系统原有的模式。对进行深入Windows编程(www.cppentry.com)是很有必要的。
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC++实现GPS全球定位系统定位数据.. 下一篇Visual C++.NET中的字符串转换方法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: