我有一个对话框,其中包含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);
.
.
.
这种方式有效,但是我想知道是否有更简单的方式?任何帮助,将不胜感激。谢谢!
答案 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的更多信息。
实施:
在对话框标题中声明一个CMap,它将保留单选按钮的状态。它在对话框控件ID和状态之间进行映射。
CMap <UINT, UINT, int, int> m_Radios;
这是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();
}
添加对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真的不是很混乱吗?考虑改用下拉列表。还是说复选框而不是单选按钮?使用单选按钮的“缺陷配置”将只允许选择一个“缺陷”。