【问题标题】:Effect of destroying OK, CANCEL and HELP windows of a porperty sheet破坏属性表的 OK、CANCEL 和 HELP 窗口的效果
【发布时间】:2015-03-30 11:02:23
【问题描述】:

我想在一个项目中使用基于 CPropertySheet 的应用程序,但我不想使用 CPropertySheet 类附带的那些默认的 OK、Cancel、Help 和 Apply 按钮。因此,我销毁了 OnInitDialog 上的那些窗口。以下是参考代码:

BOOLCProductUI::OnInitDialog()
{
    CPropertySheet::OnInitDialog();

    CRect rect;
    CButton *pTempBtn;
    CButton SaveChanges;

    pTempBtn = reinterpret_cast<CButton *>(GetDlgItem(IDHELP));
    if (NULL != pTempBtn)
    {
        pTempBtn->GetWindowRect(&rect);
        pTempBtn->DestroyWindow();
    }

    pTempBtn = reinterpret_cast<CButton *>(GetDlgItem(IDOK));
    if (NULL != pTempBtn)
    {
        pTempBtn->DestroyWindow();
    }

    pTempBtn = reinterpret_cast<CButton *>(GetDlgItem(IDCANCEL));
    if (NULL != pTempBtn)
    {
        pTempBtn->DestroyWindow();
    }

    pTempBtn = reinterpret_cast<CButton *>(GetDlgItem(ID_APPLY_NOW));
    if (NULL != pTempBtn)
    {
        ScreenToClient(&rect);
        pTempBtn->MoveWindow(rect);
        pTempBtn->SetWindowText(_T("Save Changes"));
    }

    UpdateData(FALSE);
    return TRUE;
}

CProductUI 是 CPropertySheet 的一个类。
但是,当我在调试模式下使用 VC++2008 编译程序时,我在行
处收到 Debug Assertion Failed 错误消息 "CPropertySheet::OnInitDialog();"
谁能解释一下为什么会这样?

【问题讨论】:

  • Assert message 应该可以帮助您了解问题所在。一般来说,不要销毁它们,只需隐藏即可。
  • 我的第一个动作是摧毁它们。我意识到 DestroyWindow() 会引起一些问题,但是我评论了这些调用并尝试使用 ShowWindow(SW_HIDE) 运行我的应用程序,但在调试模式下遇到了相同的调试断言。
  • 确切的错误信息是什么?连同行号(在同一条消息中),它应该突出显示出了什么问题。
  • 调试断言失败错误消息框包含以下程序:(我的 exe 的路径)文件:f:\dd\vctool\vc7libs\ship\atlmfc\include\afxcmn.inl 行:268
  • LOL 是的,我有 MFC 源代码,但您可以看到 OnInitDialog() 中有许多 ASSERT。哪一个失败了?

标签: c++ mfc dialog cpropertysheet


【解决方案1】:

根据How to Hide the Apply Button in CPropertySheet。销毁窗口不是隐藏属性表默认按钮的正确解决方案。我建议你使用 "ShowWindow()"。但是正如您已经提到的,您的 showwindow() 也会产生问题,如果您的调用正确,这是不可能的。顺其自然,如果您的 ShowWindow() 在“OnInitDialog()”函数中不起作用,那么最好将此函数移至“OnCreate()”。如果它不起作用,请分享您的整个 .H 和 .CPP 文件。

【讨论】:

    【解决方案2】:
    1. 你应该打电话给ShowWindow (SW_HIDE);而不是DestroyWindow();
    2. 也不需要将GetDlgItem()返回的CWnd*转换为CButton*
    3. 还请注释掉您的CButton SaveChanges; 声明。你 不需要。

    您也可以使用内置标志来做到这一点:

    CMyPropertyPage myPage;
    myPage.m_psp.dwFlags &= ~PSP_HASHELP;
    myPropertySheet.AddPage(&myPage);
    
    myPropertySheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
    myPropertySheet.m_psh.dwFlags &= ~PSH_HASHELP;
    

    重要提示:一般情况下,请在调试模式下运行您的应用程序以查看它断言的位置。

    【讨论】:

    • 任何方法来撤消我对 DestroyWindow() 的调用造成的损害,因为在评论了对 DestroyWindow() 的调用然后隐藏窗口之后,我仍然收到相同的错误消息。 DestroyWindow() 是否篡改了属性表的默认设置?
    • 在调试模式 (F5) 下运行应用程序,您将看到它在调试器中断言的确切行。
    • 您还需要禁用任何隐藏按钮。因此,除了调用ShowWindow(SW_HIDE),您还需要在CWnd 上调用EnableWindow(false),否则按钮仍将通过制表键和按钮文本“&”加速键击“激活”。
    • 内置标志仅适用于应用和帮助按钮。我需要重新创建我的项目吗?
    • 不,您不需要重新创建项目。您是否能够识别它断言的行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2014-11-06
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多