Используя Visual Studio 2013, я создал диалоговый ресурс с помощью редактора ресурсов. Это дочерний элемент управления без границ, это просто набор переключателей, кнопок и статического текста. Я хочу превратить это в пользовательский элемент управления, чтобы разместить его в нескольких разных местах. Давайте назовем это «Панель».
Затем я создал обычный диалог и с помощью панели инструментов «Пользовательский элемент управления» определил область для Panel. Панель сама регистрируется и имеет действительный дескриптор окна.
Я использовал следующий пример:
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), чтобы класс Panel имел их, но они пусты. У меня нет никакой настраиваемой рисования, так как панель содержит только обычные кнопки.
Что я должен включить в OnPaint ()?
Я также заметил, что ни одна из кнопок-членов не создается в Panel, как это обычно происходит в методе диалога DoDataExchange. Вместо этого мне пришлось прибегнуть к динамическому созданию каждого элемента управления внутри метода PreSubclassWindow () Panel:
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()
}
Зачем мне это делать, если я уже определил / спроектировал Panel и каждый из ее элементов управления в редакторе ресурсов?
Если я не сделаю этого в методе PreSubclassWindow, в диалоговом окне ничего не появится.
Любая помощь приветствуется. Благодарю.
Статья говорит переопределить OnPaint
а также OnEraseBkgnd
если вы хотите изменить функциональность. Это не говорит, что вы должны переопределять всегда.
Просто удали ON_WM_PAINT
а также ON_WM_ERASEBKGND
, Удалить OnPaint
а также OnEraseBkgnd
если они тебе не нужны Или вызовите реализации базового класса, если вы не вносите никаких изменений:
void MyPanel::OnPaint() { CWnd::OnPaint(); }
BOOL MyPanel::OnEraseBkgnd(CDC* pDC) { return CWnd::OnEraseBkgnd(pDC); }
Это покажет пустой элемент управления без ничего, если вы не добавите дочернее окно в _panel
как вы сделали в MyPanel:PreSubclassWindow
Вы добавляете _groupBox
в _panel
, И вы добавляете _panel
к MyDialog
,
MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)}
необходимо вызвать SubclassWindow
за _panel
, Что в свою очередь вызывает _groupBox.Create
,
Если MyPanel::OnPaint
а также MyPanel::PreSubclassWindow
ничего не делаем MyPanel
отображается как пустой элемент управления.
… сделать это для каждого элемента диалога ??? кажется излишним …
Вы можете напрямую добавить _groupBox
к основному диалогу. Но если вы хотите добавить определенные элементы управления в MyPanel
тогда вы должны сделать это вручную.
Вы также можете создать дочерний диалог в главном диалоге. Например, так работает элемент управления вкладками.
Других решений пока нет …