Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. VS 2010 - SubClass - FromHandlePermanent Assert

VS 2010 - SubClass - FromHandlePermanent Assert

Scheduled Pinned Locked Moved C / C++ / MFC
c++cssvisual-studioquestionannouncement
2 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tony Teveris
    wrote on last edited by
    #1

    Trying to subclass a combobox i order to have the entries have a tab stop. When I perform the subclass I get an assert. This code use to work in the early days of MFC but with 2010 it fails. I did not try it with any VS version in between. Is it something very simple I'm missing? Thanks

    class CTabCBox : public CComboBox
    {
    public:
    CTabCBox() {icTab=0; lpiTab=NULL;}
    ~CTabCBox() {if (lpiTab) free(lpiTab);}

    // subclassed construction
    BOOL SubclassCBox(UINT nID,CWnd\* pParent,int icTabs,LPINT lpiTabs);
    

    protected:
    int icTab; // count of tab stops
    LPINT lpiTab; // tab stops in logical units

    virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMis);
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDis);
    

    };

    // CtestDlg dialog
    class CtestDlg : public CDialogEx
    {
    // Construction
    public:
    CtestDlg(CWnd* pParent = NULL); // standard constructor

    // Dialog Data
    enum { IDD = IDD_TEST_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange\* pDX);	// DDX/DDV support
    

    // Implementation
    protected:
    HICON m_hIcon;

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx\_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx\_msg void OnPaint();
    afx\_msg HCURSOR OnQueryDragIcon();
    DECLARE\_MESSAGE\_MAP()
    

    public:
    CTabCBox m_ctrlFontsX;
    CComboBox m_ctrlFonts;
    };

    // from INITDIALOG
    // TODO: Add extra initialization here
    TEXTMETRIC tm;
    int iTab;

    // compute tab stop
    if (m\_ctrlFonts.GetDC()->GetTextMetrics(&tm))
    	iTab = (33+8) \* tm.tmAveCharWidth;
    
    m\_ctrlFontsX.SubclassCBox(IDC\_COMBO1,this,1,&iTab);
    
    CString csS("Font title string\\tnnnnnnnn");
    
    m\_ctrlFontsX.AddString(csS);
    

    BOOL CTabCBox::SubclassCBox(UINT nID, CWnd* pParent, int icTabs, LPINT lpiTabs)
    {
    DWORD dwcb;
    int iRc = 0;

    // make very sure all tab members are free and clear
    if (lpiTab)
    	free(lpiTab);
    lpiTab = NULL;
    icTab = 0;
    
    if (icTabs>0)
    	{
    	// make copy of tab info
    	dwcb = icTabs\*sizeof(int);
    	if (!(lpiTab = (LPINT)malloc(dwcb)))
    		return(FALSE);
    	memcpy(lpiTab,lpiTabs,(size\_t)dwcb);
    	icTab = icTabs;
    	}
    iRc = SubclassDlgItem(nID, pParent); // THIS CAUSES THE ASSERT
    return(iRc);
    

    } // end of SubclassCBox

    It always fails on the second assert (FromHandle....) from wincore.cpp
    BOOL CWnd::Attach(HWND hWndNew)
    {
    ASSERT(m_hWnd == NULL); // only attach once, detach on destroy
    ASSERT(FromHandlePermanent(hWndNew) == NULL);
    // must not already be in permanent map

    Tony Teveris Gerb

    L 1 Reply Last reply
    0
    • T Tony Teveris

      Trying to subclass a combobox i order to have the entries have a tab stop. When I perform the subclass I get an assert. This code use to work in the early days of MFC but with 2010 it fails. I did not try it with any VS version in between. Is it something very simple I'm missing? Thanks

      class CTabCBox : public CComboBox
      {
      public:
      CTabCBox() {icTab=0; lpiTab=NULL;}
      ~CTabCBox() {if (lpiTab) free(lpiTab);}

      // subclassed construction
      BOOL SubclassCBox(UINT nID,CWnd\* pParent,int icTabs,LPINT lpiTabs);
      

      protected:
      int icTab; // count of tab stops
      LPINT lpiTab; // tab stops in logical units

      virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMis);
      virtual void DrawItem(LPDRAWITEMSTRUCT lpDis);
      

      };

      // CtestDlg dialog
      class CtestDlg : public CDialogEx
      {
      // Construction
      public:
      CtestDlg(CWnd* pParent = NULL); // standard constructor

      // Dialog Data
      enum { IDD = IDD_TEST_DIALOG };

      protected:
      virtual void DoDataExchange(CDataExchange\* pDX);	// DDX/DDV support
      

      // Implementation
      protected:
      HICON m_hIcon;

      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx\_msg void OnSysCommand(UINT nID, LPARAM lParam);
      afx\_msg void OnPaint();
      afx\_msg HCURSOR OnQueryDragIcon();
      DECLARE\_MESSAGE\_MAP()
      

      public:
      CTabCBox m_ctrlFontsX;
      CComboBox m_ctrlFonts;
      };

      // from INITDIALOG
      // TODO: Add extra initialization here
      TEXTMETRIC tm;
      int iTab;

      // compute tab stop
      if (m\_ctrlFonts.GetDC()->GetTextMetrics(&tm))
      	iTab = (33+8) \* tm.tmAveCharWidth;
      
      m\_ctrlFontsX.SubclassCBox(IDC\_COMBO1,this,1,&iTab);
      
      CString csS("Font title string\\tnnnnnnnn");
      
      m\_ctrlFontsX.AddString(csS);
      

      BOOL CTabCBox::SubclassCBox(UINT nID, CWnd* pParent, int icTabs, LPINT lpiTabs)
      {
      DWORD dwcb;
      int iRc = 0;

      // make very sure all tab members are free and clear
      if (lpiTab)
      	free(lpiTab);
      lpiTab = NULL;
      icTab = 0;
      
      if (icTabs>0)
      	{
      	// make copy of tab info
      	dwcb = icTabs\*sizeof(int);
      	if (!(lpiTab = (LPINT)malloc(dwcb)))
      		return(FALSE);
      	memcpy(lpiTab,lpiTabs,(size\_t)dwcb);
      	icTab = icTabs;
      	}
      iRc = SubclassDlgItem(nID, pParent); // THIS CAUSES THE ASSERT
      return(iRc);
      

      } // end of SubclassCBox

      It always fails on the second assert (FromHandle....) from wincore.cpp
      BOOL CWnd::Attach(HWND hWndNew)
      {
      ASSERT(m_hWnd == NULL); // only attach once, detach on destroy
      ASSERT(FromHandlePermanent(hWndNew) == NULL);
      // must not already be in permanent map

      Tony Teveris Gerb

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      Hi Tony, My guess would be that your CtestDlg::DoDataExchange function has a DDX_Control[^] entry for the m_ctrlFontsX member. If I am correct then you should comment it out or remove it. This happens when you right click a control in the VS dialog editor and choose 'Add Variable'. Visual Studio will add a member variable along with a DDX entry in the DoDataExchange function. Essentially what is happening is that MFC has already subclassed the control and added the handle into the internal permanent handle map. Here is an excellent document explaining MFC handles and temporary CWnd* objects: Inside MFC: Handle Maps and Temporary Objects[^] Let me know if I was correct. Best Wishes, -David Delaune

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups