我在一个MFC DLL(选择创建工程时是第二种)做了一个对话框程序,该程序有N个对话框,但只用一个主对话框显示.主对话框中有一个工具栏,点击工具栏的不同按钮则将相应的对话框作为子窗口在主对话框中显示,并隐藏之前显示的子窗口(也是对话框).所有子对话框均动态创建一次,创建后对象指针被作为主对话框的成员变量保存.
所有子对话框模板均设为无边框子窗口属性.响应工具栏按钮命令消息的函数类似下面代码:
CMainDlg::OnSelectDlg(nID)
{
     CDialog* pCurSelDlg = NULL;     switch(nID)
     {
     case ID_SOME_DLG:
          if(m_pSomeChildDlg == NULL)
                m_pSomeChildDlg = new CSomeChildDlg;
          if(m_pSomeChildDlg)
                m_pSomeChildDlg->Create(this);
          pCurSelDlg = m_pSomeChildDlg;
          break;
     case ID_SOME_OTHER_DLG:
          .
          .
          .
     }     if(pCurSelDlg == NULL)
          return;     // reposition the currently selected dlg
          .
          .
          .     // hide prev child dlg & show cur sel dlg
     if(m_pCurSelDlg)
          m_pCurSelDlg->ShowWindow(SW_HIDE);
     m_pCurSelDlg = pCurSelDlg;
     m_pCurSelDlg->ShowWindow(SW_SHOW);
}在各个子对话框的PreTranslateMessage函数中,对WM_KEYDOWN消息作了一些特别的处理(判断上,下,ENTER键消息切换焦点控件).这个DLL中只有一个导出函数ShowFxn(),用来显示主对话框.
第一种, 作为模态对话框显示:
DLLEXPORT void ShowFunc()
{
     CMainDlg dlgMain;
     dlgMain.DoModal();
}
一切OK.第二种, 作为非模态对话框显示:
CMainDlg* g_pMainDlg = NULL;
DLLEXPORT void ShowFunc()
{
     if(g_pMainDlg)
         g_pMainDlg->SetFocus();
     else
     {
         g_pMainDlg = new CMainDlg;
         if(g_pMainDlg)
         {
             g_pMainDlg->Create(NULL);
             g_pMainDlg->ShowWindow(SW_SHOW);
         }
     }
}
对话框正常显示,各子对话框基本工作正常.唯一一点让人摸不着头脑.子对话框的PreTranslateMessage函数好像根本就没被调.预先对上,下,ENTER键的处理一点作用都不起,甚至连TABLE键都不能切换焦点控件.
怀疑消息被主对话框截获了,于是在主对话框中的PreTranslateMessage函数中插入提示语句,NOTHING.好像所有对话框的PreTranslateMessage都不曾被调用过一样.极度郁闷中....