4 Aug 2009 18:01
Bug in CMemDlgTemplate?
I am creating a dialog in memory by deriving my dialog class from CIndirectDialogImpl.
My dialog has a single child control, a CRichEditCtrl subclass. (This is a messagebox class that uses the
rich edit for displaying the message in RTF).
My problem is with the ControlID for the rich edit control. I set the ID to IDC_RICHEDIT which is 101 in my
resources, but when I subsequently try to subclass the control in OnInitDialog using that control id, I
get a null HWND.
I've determined that the real control ID, as reported by Spy++, is a DWORD with the low word being my control
id but the upper word being something else, either 0xCCCC, 0xC080, etc.
I'm overriding DoInitControls. Originally I was doing this using BEGIN_CONTROLS_MAP, but in an attempt
to troubleshoot my issue, I switched to just a direct override without using the macros:
void DoInitControls()
{
m_Template.AddControl(CRichEditCtrl::GetWndClassName(), (WORD)IDC_RICHEDIT, 0, 0, 100, 16,
WS_CHILD|WS_VISIBLE, 0, _T(""), NULL, 0);
}
I tracked the problem down to CMemDlgTemplate.AddControl in atldlgs.h to line 3129 in my distribution:
DLGITEMTEMPLATEEX item = {dwHelpID, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle,
ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, nX, nY, nWidth, nHeight, wId};
This statement initializes the DLGITEMTEMPLATEEX structure directly using struct/array-style
initialization. The problem seems to be that while the .id member of DLGITEMTEMPLATEX is properly
initialized as a WORD value, in actuality due to padding in memory it is a DWORD, and the high word is not
initialized via the statement above and contains whatever garbage existed in that memory previously.
(Continue reading)
RSS Feed