Loading ...
Sorry, an error occurred while loading the content.

Bug in CMemDlgTemplate?

Expand Messages
  • domehead100
    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
    Message 1 of 4 , Aug 4, 2009
    View Source
    • 0 Attachment
      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
    • Alain Rist
      Hi Mike, For _ATL_VER
      Message 2 of 4 , Aug 4, 2009
      View Source
      • 0 Attachment
        Hi Mike,

        For _ATL_VER < 0x800 (pre VC2008) WTL 8.0 incorrectly defines DLGITEMTEMPLATEEX::id as WORD instead of DWORD. Changing WORD to DWORD in atldlgs.h #2972 (WTL 8.0 MS distribution) will fix it.
        This bug ( http://sourceforge.net/tracker/?func=detail&aid=1858494&group_id=109071&atid=652372 ) is fixed in current SVN.

        cheers,
        AR

        [Non-text portions of this message have been removed]
      • domehead100
        ... Thanks Alain! Note: I am using WTL8.0_7161_Final, and it is not fixed in that release. I think you meant to say it is fixed in 8.1? I was getting quite
        Message 3 of 4 , Aug 5, 2009
        View Source
        • 0 Attachment
          --- In wtl@yahoogroups.com, "Alain Rist" <ar@...> wrote:
          >
          > Hi Mike,
          >
          > For _ATL_VER < 0x800 (pre VC2008) WTL 8.0 incorrectly defines DLGITEMTEMPLATEEX::id as WORD instead of DWORD. Changing WORD to DWORD in atldlgs.h #2972 (WTL 8.0 MS distribution) will fix it.
          > This bug ( http://sourceforge.net/tracker/?func=detail&aid=1858494&group_id=109071&atid=652372 ) is fixed in current SVN.
          >
          > cheers,
          > AR
          >
          > [Non-text portions of this message have been removed]
          >

          Thanks Alain! Note: I am using WTL8.0_7161_Final, and it is not fixed in that release. I think you meant to say it is fixed in 8.1?

          I was getting quite confused because I was looking at the MSDN documentation for VC 7.1, which still listed .id as a WORD in DLGITEMTEMPLATEEX.

          ~Mike
        • gilad_no
          ... Hi Mike, From the main WTL web page: It is always recommended to get the latest release via SVN :) New releases are usually a result of newly implemented
          Message 4 of 4 , Aug 6, 2009
          View Source
          • 0 Attachment
            --- In wtl@yahoogroups.com, "domehead100" <domehead100@...> wrote:
            >
            > --- In wtl@yahoogroups.com, "Alain Rist" <ar@> wrote:
            > >
            > > Hi Mike,
            > >
            > > For _ATL_VER < 0x800 (pre VC2008) WTL 8.0 incorrectly defines DLGITEMTEMPLATEEX::id as WORD instead of DWORD. Changing WORD to DWORD in atldlgs.h #2972 (WTL 8.0 MS distribution) will fix it.
            > > This bug ( http://sourceforge.net/tracker/?func=detail&aid=1858494&group_id=109071&atid=652372 ) is fixed in current SVN.
            > >
            > > cheers,
            > > AR
            > >
            > > [Non-text portions of this message have been removed]
            > >
            >
            > Thanks Alain! Note: I am using WTL8.0_7161_Final, and it is not fixed in that release. I think you meant to say it is fixed in 8.1?
            >
            > I was getting quite confused because I was looking at the MSDN documentation for VC 7.1, which still listed .id as a WORD in DLGITEMTEMPLATEEX.
            >
            > ~Mike
            >

            Hi Mike,

            From the main WTL web page: "It is always recommended to get the latest release via SVN" :)

            New releases are usually a result of newly implemented features, rather than only bug fixes.

            - Gilad
          Your message has been successfully submitted and would be delivered to recipients shortly.