SubclassDlgItem()调试断言失败

时间:2017-02-16 13:54:25

标签: visual-c++ mfc

我创建了一个带自定义控件的dailog框。我在我的应用程序中使用终极网格。 (https://www.codeproject.com/Articles/20183/The-Ultimate-Grid-Home-Page)。

运行项目时出现错误(Debug Assertion Failed)。

BOOL CCustomControlDlg::OnInitDialog()
{   
    CDialog::OnInitDialog();

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
    // Add "About..." menu item to system menu.
    m_grid.AttachGrid(this, IDC_CUSTOM1);//    ERROR LINE

    return TRUE;  // return TRUE  unless you set the focus to a control
}

//Attach grid implementation
BOOL CUGCtrl::AttachGrid(CWnd * wnd,UINT ID){

    if( SubclassDlgItem(IDC_CUSTOM1,wnd))  // ERROR LINE
    {
        long style = GetWindowLong(m_hWnd,GWL_STYLE);
        style = style|WS_CLIPCHILDREN|WS_TABSTOP;
        SetWindowLong(m_hWnd,GWL_STYLE,style);

        // if the parent window is specified
        if(wnd!= NULL)
        {
            LOGFONT logFont;
            CFont *pTempFont = wnd->GetFont();
            pTempFont->GetLogFont( &logFont );

            // ceate a font object based on the font information retrieved from
            // parent window.  This font will be used as grid's default font.
            int nIndex = AddFont( logFont.lfHeight, logFont.lfWidth, logFont.lfEscapement,
                     logFont.lfOrientation, logFont.lfWeight, logFont.lfItalic,
                     logFont.lfUnderline, logFont.lfStrikeOut, logFont.lfCharSet,
                     logFont.lfOutPrecision, logFont.lfClipPrecision, 
                     logFont.lfQuality, logFont.lfPitchAndFamily, logFont.lfFaceName );

            SetDefFont( nIndex );

            // create a font that will be used for the heading cells.  This object
            // is almost identical to the grid's default font, except its weight
            // was increased by 200.
            nIndex = AddFont( logFont.lfHeight, logFont.lfWidth, logFont.lfEscapement,
                     logFont.lfOrientation, logFont.lfWeight + 200, logFont.lfItalic,
                     logFont.lfUnderline, logFont.lfStrikeOut, logFont.lfCharSet,
                     logFont.lfOutPrecision, logFont.lfClipPrecision, 
                     logFont.lfQuality, logFont.lfPitchAndFamily, logFont.lfFaceName );

            CUGCell cell;
            GetHeadingDefault( &cell );
            cell.SetFont( GetFont( nIndex ) );
            SetHeadingDefault( &cell );
        }

        CreateChildWindows();
        // When WS_EX_RTLREADING style was specified for the place holder
        // window, then set the grid to be in RTL layout mode.
        style = GetWindowLong( m_hWnd, GWL_EXSTYLE );
        if ( style&WS_EX_RTLREADING )
            SetGridLayout( 1 );

        OnSetup();
        OnSheetSetup(0);

        // Allow drawing after the grid is initialized
        m_GI->m_paintMode = TRUE;
        // Adjust the grid's components to fit current setup
        AdjustComponentSizes();

        return TRUE;
    }

    return FALSE;
}

enter image description here

任何人都知道如何解决这个问题?

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif

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

// Implementation
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
}

void CCustomControlDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CCustomControlDlg)
    // NOTE: the ClassWizard will add DDX and DDV calls here
    DDX_Control(pDX, IDC_CUSTOM1, m_drawpad);
    //}}AFX_DATA_MAP
}

1 个答案:

答案 0 :(得分:1)

问题是,您将两个不同的C ++对象附加到同一个控件(IDC_CUSTOM1)。 DoDataExchange()中的条目通过调用DDX_Control(pDX, IDC_CUSTOM1, m_drawpad);隐式执行子类化,而OnInitDialog()中的代码更明确(m_grid.AttachGrid(this, IDC_CUSTOM1);),但基本上做同样的事情。

要解决此问题,您可以选择多种选项,具体取决于您的目标:

  • 如果您不需要DDX_Control()附加DoDataExchange()对象,请移除m_drawpad中的IDC_CUSTOM1来电。
  • 如果您不需要m_grid.AttachGrid()附加OnInitDialog()对象,请移除m_grid内的IDC_CUSTOM1来电。
  • 在对话框资源中添加一个额外的控件占位符,并将其用于其中任何一个对象,以备两者同时使用。