MFC 自定义控件未出现在对话框中
MFC Custom Control Not Appearing On Dialog
使用Visual Studio 2013,我使用资源编辑器创建了一个对话框资源。它是一个没有边框的子控件,只是单选按钮、普通按钮和静态文本的集合。我想把它变成一个自定义控件,以便将它放在几个不同的位置。我们称其为 "Panel".
然后我创建了一个常规对话框并使用工具箱 "Custom Control",为面板定义了一个区域。 Panel 自行注册并具有有效的 window 句柄。
我用了下面的例子:
https://www.codeproject.com/Articles/521/Creating-Custom-Controls
父级的 DDX 被击中并且 _panel 被正确实例化:
MyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX)
DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)
}
我读到我需要覆盖 OnPaint() 和 OnEraseBkgnd(CDC* pDC) 方法,以便面板 class 具有这些方法,但它们是空的。我没有任何自定义绘画要做,因为面板只包含常规按钮。
我必须在 OnPaint() 中包含什么?
我还注意到 none 的成员按钮在面板中被实例化,就像通常在对话框的 DoDataExchange 方法中发生的那样。相反,我不得不求助于在面板的 PreSubclassWindow() 方法中动态创建每个控件:
void MyPanel:PreSubclassWindow()
{
_groupBox.Create(_T("Options"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, CRect(11, 11, 112, 231), this, IDC_STATIC_GROUPBOX);
//... do this for every dialog element??? seems like overkill...
CWnd::PreSubclassWindow()
}
当我已经 defined/designed 资源编辑器中的面板及其每个控件时,为什么还需要这样做?
如果我在 PreSubclassWindow 方法中不这样做,对话框中将不会出现任何内容。
感谢任何帮助。谢谢
文章说如果您想更改功能,请覆盖 OnPaint
和 OnEraseBkgnd
。它并不是说你必须总是覆盖。
只需删除 ON_WM_PAINT
和 ON_WM_ERASEBKGND
,如果不需要,请删除 OnPaint
和 OnEraseBkgnd
。或者,如果您不进行任何更改,则调用基础 class 实现:
void MyPanel::OnPaint() { CWnd::OnPaint(); }
BOOL MyPanel::OnEraseBkgnd(CDC* pDC) { return CWnd::OnEraseBkgnd(pDC); }
这将显示一个空白控件,其中没有任何内容,除非您像在 MyPanel:PreSubclassWindow
中那样将子项 window 添加到 _panel
您正在将 _groupBox
添加到 _panel
。您正在将 _panel
添加到 MyDialog
。
需要 MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)}
才能为 _panel
调用 SubclassWindow
。依次调用 _groupBox.Create
.
如果 MyPanel::OnPaint
和 MyPanel::PreSubclassWindow
没有做任何事情 MyPanel
显示为空白控件。
... do this for every dialog element??? seems like overkill...
您可以直接在主对话框中添加_groupBox
。但是如果你想在 MyPanel
中添加特定的控件,那么你必须手动进行。
您还可以在主对话框中创建子对话框。例如,这就是选项卡控件的工作方式。
使用Visual Studio 2013,我使用资源编辑器创建了一个对话框资源。它是一个没有边框的子控件,只是单选按钮、普通按钮和静态文本的集合。我想把它变成一个自定义控件,以便将它放在几个不同的位置。我们称其为 "Panel".
然后我创建了一个常规对话框并使用工具箱 "Custom Control",为面板定义了一个区域。 Panel 自行注册并具有有效的 window 句柄。
我用了下面的例子: https://www.codeproject.com/Articles/521/Creating-Custom-Controls
父级的 DDX 被击中并且 _panel 被正确实例化:
MyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX)
DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)
}
我读到我需要覆盖 OnPaint() 和 OnEraseBkgnd(CDC* pDC) 方法,以便面板 class 具有这些方法,但它们是空的。我没有任何自定义绘画要做,因为面板只包含常规按钮。
我必须在 OnPaint() 中包含什么?
我还注意到 none 的成员按钮在面板中被实例化,就像通常在对话框的 DoDataExchange 方法中发生的那样。相反,我不得不求助于在面板的 PreSubclassWindow() 方法中动态创建每个控件:
void MyPanel:PreSubclassWindow()
{
_groupBox.Create(_T("Options"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, CRect(11, 11, 112, 231), this, IDC_STATIC_GROUPBOX);
//... do this for every dialog element??? seems like overkill...
CWnd::PreSubclassWindow()
}
当我已经 defined/designed 资源编辑器中的面板及其每个控件时,为什么还需要这样做?
如果我在 PreSubclassWindow 方法中不这样做,对话框中将不会出现任何内容。
感谢任何帮助。谢谢
文章说如果您想更改功能,请覆盖 OnPaint
和 OnEraseBkgnd
。它并不是说你必须总是覆盖。
只需删除 ON_WM_PAINT
和 ON_WM_ERASEBKGND
,如果不需要,请删除 OnPaint
和 OnEraseBkgnd
。或者,如果您不进行任何更改,则调用基础 class 实现:
void MyPanel::OnPaint() { CWnd::OnPaint(); }
BOOL MyPanel::OnEraseBkgnd(CDC* pDC) { return CWnd::OnEraseBkgnd(pDC); }
这将显示一个空白控件,其中没有任何内容,除非您像在 MyPanel:PreSubclassWindow
_panel
您正在将 _groupBox
添加到 _panel
。您正在将 _panel
添加到 MyDialog
。
MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)}
才能为 _panel
调用 SubclassWindow
。依次调用 _groupBox.Create
.
如果 MyPanel::OnPaint
和 MyPanel::PreSubclassWindow
没有做任何事情 MyPanel
显示为空白控件。
... do this for every dialog element??? seems like overkill...
您可以直接在主对话框中添加_groupBox
。但是如果你想在 MyPanel
中添加特定的控件,那么你必须手动进行。
您还可以在主对话框中创建子对话框。例如,这就是选项卡控件的工作方式。