2013-07-11 31 views
3

在我的應用程序中,我忽略了CFrameWnd::OnHelp以打開word文檔而不是我們的舊.hlp文件。但是,當我按F1時,我發現該功能正在執行兩次。我檢查了堆棧,發現AfxWndProcBase正在接收命令0x1E146,然後當調用CFrameWnd::OnCmdMsgCWnd::OnCommand截斷爲0xE146,並且0xE146ID_HELP命令。然後緊接着,AfxWndProcBase正在接收命令0xE146,並再次運行幫助命令。經過一些實驗後,我發現正在處理第一條消息時,正在接收並處理內部AfxMessageBox的呼叫。什麼會導致Windows發送ID_HELP命令兩次

處理程序是在這裏:(?,什麼是第一個)

void CMainFrame::OnHelp() { 
    BOOL bWorked; 
    STARTUPINFO suInfo = {}; 
    suInfo.cb = sizeof(suInfo); 
    PROCESS_INFORMATION procInfo = {}; 
    CString m_Process = _T("Start"); 
    CString vipx = /*_T("\"") +*/ CString(AfxGetApp()->m_pszHelpFilePath) /*+ _T("\"")*/; 

    bWorked = ::CreateProcess(m_Process, 
      vipx.GetBuffer(),  // requires non-const :(
      NULL, 
      NULL, 
      FALSE, 
      NORMAL_PRIORITY_CLASS, 
      NULL, 
      NULL, 
      &suInfo, 
      &procInfo); 
    vipx.ReleaseBuffer(); 

    if (procInfo.dwThreadId==NULL || bWorked==false) 
     AfxMessageBox(_T("Failed to launch help: " + GetErrNoText(GetLastError()))); 
    //AfxMessageBox causes my app to receive the message again? 

    CloseHandle(procInfo.hProcess); 
    CloseHandle(procInfo.hThread); 
} 

爲什麼都0x1E1460xE146被髮送到我的應用程序,當我按下F1

重寫後,我發現,調用ShellExecute也會導致「1深度遞歸」。

我不知道,如果它是培訓相關,但這裏是我的表格的消息映射:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 
//{{AFX_MSG_MAP(CMainFrame) 
    ON_WM_CREATE() 
//}}AFX_MSG_MAP 
    // Global help commands 
    ON_COMMAND(ID_HELP, OnHelp) //F1 <--- both messages are this one? 
END_MESSAGE_MAP() 

在我的資源文件中,我發現這些,一個是F1,一個用於Shift + F1鍵:

VK_F1,   ID_CONTEXT_HELP,  VIRTKEY, SHIFT, NOINVERT 
VK_F1,   ID_HELP,    VIRTKEY, NOINVERT 

可能沒用,但這裏的兩個調用堆棧:

MyApp.exe!CMainFrame::OnHelp() Line 66 C++ 
mfc90ud.dll!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x01fea410, unsigned int nID=57670, int nCode=0, void (void)* pfn=0x0040b720, void * pExtra=0x00000000, unsigned int nSig=57, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 82 C++ 
mfc90ud.dll!CCmdTarget::OnCmdMsg(unsigned int nID=57670, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 381 + 0x27 bytes C++ 
mfc90ud.dll!CFrameWnd::OnCmdMsg(unsigned int nID=57670, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 946 + 0x18 bytes C++ 
mfc90ud.dll!CWnd::OnCommand(unsigned int wParam=123206, long lParam=0) Line 2364 C++ 
mfc90ud.dll!CFrameWnd::OnCommand(unsigned int wParam=123206, long lParam=0) Line 366 C++ 
mfc90ud.dll!CWnd::OnWndMsg(unsigned int message=273, unsigned int wParam=123206, long lParam=0, long * pResult=0x0018fba4) Line 1769 + 0x1e bytes C++ 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=273, unsigned int wParam=123206, long lParam=0) Line 1755 + 0x20 bytes C++ 
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x01fea410, HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=123206, long lParam=0) Line 240 + 0x1c bytes C++ 
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=123206, long lParam=0) Line 403 C++ 
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=123206, long lParam=0) Line 441 + 0x15 bytes C++ 
    ... 
mfc90ud.dll!CFrameWnd::PreTranslateMessage(tagMSG * pMsg=0x00712740) Line 249 + 0x1b bytes C++ 
mfc90ud.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop=0x00160bb4, tagMSG * pMsg=0x00712740) Line 2946 + 0x14 bytes C++ 
mfc90ud.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg=0x00712740) Line 233 + 0x12 bytes C++ 
mfc90ud.dll!CWinThread::PreTranslateMessage(tagMSG * pMsg=0x00712740) Line 777 + 0x9 bytes C++ 
MyApp.exe!CCXMyAppApp::PreTranslateMessage(tagMSG * pMsg=0x00712740) Line 749 C++ 
mfc90ud.dll!AfxPreTranslateMessage(tagMSG * pMsg=0x00712740) Line 252 + 0x11 bytes C++ 
mfc90ud.dll!AfxInternalPumpMessage() Line 178 + 0x18 bytes C++ 

二消息:

MyApp.exe!CMainFrame::OnHelp() Line 66 C++ 
mfc90ud.dll!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x01fea410, unsigned int nID=57670, int nCode=0, void (void)* pfn=0x0040b720, void * pExtra=0x00000000, unsigned int nSig=57, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 82 C++ 
mfc90ud.dll!CCmdTarget::OnCmdMsg(unsigned int nID=57670, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 381 + 0x27 bytes C++ 
mfc90ud.dll!CFrameWnd::OnCmdMsg(unsigned int nID=57670, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 946 + 0x18 bytes C++ 
mfc90ud.dll!CWnd::OnCommand(unsigned int wParam=57670, long lParam=0) Line 2364 C++ 
mfc90ud.dll!CFrameWnd::OnCommand(unsigned int wParam=57670, long lParam=0) Line 366 C++ 
mfc90ud.dll!CWnd::OnWndMsg(unsigned int message=273, unsigned int wParam=57670, long lParam=0, long * pResult=0x0018e264) Line 1769 + 0x1e bytes C++ 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=273, unsigned int wParam=57670, long lParam=0) Line 1755 + 0x20 bytes C++ 
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x01fea410, HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=57670, long lParam=0) Line 240 + 0x1c bytes C++ 
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=57670, long lParam=0) Line 403 C++ 
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x001703da, unsigned int nMsg=273, unsigned int wParam=57670, long lParam=0) Line 441 + 0x15 bytes C++ 
... 
mfc90ud.dll!CWnd::SendMessageW(unsigned int message=273, unsigned int wParam=57670, long lParam=0) Line 42 + 0x44 bytes C++ 
mfc90ud.dll!CWnd::OnHelpInfo(tagHELPINFO * __formal=0x0008c890) Line 3195 C++ 
mfc90ud.dll!CWnd::OnWndMsg(unsigned int message=83, unsigned int wParam=0, long lParam=575632, long * pResult=0x0018e5ec) Line 1948 + 0xd bytes C++ 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=83, unsigned int wParam=0, long lParam=575632) Line 1755 + 0x20 bytes C++ 
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x0253a410, HWND__ * hWnd=0x00160bb4, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 240 + 0x1c bytes C++ 
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x00160bb4, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 403 C++ 
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x00160bb4, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 441 + 0x15 bytes C++ 
    ... 
mfc90ud.dll!CWnd::DefWindowProcW(unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 1043 + 0x20 bytes C++ 
mfc90ud.dll!CWnd::Default() Line 274 C++ 
mfc90ud.dll!CWnd::OnHelpInfo(tagHELPINFO * __formal=0x0008c890) Line 3198 + 0x8 bytes C++ 
mfc90ud.dll!CWnd::OnWndMsg(unsigned int message=83, unsigned int wParam=0, long lParam=575632, long * pResult=0x0018eb70) Line 1948 + 0xd bytes C++ 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=83, unsigned int wParam=0, long lParam=575632) Line 1755 + 0x20 bytes C++ 
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x0253aa28, HWND__ * hWnd=0x000b08c6, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 240 + 0x1c bytes C++ 
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x000b08c6, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 403 C++ 
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x000b08c6, unsigned int nMsg=83, unsigned int wParam=0, long lParam=575632) Line 441 + 0x15 bytes C++ 
    ... 
mfc90ud.dll!CWnd::DefWindowProcW(unsigned int nMsg=77, unsigned int wParam=0, long lParam=0) Line 1043 + 0x20 bytes C++ 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=77, unsigned int wParam=0, long lParam=0) Line 1756 + 0x1c bytes C++ 
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x0253aa28, HWND__ * hWnd=0x000b08c6, unsigned int nMsg=77, unsigned int wParam=0, long lParam=0) Line 240 + 0x1c bytes C++ 
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x000b08c6, unsigned int nMsg=77, unsigned int wParam=0, long lParam=0) Line 403 C++ 
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x000b08c6, unsigned int nMsg=77, unsigned int wParam=0, long lParam=0) Line 441 + 0x15 bytes C++ 
    ... 
mfc90ud.dll!CWnd::WindowProc(unsigned int message=7423648, unsigned int wParam=7423712, long lParam=2016221872) Line 1755 + 0x20 bytes C++ 
    ... 
mfc90ud.dll!AfxDeactivateActCtx(unsigned long dwFlags=0, unsigned long ulCookie=353633777) Line 260 + 0x17 bytes C++ 
mfc90ud.dll!AFX_MAINTAIN_STATE2::~AFX_MAINTAIN_STATE2() Line 63 + 0xe bytes C++ 
+0

'的CWnd :: OnCommand'截斷'wParam' 0x1E146爲'nID' 0xE146因爲'的NID = LOWORD(wParam參數)',所以沒關係。如果用'TRACE'替換'AfxMessageBox',你會得到兩條消息嗎?另外,我不明白「AfxMessageBox」調用中的「+」,參數#1是LPCTSTR,因此在調用「AfxMessageBox」之前需要連接字符串,這不會發生在「+」 –

+0

我沒有嘗試過'TRACE',但是如果我在'AfxMessageBox'之前調用'ShellExecute',_that_會得到第二個消息_instead_。非常奇怪。 'GetErrNoText'是我寫的函數,它返回一個'CString',所以'LPCTSTR + CString'確實連接在一起。 –

回答

3

它看起來像ID_HELP是一個預先定義的MFC #define,如果你想繼續使用這個ID,你需要有處理程序在你的CWinApp派生類(見this MSDN article),而不是框架類。

或者,您可以用您自己的ID(例如IDM_HELP)代替ID_HELP,這與預先定義的MFC ID不衝突,這樣您就不會爲同一個ID獲得兩個單獨的處理程序。

+0

是的,我正在_trying_處理預定義的MFC ID_HELP,它不是自定義ID。 ....等待......處理程序進入CWinApp?爲什麼我的處理程序代碼在CMainFrame中? –

+0

此MSDN錯誤報告提到MFC有時可能會超載未記錄的'CMainFrame :: OnHelp',這顯然是我困惑的:http://connect.microsoft.com/VisualStudio/feedback/details/411625/no-msdn-documentation - 用於-MFC-CFrameWnd的-onhelp或 - cmdiframewnd-onhelp。你幫我找到了錯誤! –

1

Apperently this person found the same issue並談論原因和結果。

此雙重事件處理是由於一些遺留代碼。

自Windows 95(Viorel_提到的支持文章)以來,Windows自動將F1密鑰轉換爲WM_HELP消息。您注意到的與0x4d消息的處理完全相同;這是一些Windows代碼。然後,當應用程序收到WM_HELP消息時,它可以通過調用WinHelp來處理它。

在Windows 95之前,WM_HELP消息不存在。處理F1的唯一方法是創建一個VK_F1快捷方式,併爲其添加一個處理程序。 Windows 95通過添加WM_HELP消息,使幫助管理更加容易。由於Win95,您不必爲ID_HELP創建VK_F1快捷方式。

但是,如果選擇「上下文相關幫助」選項,MFC應用程序嚮導仍會添加此快捷方式。MFC比Windows 95舊!如果使用上下文相關幫助創建MFC Appwizard應用程序,則會爲與CFrameWnd :: OnHelp()相關聯的VK_F1創建快捷方式,該快捷方式將WM_HELP消息路由到應用程序的窗口窗口。 「到現在爲止還挺好」。

但Windows也自動將F1按鍵轉換爲WM_HELP消息。所以再次調用CFrameWnd :: OnHelp(),因爲MFC處理WM_HELP事件。

如果您不想被調用兩次,請刪除資源文件中的鍵盤快捷方式,然後處理WM_HELP。然後,你將有以下過程:

  • 的Windows捕獲F1鍵,生成WM_HELP

  • 對於WM_HELP(ON_WM_HELPINFO)消息處理程序在你的代碼捕獲WM_HELP消息。 WM_HELP的MFC默認消息處理是發送WM_COMMAND(ID_HELP)消息(這是另一個有趣的部分!)

  • 代碼中WM_COMMAND(ID_HELP)的消息處理程序調用默認的MFC處理。這運行winhelp。

以下的CMainFrame代碼不處理兩次幫助信息:

ON_WM_HELPINFO() 
ON_COMMAND(ID_HELP, &CMDIFrameWndEx::OnHelp) 

.. 


BOOL CMainFrame::OnHelpInfo(HELPINFO* pHelpInfo) 
{ 
    return CMDIFrameWndEx::OnHelpInfo(pHelpInfo); 
} 

而且不要忘記刪除快捷方式VK_F1資源文件!

不要給予好評這個帖子,follow the link and upvote the origional post

相關問題