我正在使用自定義繪製對CSliderCtrl進行一些更改,該控件將用於對話框中。下面是結構: 在我MessageMap我:ON_NOTIFY_REFLECT_EX(NM_CUSTOMDRAW, OnNMCustomdraw)
CustomDraw中的SetWindowLong導致未處理的異常
的OnNMCustomdraw方法如下所示:
BOOL CCustomSliderCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
*pResult = CDRF_DODEFAULT;
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
switch(pNMCD->dwDrawStage)
{
case CDDS_PREPAINT:
{
//Dialogs don't receive CDRF_NOTIFYITEMDRAW notifcations by returning it as part of pResult, we must
//use the following so we ensure we receive the msg
SetWindowLong(pNMHDR->hwndFrom, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW);
return TRUE;
}
case CDDS_ITEMPREPAINT:
if(pNMCD->dwItemSpec == TBCD_CHANNEL)
{
...SNIP...
SetWindowLong(pNMHDR->hwndFrom, DWL_MSGRESULT, CDRF_SKIPDEFAULT);
return TRUE;
}
}
return FALSE;
}
讀圍繞我瞭解到,您必須使用SetWindowLong函數來設置的返回值自定義繪製,否則你的方法不會總是收到CDDS_ITEMPREPAINT消息。但是,使用SetWindowLong時,我的應用程序永遠不會收到CDDS_ITEMPREPAINT,所以我的滑塊看起來就像一個標準滑塊。當在滑塊上發生任何類型的交互時,應用程序崩潰,例如懸停在其上,或者最小化和最大化對話框。
我剪掉了TBCD_CHANNEL代碼,因爲它永遠不會到達。
在調試模式下運行時,它在AfxClock.cpp中的AfxUnlockGlobals方法結束時崩潰。這是一個堆棧跟蹤: 更新:由於添加了調試符號,崩潰似乎在CWnd :: DefWindowProc mwthod中找到。
comctl32.dll!_TrackBar[email protected]() + 0x551 bytes
[email protected]() + 0x28 bytes
[email protected]() + 0xb7 bytes
[email protected]() + 0x51 bytes
[email protected]() + 0x1b bytes
mfc90ud.dll!CWnd::DefWindowProcW(unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 1043 + 0x20 bytes C++
mfc90ud.dll!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0) Line 1756 + 0x1c bytes C++
mfc90ud.dll!AfxCallWndProc(CWnd * pWnd=0x0012fdbc, HWND__ * hWnd=0x000308fe, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 240 + 0x1c bytes C++
mfc90ud.dll!AfxWndProc(HWND__ * hWnd=0x000308fe, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 403 C++
mfc90ud.dll!AfxWndProcBase(HWND__ * hWnd=0x000308fe, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 441 + 0x15 bytes C++
[email protected]() + 0x28 bytes
[email protected]() + 0xb7 bytes
[email protected]() + 0x4d bytes
[email protected]() + 0x24 bytes
[email protected]() + 0x13 bytes
[email protected]() + 0xc bytes
[email protected]() + 0xf bytes
mfc90ud.dll!AfxInternalPumpMessage() Line 183 C++
mfc90ud.dll!CWinThread::PumpMessage() Line 900 C++
mfc90ud.dll!AfxPumpMessage() Line 190 + 0xd bytes C++
mfc90ud.dll!CWnd::RunModalLoop(unsigned long dwFlags=4) Line 4386 + 0x5 bytes C++
mfc90ud.dll!CDialog::DoModal() Line 584 + 0xc bytes C++
SetSelection.exe!CSetSelectionApp::InitInstance() Line 64 + 0xb bytes C++
mfc90ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020a84, int nCmdShow=1) Line 37 + 0xd bytes C++
SetSelection.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020a84, int nCmdShow=1) Line 34 C++
SetSelection.exe!__tmainCRTStartup() Line 578 + 0x35 bytes C
SetSelection.exe!wWinMainCRTStartup() Line 403 C
[email protected]() + 0x23 bytes
那麼,有沒有人有任何洞察到這件事?如果您需要更多信息,請告訴我。
更新:我已經找到了解決辦法,現在,而不是使用SetWindowLong函數我只是把結果賦值給pResult,然後返回。我強制通過調用SetRangeMin(GetRangeMin(),TRUE)重繪子項,不完全優雅,但它的作品。
提示:爲了獲得更好的堆棧跟蹤,請配置一個[symbol server](http://support.microsoft.com/kb/311503) – MSalters 2010-04-13 07:35:54
謝謝,我現在就來玩一玩。 – Andrew 2010-04-13 07:50:17
添加了更好的堆棧跟蹤,感謝提示。 – Andrew 2010-04-13 08:08:43