重置一堆单选按钮

时间:2019-09-12 04:25:13

标签: visual-c++ mfc dialog radio-button

我有一个对话框,其中包含500多个单选按钮。我想创建一个按钮,供用户单击以重置所有单选按钮,以防他/她犯了太多错误。

我尝试过单独做。

void DefectConfigurator::OnBnClickedButton2()
{      
        CButton* pBtn1 = (CButton*) GetDlgItem(IDC_AAAA);
        pBtn1->SetCheck(0);
        CButton* pBtn2 = (CButton*) GetDlgItem(IDC_BBBB);
        pBtn2->SetCheck(0);
        CButton* pBtn3 = (CButton*) GetDlgtem(IDC_CCCC);
        pBtn3->SetCheck(0);
            .
            .
            .

这种方式有效,但是我想知道是否有更简单的方式?任何帮助,将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:1)

int n = in.nextInt(), q = in.nextInt(); int[] x = new int[n]; for (int i = 0; i < n; i++) { x[i] = in.nextInt(); } int[] a = new int[n]; while (q-- > 0) { int i = in.nextInt(); a[i] = 1; } int max = 0; for (int i = 0; i < n; i++) { if (a[i] == 1) { max = Math.max(max, x[i]); } if (x[i] < max) { x[i] = 0; } } for (int i = 0; i < n; i++) { out.print(x[i]); out.print(' '); } 控件ID只是resource.h文件中的数字。因此,请确保IDC_IDC_AAAA ... IDC_BBBB等是连续的且无中断。然后只需在IDC_ZZZZ循环中进行迭代:

for

如果要谨慎,可以将for (UINT nID = IDC_AAAA; nID <= IDC_ZZZZ; ++nID) { CButton* pBtn = static_cast<CButton *>(GetDlgItem(nID)); pBtn->SetCheck(BST_UNCHECKED); } 替换为static_cast以进行运行时类型检查,然后检查空指针。

答案 1 :(得分:0)

在MFC中,建议在控件和变量之间交换数据的方法是DDX。它使用DoDataExchange函数,该函数由MFC向导默认创建(在大多数情况下)。通过调用UpdateData函数,可以在UI和变量之间双向交换数据。

一般的想法是在对话框类中有一个变量,该变量保存单选组的当前状态(未选中任何项或选中的按钮的索引)。这是通过DDX_Radio函数完成的。您在此article中有一个简单的示例。

回到您的问题:

如果您有500个单选按钮,则它们可能会分成不同的组。该组中的第一个单选按钮具有WS_GROUP样式,并且同一组中的所有后续单选按钮不得具有WS_GROUP样式。 有关MFC单选按钮和DDX here的更多信息。

实施:

  1. 在对话框标题中声明一个CMap,它将保留单选按钮的状态。它在对话框控件ID和状态之间进行映射。

    CMap <UINT, UINT, int, int> m_Radios;
    
  2. 这是DDX函数:

    void CMFC1Dlg::DDX_CustomRadios(CDataExchange* pDX)
    {
        // 1. enumerate all radio groups.
        // 2. call to a DDX_Radio implementation  
        CWnd * wnd = pDX->m_pDlgWnd->GetWindow(GW_CHILD);
        while (wnd)
        {
            // verify if this is radio button with WS_GROUP style.
            if (wnd->GetStyle() & WS_GROUP &&
                wnd->SendMessage(WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON)
            {           
    #define CLEAR_STATE -1
                int radioState = CLEAR_STATE;
                int radioId = wnd->GetDlgCtrlID();
    
                if(!pDX->m_bSaveAndValidate)
                    if (!m_Radios.Lookup(radioId, radioState))
                        m_Radios[radioId] = radioState;
    
                DDX_Radio(pDX, radioId, radioState);
    
                m_Radios[radioId] = radioState;
            }
    
            wnd = wnd->GetNextWindow();
        }   
    
  3. 添加对DoDataExchange的呼叫:

    void CMFC1Dlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX); 
    
        DDX_CustomRadios(pDX);
    }       
    

用法:

清除所有单选按钮:

    void CMFC1Dlg::OnBnClearAll()
    {
        m_Radios.RemoveAll();

        UpdateData(FALSE); // this updates the ui
    }

将UI中的所有按钮状态保存到变量:

    void CMFC1Dlg::OnBnSaveAll()
    {
        UpdateData(TRUE);

        POSITION pos = m_Radios.GetStartPosition();
        while (pos != NULL)
        {
            UINT nId = 0;
            BOOL state = 0;

            m_Radios.GetNextAssoc(pos, nId, state);

            TRACE("Control: %d State: %d\r\n", nId, state);
        }
    }

答案 2 :(得分:0)

我宁愿使用CheckRadioButton() Win32函数:

CheckRadioButton(m_hWnd, IDC_AAAA, IDC_AAAA + 500 - 1, -1);

尚未测试过,但请检查以下两点:

  • 文档中没有具体提及它,但是nIDLastButton参数似乎具有包容性,因此我使用了IDC_AAAA + 500 - 1
  • 我将nIDCheckButton设置为-1,这应该不会导致选中任何单选按钮。

您可以选择使用DDX / DDV,DDX_Radio()函数可以为您完成所有工作(写入和读取数据)。在调用UpdateData(FALSE)之前将变量设置为-1。请记住,这是进入无线电组的索引,而不是控件标识符。

作为旁注,具有500个单选按钮的UI真的不是很混乱吗?考虑改用下拉列表。还是说复选框而不是单选按钮?使用单选按钮的“缺陷配置”将只允许选择一个“缺陷”。

相关问题