Re: ? CustomDraw Message Reflection Problem (Bug?)
Joseph M. Newcomer wrote (in news:p09ji4lic5qo8c140dbp5eqhv8n7i0cm0d@4ax.com):
At this point I would be reduced to single-stepping through the MFC
window-handler code that handles reflected messages, probably with
conditional breakpoints set so I didn't go crazy ignoring messages I didn't
want. For example, I'd determine the window handle and not break unless
LPARAM was that value. That's all I can suggest right now, because it really
does sound like a bug.
I don?t know about debugging the MFC internal code, but I just did a test with a
bare project and had the same results: the control does not get subsequent
notifications if it returns FALSE and the parent doesn?t have a handler.
Hopefully someone can figure out what?s wrong and/or a fix and/or a workaround.
(I?m using VS.NET 2003 SP1, and have no idea how to report this as a bug to
someone at Microsoft who would hear it and do something about it.) Here?s the
handlers of the control and dialog, and the debug traces (the last one clearly
shows that the control isn?t getting notifications):
BEGIN_MESSAGE_MAP(CMyLC, CListCtrl)
ON_NOTIFY_REFLECT_EX(NM_CUSTOMDRAW, OnNMCustomdraw)
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP(CaDlg, CDialog)
?
// This is either active or commented out:
// ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST, OnNMCustomdrawList)
END_MESSAGE_MAP()
BOOL CMyLC::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult) {
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
CString t=_T("");
t.Format(_T("%s\tdrawstage:%d\titem:%d,%d\n"),
_T("\tCCustList::OnNMCustomDraw"), pLVCD->nmcd.dwDrawStage,
pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem);
TRACE(t);
switch (pLVCD->nmcd.dwDrawStage) {
case CDDS_PREPAINT: *pResult=CDRF_NOTIFYITEMDRAW; break;
case CDDS_ITEM|CDDS_PREPAINT: *pResult=CDRF_NOTIFYSUBITEMDRAW; break;
case CDDS_ITEM|CDDS_PREPAINT|CDDS_SUBITEM:
default: *pResult=CDRF_DODEFAULT; break;
}
return FALSE;
}
void CaDlg::OnNMCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult) {
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
CString t=_T("");
t.Format(_T("%s\tdrawstage:%d\titem:%d,%d\n"), _T("CaDlg::OnNMCustomDrawList"),
pLVCD->nmcd.dwDrawStage, pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem);
TRACE(t);
switch (pLVCD->nmcd.dwDrawStage) {
case CDDS_PREPAINT: *pResult=CDRF_NOTIFYITEMDRAW; break;
case CDDS_ITEM|CDDS_PREPAINT: *pResult=CDRF_NOTIFYSUBITEMDRAW; break;
case CDDS_ITEM|CDDS_PREPAINT|CDDS_SUBITEM:
default: *pResult=CDRF_DODEFAULT; break;
}
}
Yes, TRUE (GOOD):
CCustList::OnNMCustomDraw drawstage:1 item:2010419606,0
CCustList::OnNMCustomDraw drawstage:65537 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,1
CCustList::OnNMCustomDraw drawstage:65537 item:1,1
CCustList::OnNMCustomDraw drawstage:196609 item:1,0
CCustList::OnNMCustomDraw drawstage:196609 item:1,1
No, TRUE (GOOD):
CCustList::OnNMCustomDraw drawstage:1 item:2010419606,0
CCustList::OnNMCustomDraw drawstage:65537 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,1
CCustList::OnNMCustomDraw drawstage:65537 item:1,1
CCustList::OnNMCustomDraw drawstage:196609 item:1,0
CCustList::OnNMCustomDraw drawstage:196609 item:1,1
Yes, FALSE (GOOD):
CCustList::OnNMCustomDraw drawstage:1 item:2010419606,0
CaDlg::OnNMCustomDrawList drawstage:1 item:2010419606,0
CCustList::OnNMCustomDraw drawstage:65537 item:0,0
CaDlg::OnNMCustomDrawList drawstage:65537 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,0
CaDlg::OnNMCustomDrawList drawstage:196609 item:0,0
CCustList::OnNMCustomDraw drawstage:196609 item:0,1
CaDlg::OnNMCustomDrawList drawstage:196609 item:0,1
CCustList::OnNMCustomDraw drawstage:65537 item:1,1
CaDlg::OnNMCustomDrawList drawstage:65537 item:1,1
CCustList::OnNMCustomDraw drawstage:196609 item:1,0
CaDlg::OnNMCustomDrawList drawstage:196609 item:1,0
CCustList::OnNMCustomDraw drawstage:196609 item:1,1
CaDlg::OnNMCustomDrawList drawstage:196609 item:1,1
No, FALSE (BAD!):
CCustList::OnNMCustomDraw drawstage:1 item:2010419606,0
--
Alec S.
news/alec->synetech/cjb/net
If the control returns TRUE, then it gets all expected notifications, and
the parent gets none whether it has the handler enabled or not. Good.
If the control returns FALSE, then the parent gets notifications as
expected. Good. The control itself however only gets messages if the parent
has a handler (even empty); if the parent does not have a handler (in the
message map), then the control does not get CDDS_ITEMPREPAINT (or
CDDS_SUBITEM or CDDS_POSTPAINT, etc.) notifications. Bad!
This seems like a bug. Why would the list control not get (sub)item
notifications (or postpaint, etc.) if the parent does not have a handler?