在我的應用程序中,我忽略了CFrameWnd::OnHelp
以打開word文檔而不是我們的舊.hlp文件。但是,當我按F1時,我發現該功能正在執行兩次。我檢查了堆棧,發現AfxWndProcBase
正在接收命令0x1E146
,然後當調用CFrameWnd::OnCmdMsg
時CWnd::OnCommand
截斷爲0xE146
,並且0xE146
是ID_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);
}
爲什麼都0x1E146
和0xE146
被髮送到我的應用程序,當我按下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++
'的CWnd :: OnCommand'截斷'wParam' 0x1E146爲'nID' 0xE146因爲'的NID = LOWORD(wParam參數)',所以沒關係。如果用'TRACE'替換'AfxMessageBox',你會得到兩條消息嗎?另外,我不明白「AfxMessageBox」調用中的「+」,參數#1是LPCTSTR,因此在調用「AfxMessageBox」之前需要連接字符串,這不會發生在「+」 –
我沒有嘗試過'TRACE',但是如果我在'AfxMessageBox'之前調用'ShellExecute',_that_會得到第二個消息_instead_。非常奇怪。 'GetErrNoText'是我寫的函數,它返回一個'CString',所以'LPCTSTR + CString'確實連接在一起。 –