Win32: CreateDialog вместо нескольких вызовов CreateWindow - любые недостатки?

В настоящее время я работаю над программой Win32, которая требует главного окна, содержащего множество дочерних оконных элементов управления - кнопок, списков и т.д. Я считаю, что стандартный способ создания такого окна - сначала вызвать CreateWindow для главного окна, затем снова для каждого из элементов управления.

В качестве более простого варианта я рассматриваю возможность создания главного окна с помощью редактора диалогового окна редактора ресурсов, а затем с помощью CreateDialog для создания главного окна за один раз.

Используя оператор CLASS в шаблоне диалогового окна, я должен получить главное окно для использования пользовательского класса окна (и, следовательно, пользовательской процедуры окна) и, таким образом, избежать появления окна с любым диалоговым поведением. Пример этой методики можно найти в "Программе Windows" Чарльза Петцольда: программу HEXCALC в главе 11.

Есть ли недостатки в создании моего главного окна таким образом? Если так, то кто они? Если нет, почему этот подход редко используется?

Ответ 1

Единственный недостаток CreateDialog, который я знаю (по сравнению с повторным CreateWindow, не говоря о какой-то тяжеловесной структуре, просто Win32 vs Win32) заключается в том, что диалоговые ресурсы располагают дочерние окна с помощью диалоговых блоков. Таким образом, макет зависит не только от DPI, но и от настроек пользовательской темы (выбор и размер шрифта).

Если какой-либо из ваших элементов управления должен иметь фиксированные размеры в пикселях, вы не будете довольны позиционированием, предоставленным диалоговом указателем, и вам нужно будет пройти и переместить все дочерние окна после факта.

Итак, вы можете использовать CreateDialog как ярлык для создания кучи окон с указанными классами и стилями. Но нет, вы не можете сделать свой макет в редакторе диалоговых окон.

OTOH, вы можете сохранить преобразование DLU ↔ пикселей, используемое на вашей машине проектирования, а затем достаточно узнать о разборе внутреннего формата ресурса DIALOG, чтобы вытащить информацию о местоположении, затем преобразовать в пиксели и исправить позиционирование в более автоматизированная мода.

Ответ 2

Вы не контролируете свой цикл сообщений в главном окне - менеджер диалога обрабатывает его для вас. С другой стороны, менеджер диалогов обрабатывает ускорители клавиатуры, порядок табуляции и ряд других эффектов.

Вы будете удивлены тем, что вы можете сделать со стандартным диалоговым окном - управление громкостью Windows реализовано примерно с четырьмя различными диалоговыми окнами - у него есть диалоговое окно с фреймом, в котором хост принимает окно лотка, которое, в свою очередь, удерживает громкость диалоговые окна управления, по одному для каждого объема приложения.

Ответ 3

Вы будете иметь полный контроль над своим окном, даже если он был создан с помощью CreateDialog.

Обычно, когда вы создаете свое собственное окно (вашего класса), используется оконная процедура, которую вы зарегистрировали в классе. Окно OTOH, созданное с помощью CreateDialog, будет иметь процедуру стандартного окна диалога (DefDlgProc), которая в основном будет вызывать ваш обработчик диалогового окна.

Если вы хотите иметь полный контроль над всеми сообщениями, которые вы можете заменить оконным проком только что созданного окна сразу после его создания. Просто позвоните SetWindowLongPtr с параметром GWLP_WNDPROC. Тем не менее, вы можете выполнить автоматическую обработку некоторых специфичных для диалога вещей, вызвав IsDialogMessage в своей процедуре.

Ответ 4

Нет недостатков.

Почему он редко используется? Потому что:

  • Люди обычно используют DialogBox вместо этого, поскольку это проще для более простых случаев.

  • Для более сложных случаев люди используют такие вещи, как MFC или ATL (или внешнюю библиотеку, такую ​​как GTk или Qt), и не утруждают себя собственной графикой Win32.

Ответ 5

Нет недостатков в использовании SDK Windows, внутренние библиотеки, такие как MFC, используют Windows SDK.

Люди склонны использовать библиотеки, такие как MFC, через Windows SDK, поскольку библиотеки имеют готовый материал. Однако вызовы Windows SDK быстрее, чем вызовы библиотеки, поэтому в некоторых ситуациях разработчики напрямую ссылаются на Windows SDK.

CButton btnOk ;
btnOK.Create(_T("Press Me"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(100,100,300,300), pParentWnd, 1);

похож на следующий код,

HWND hWnd = CreateWindow("BUTTON","Press Me",WS_CHILD|WS_POPUP|BS_DEFPUSHBUTTON,100,100,300,300,NULL,NULL,GetModuleHandle(NULL),NULL);
ShowWindow(hWnd,SW_SHOW);