Есть ли список элементов управления или контейнера элементов управления, определенных в диалоговом окне MFC?

Я спрашиваю о списке или элементах управления контейнера в диалоге MFC? я не имею в виду перечисление дочерних окон диалогового окна, как этот вопрос. Перейдите через дочерние диалоги MFC, MDIFrames и т. д. Я хочу получить список элементов управления, определенных как переменные в классе диалога, для которых применяется метод DDX_Control.

мне нужно иметь список всех управляющих переменных, определенных в диалоге

2 ответа

Там нет такой вещи. DDX использует элемент управления, потому что соответствующая функция DDX_* вызывается в методе DoDataExchange вашего диалогового класса. Нет таблицы, которую вы могли бы проанализировать, и поэтому вы не можете динамически определить, какая функция DDX_* вызывается в вашем методе DoDataExchange.

void CMySampleDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CReprendBudgetDlg)
    DDX_Text(pDX, IDC_EDIT1, m_name1);
    DDX_Text(pDX, IDC_EDIT2, m_name2);
    //}}AFX_DATA_MAP
}

Но вы могли бы "переопределить" функции DDX_* некоторыми своими собственными функциями, которые бы помещали идентификаторы элементов управления в массив. Поэтому после выполнения функции DoDataExchage этот массив будет содержать все идентификаторы элементов управления, используемые DDX.

void AFXAPI MY_DDX_Text(CDataExchange* pDX, int nIDC, CString& value, CWordArray & ddxcontrols)
{
  DDX_Text(pDX, nIDC, value);
  if (!pDX->bSaveAndValidate)
    ddxcontrols.Add(nIDC) ;
}


#define DDX_Text(a,b,c) MY_DDX_Text(a,b,c)  // now we can continue to use DDX_Text
                                            // and the Class Wizard will be happy

class CMySampleDlg : public CDialog
{
 ...
  protected:
    CWordArray m_ddxcontrols ;  // array that will contain all control IDs use by DDX
  ...
}


void CMySampleDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CReprendBudgetDlg)
    DDX_Text(pDX, IDC_EDIT1, m_name1, m_ddxcontrols);
    DDX_Text(pDX, IDC_EDIT2, m_name2, m_ddxcontrols);
    //}}AFX_DATA_MAP
}

Так что все, что вам нужно сделать, это

  • Напишите функции MY_DDX_* для всех функций DDX_* (они определены в afxdd_.h).
  • Во всех ваших диалогах заменяйте все вызовы функций DDX_* на мои функции MY_DDX_*
  • Поместите участников m_ddxcontrols во все ваши диалоги

Ничего из того, что я знаю, но вы можете скопировать идентификаторы ресурса управления из блока DoDataExchange в массив с нулевым терминатором:

const UINT myControls[] =
{
  IDC_EDIT1,      IDC_EDIT2,      IDC_EDIT3,
  IDC_BUTTON1,    IDC_BUTTON2,    IDC_BUTTON3,
  IDC_STATIC1,    IDC_STATIC2,    IDC_STATIC3,
  0
};

затем вы можете использовать этот массив для перебора элементов управления, как вы хотите:

for (const UINT* p = myControls; *p; ++p)
{
    CWnd *wnd = GetDlgItem(*p);
    ...
}

Не динамическое решение, но достаточно простое.

Другие вопросы по тегам