Как мне создать кнопку управления (с CreateWindow класса окна BUTTON), который имеет стандартный размер в масштабе всей системы (особенно высоту), совместимый с остальными приложениями Windows?
Я, конечно, должен учитывать DPI и, возможно, другие настройки.
Remark: Using
USE_CW_DEFAULTfor width and height results in a 0, 0 size button, so that's not a solution.





Вот что сообщает MSDN: Спецификации и рекомендации по проектированию - Визуальный дизайн: макет.
Размер кнопки по умолчанию - 50x14 DLU, который можно вычислить в пикселях, используя примеры, показанные для GetDialogBaseUnits.
Функция MapDialogRect, кажется, делает расчет за вас.
Чтобы создать кнопку стандартного размера, нам нужно сделать следующее:
LONG units = GetDialogBaseUnits();
m_hButton = CreateWindow(TEXT("BUTTON"), TEXT("Close"),
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
0, 0, MulDiv(LOWORD(units), 50, 4), MulDiv(HIWORD(units), 14, 8),
hwnd, NULL, hInst, NULL);
где 50 и 14 - соответствующие размеры DLU, 4 и 8 - горизонтальные и вертикальные блоки шаблона диалогового окна соответственно, на основе замечаний документации GetDialogBaseUnits() функция.
НО, как указал Андерс, эти показатели основаны на системном шрифте. Если в вашем окне используется шрифт диалогового окна оболочки или просто что-то, что не заставляет ваши глаза кровоточить, вы в значительной степени сами по себе.
Чтобы получить свои собственные базовые единицы «диалогового окна», вы должны получить текущие текстовые метрики с помощью GetTextMetrics() и использовать высоту символа и среднюю ширину (tmHeight и tmAveCharWidth структуры TEXTMETRIC соответственно) и самостоятельно перевести их с помощью MulDiv, пока не вы находитесь в диалог, то MapDialogRect() сделает всю работу за вас.
Обратите внимание, что tmAveCharWidth только приближает фактическую среднюю ширину символа, поэтому вместо этого рекомендуется использовать функцию GetTextExtentPoint32() для алфавитного набора символов.
Видеть:
Если кнопки - единственный элемент управления, размер которого вы хотите изменять автоматически, вы также можете использовать макрос сообщения BCM_GETIDEALSIZEButton_GetIdealSize() (только для Windows XP и более поздних версий), чтобы получить оптимальную ширину и высоту, которые подходят ко всему, что содержит кнопка, хотя это выглядит довольно уродливо без каких-либо полей вокруг текст кнопки.
В еще более совершенном мире макет графического интерфейса в 2009 году вообще не будет включать пиксельные координаты. :) Менеджеры динамической компоновки - лучшее решение в большинстве случаев, imo.
Бог с ним! :) Хотя даже в этом перегруженном пикселями мире Win32 у вас есть для этого несколько полезных функций, так что вам никогда не придется иметь дело с координатами пикселей явно.
да, BCM_GETIDEALSIZE дает вам стреляющие затемнения
Обе ссылки в средней части не работают. Получено с WayBack Machine: Первый: web.archive.org/web/20140608215304/http://support.microsoft. com /… Второй: web.archive.org/web/20131208002908/http://… (предлагается изменить)
@macbirdie: вы НЕ должны использовать GetDialogBaseUnits (), он основан на системном шрифте по умолчанию (Ugly bitmap font). Вы должны использовать MapDialogRect ()
Как я упоминал в предыдущем комментарии, MapDialogRect не работает для окон, не являющихся диалоговыми окнами, поэтому я думаю, мне нужно попробовать функции GetTextExtentPoint32 и GetTextMetrics, как было предложено.
MapDialogRect не поможет, если ваше окно, к сожалению, не является диалоговым, но вычисления вручную работают очень хорошо.