Bug in CMemDlgTemplate?
"domehead100" <[email protected]>
| Newsgroups | gmane.comp.windows.wtl |
|---|---|
| Message-ID | <[email protected]> |
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.
At least that's what I think is happening. The size of the structure is 24 bytes, and indeed the 21st and 22nd bytes contain the proper .id, but the 23rd and 24th bytes contain what appears to be random data.
So, when I later call GetDlgItem() and pass in my ID, that function does not find the window because the "real" id is a DWORD and contains garbage in the high word.
To resolve this, I edited atldlgs.h and specifically initialized the DLGITEMTEMPLATEEX structure to {0} and then assigned each of the members:
DLGITEMTEMPLATEEX item = {0};
item.helpID = dwHelpID;
item.style = ATL::CControlWinTraits::GetWndStyle(0) | dwStyle;
item.exStyle = ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle;
item.x = nX;
item.y = nY;
item.cx = nWidth;
item.cy = nHeight;
item.id = wId;
This seems to have resolved the issue.
Thoughts?
~Mike
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/wtl/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/wtl/join
(Yahoo! ID required)
<*> To change settings via email:
mailto:[email protected]
mailto:[email protected]
<*> To unsubscribe from this group, send an email to:
[email protected]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/