禁用对话框确定按钮 MFC

问题描述 投票:0回答:6

如何禁用 MFC 对话框的“确定”按钮?
此代码:

CWnd* fieldOK = pDlg->GetDlgItem(IDOK);
fieldOK->EnableWindow(FALSE);

导致异常“Access violation reading location...” 在函数
ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));
CWnd::EnableWindow(BOOL bEnable)
行中
winnocc.cpp
mfc90d.dll

这次重点放在另一个控件上。
什么是错的?

感谢您的帮助。

[编辑]

bool CSCalcNormCell::OnSelectionChanged( CWnd* pDlg, int type, int page, UINT ctrl_id ) 
{ 
  DDX_DataBox(pDX.get(), IDC_WORKSHOP_COMBO, ws_code); 
  if (!CInfactoryPriceAdapter::CanEditPricesForWorkshop( ws_code )) 
  { 
    CWnd* fieldOK = pDlg->GetDlgItem(IDOK); 
    fieldOK->EnableWindow(FALSE); 
  } 
  else 
  { 
    CWnd* fieldOK = pDlg->GetDlgItem(IDOK); 
    fieldOK->EnableWindow(TRUE); 
  } 
}
c++ mfc dialog
6个回答
6
投票

我不确定为什么不能这样做。如果我使用常规的 CDialog 并像这样进行初始化:

BOOL CMyDialog::OnInitDialog() {
    CDialog::OnInitDialog();
    CWnd *okbtn = GetDlgItem( IDOK );
    if ( okbtn ) {
        okbtn->EnableWindow( FALSE );
    }
    return TRUE;
}

它可以很好地禁用按钮。也许还有其他问题?


2
投票

试试这个:http://support.microsoft.com/kb/122489

如何禁用 MFC 对话框的默认按钮处理

虽然建议默认按钮(按钮)支持,但您可能 想要在某些方面禁用或修改标准实现 情况。您可以按照这些在 MFC 应用程序中执行此操作 步骤:

将对话框加载到 App Studio 中并更改 OK 按钮标识符 从 IDOK 到其他东西,例如 IDC_MYOK。另外,清除支票 来自默认按钮属性。

使用 ClassWizard 创建消息 此按钮的处理函数名为 OnClickedMyOK。这个功能 将在从这里收到 BN_CLICKED 消息时执行 按钮。

在OnClickedMyOK的代码中,调用基类版本 OnOK 函数。这是一个例子:

void CMyDialog::OnClickedMyOK()
   {
      CDialog::OnOK();
   }

为您的对话框重写 OnOK,并且在函数内部什么也不做。这是一个例子:

void CMyDialog::OnOK()
   {
   }

运行程序并弹出对话框。将焦点放在其他控件上 比确定按钮。按返回键。请注意 CDialog::OnOK() 永远不会被执行。


1
投票

我怀疑问题出在

pDlg
指针。当您调用
pDlg->GetDlgItem(IDOK)
时,对话框是否已经创建?

CWnd* fieldOK = pDlg->GetDlgItem(IDOK);
行下断点并调试它以查看fieldOK指针是否为空或有效指针。

这就是为什么我认为

mark's answer is very close. You can disable it on
OnInitDialog` 或您对话类的其他成员出现后的原因。


0
投票

你遇到的问题是界面上还没有创建按钮控件。我们无法全面了解您的问题。

无论如何,你应该保护你的代码免于崩溃。最好让您的代码什么也不做,而不是让应用程序崩溃。像这样重构它避免了由于 NULL 指针导致的访问冲突问题:

bool CSCalcNormCell::OnSelectionChanged( CWnd* pDlg, int type, int page, UINT ctrl_id ) 
{ 
    DDX_DataBox(pDX.get(), IDC_WORKSHOP_COMBO, ws_code);

    CWnd* fieldOK = pDlg->GetDlgItem(IDOK); 
    if (fieldOK)
    {
        if (!CInfactoryPriceAdapter::CanEditPricesForWorkshop( ws_code )) 
            fieldOK->EnableWindow(FALSE); 
        else
            fieldOK->EnableWindow(TRUE); 
     }
}

0
投票

需要在 LoadBitmaps() 函数中为 OK 按钮的禁用模式加载位图


0
投票

我不知道是什么导致了异常,我也得到了它,但我发现了一种使用命令更新处理程序禁用按钮的替代方法,遵循 https://forums.codeguru.com/showthread.php?314881-CButton -class-how-to-grey-out-a-command-button&p=1033756#post1033756 达文的回答。

这对我来说很好(来自 darwen 的代码):

    afx_msg void OnUpdateButton(CCmdUI *pCmdUI); // Declaration
    
    void CYourClass::OnUpdateButton(CCmdUI *pCmdUI) // Definition
    {
        pCmdUI->Enable(enableButton); // BOOL enableButton
    }
    
    ON_UPDATE_COMMAND_UI(ID_BUTTON, OnUpdateButton) // On message map
© www.soinside.com 2019 - 2024. All rights reserved.