【问题标题】:Is there a list of controls or controls container defined in an MFC dialog是否有在 MFC 对话框中定义的控件列表或控件容器
【发布时间】:2013-04-17 23:33:49
【问题描述】:

我在询问 mfc 对话框中的列表或控件容器?我并不是说像这个问题Loop through MFC Child Dialogs, MDIFrames etc 那样列出对话框的子窗口,我想要的是在对话框类中定义为变量的控件列表,这些控件应用了 DDX_Control 方法。

我需要在对话框中定义所有控制变量的列表

【问题讨论】:

  • 据我所知,没有这样的东西。每当我不得不遍历所有控件时,我都会遍历子窗口。你想做什么才能需要它?
  • 我有一个以前编写的应用程序,其中的类不依赖于 mfc,而是 owl,控件已在构造函数中初始化,但现在我要迁移到 MFC,我需要在 DoDataExchange 中初始化它们更改书面代码中的任何内容我有数百个对话框,我有一个映射方法、事件处理宏和消息的策略,完成后我将继续努力回答这个问题stackoverflow.com/questions/15930819/…。我必须在我的项目中重新实现基本控件 [TEdit,..]
  • 所以我将在初始化时将父控件和控件资源 ID 传递给子控件,控件会将其资源 ID 存储在成员变量中,子控件会将自身添加到父控件列表中,在parent 的 DoDataExchange 我们将遍历控件并初始化它们,我希望我可以从 MFC 中找到控件列表

标签: c++ mfc controls containers cdialog


【解决方案1】:

没有这样的事情。 DDX 使用控件是因为在对话框类的 DoDataExchange 方法中调用了相应的 DDX_* 函数。没有可以解析的表,因此无法动态确定在 DoDataExchange 方法中调用了哪个 DDX_* 函数。

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_* 函数,这些函数会将控件 ID 放入数组中。因此,一旦执行了 DoDataExchage 函数,该数组将包含 DDX 使用的所有控件 ID。

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
}

所以你要做的就是

  • 为所有 DDX_* 函数编写 MY_DDX_* 函数(它们是 在 afxdd_.h 中定义)。
  • 在所有对话框中替换所有对 DDX_* 函数的调用,我的 MY_DDX_* 函数
  • 将 m_ddxcontrols 成员放入所有对话框中

【讨论】:

  • 这是一个解决方案,但似乎在类向导中无法理解,我的问题是它是否在 mfc 中是本机的,我不会编辑数百个代码文件,而是我'将向基本对话框添加一个列表,基本控件会将它们自身附加到其父对话框的列表中,在 DoDataExchange 中,我将遍历列表并为每个控件调用 DDX_Control。这将写在一个地方[基础对话框和基础控件]
  • 我刚刚编辑了答案。您可以使用宏,以便类向导继续工作。
【解决方案2】:

我不知道,但您可以将控制资源 ID 从 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);
    ...
}

不是动态解决方案,但足够简单。

【讨论】:

  • 不,我的意思是动态的,总是喜欢动态的,在这个任务中这是必须的
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多