简体   繁体   English

禁用对话框确定按钮MFC

[英]Disabling dialog OK button MFC

How do I disable MFC dialog OK button? 如何禁用MFC对话框确定按钮?
This code: 这段代码:
CWnd* fieldOK = pDlg->GetDlgItem(IDOK);
fieldOK->EnableWindow(FALSE);

causes exception " Access violation reading location... " in line ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));行中导致异常“ 访问冲突读取位置...ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); of function CWnd::EnableWindow(BOOL bEnable) in winnocc.cpp from mfc90d.dll 的功能CWnd::EnableWindow(BOOL bEnable)winnocc.cppmfc90d.dll
In this time focus is on another control. 在这个时候,重点是另一个控制。
What's can be wrong? 什么是错的?

Thanks for help. 感谢帮助。

[EDITED] [EDITED]

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); 
  } 
}

I'm not sure why would wouldn't be able to do it. 我不确定为什么不能这样做。 If I take a regular CDialog and I do an init like this: 如果我采用常规的CDialog,我会像这样做一个init:

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

it disables the button just fine. 它禁用按钮就好了。 Perhaps something else is wrong? 也许别的什么不对?

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

How to Disable Default Pushbutton Handling for MFC Dialog 如何禁用MFC对话框的默认按钮处理

Although default button (pushbutton) support is recommended, you might want to disable or modify the standard implementation in certain situations. 虽然建议使用默认按钮(按钮)支持,但您可能希望在某些情况下禁用或修改标准实现。 You can do this in an MFC application by following these steps: 您可以按照以下步骤在MFC应用程序中执行此操作:

Load the dialog into App Studio and change the OK button identifier from IDOK to something else such as IDC_MYOK. 将对话框加载到App Studio中,将OK按钮标识符从IDOK更改为其他内容,例如IDC_MYOK。 Also, clear the check from Default Button property. 另外,清除Default Button属性中的检查。

Use ClassWizard to create a message handling function for this button named OnClickedMyOK. 使用ClassWizard为名为OnClickedMyOK的按钮创建消息处理函数。 This function will be executed when a BN_CLICKED message is received from this button. 当从此按钮收到BN_CLICKED消息时,将执行此功能。

In the code for OnClickedMyOK, call the base class version of the OnOK function. 在OnClickedMyOK的代码中,调用OnOK函数的基类版本。 Here is an example: 这是一个例子:

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

Override OnOK for your dialog, and do nothing inside the function. 覆盖OnOK为您的对话框,并在函数内部不执行任何操作。 Here is an example: 这是一个例子:

void CMyDialog::OnOK()
   {
   }

Run the program and bring up the dialog. 运行程序并调出对话框。 Give focus to a control other than the OK button. 将焦点置于“确定”按钮以外的控件上。 Press the RETURN key. 按RETURN键。 Notice that CDialog::OnOK() is never executed. 请注意,CDialog :: OnOK()永远不会执行。

I suspect the problem comes from pDlg pointer. 我怀疑问题来自pDlg指针。 When you call pDlg->GetDlgItem(IDOK) , is the dialog already created already? 当你调用pDlg->GetDlgItem(IDOK) ,是否已经创建了对话框?

Make a breakpoint at the line CWnd* fieldOK = pDlg->GetDlgItem(IDOK); CWnd* fieldOK = pDlg->GetDlgItem(IDOK);行创建一个断点CWnd* fieldOK = pDlg->GetDlgItem(IDOK); and debug into it to see if fieldOK pointer is null or a valid pointer. 并调试它以查看fieldOK指针是否为空或有效指针。

That is why I think mark's answer is very close. You can disable it on 这就是为什么我认为mark's answer is very close. You can disable it on mark's answer is very close. You can disable it on OnInitDialog` or other members of you dialog class after it showed up. mark's answer is very close. You can disable it on OnInitDialog`或对话框类的其他成员出现后将其mark's answer is very close. You can disable it on

The problem you have is that the button control has not been created on the interface yet. 您遇到的问题是尚未在界面上创建按钮控件。 We do not get the full vision of your problem. 我们无法全面了解您的问题。

Anyway, you should protect your code from crashing. 无论如何,你应该保护你的代码不会崩溃。 It is better that your code does nothing than to crash the application. 您的代码最好不要使应用程序崩溃。 Restructuring it like this avoids the access violation problem due to the NULL pointer: 像这样重构它可以避免由于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); 
     }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM