Правильный способ получения предпочтительного размера элементов управления Windows

Мне нужно определить предпочтительный размер - как ширину, так и высоту - элементов управления в Windows API. Насколько я могу судить, единственным официальным словом в этом вопросе является страница Layout Руководства для Windows Desktop Program, документ, казалось бы, представленный с Windows Vista и эквивалент документов Microsoft Management Console, на основе которых, по-видимому, основывается.

На предыдущей странице приведены размеры в обоих диалоговых окнах и пикселях (что-то не на последней странице!) якобы для 9-точечного интерфейса Segoe с разрешением 96 точек на дюйм. Я не знаю, были ли вычисления диалогового блока никогда не обновлялись для этого нового значения DPI или нет, но, несмотря на это, я пробовал три разных подхода, и ничего не складывалось точно.

Эта программа вычисляет двумя способами, как на основе информации здесь и здесь. Первый использует поле tmAveCharWidth структуры TEXTMETRICS; второй использует функцию GetTextExtentPoint32() в первом соединении. Затем он повторяет этот процесс, принимая во внимание древний шрифт системы (см. Первую ссылку).

Запуск этой программы в Windows 7 с помощью

  • BUTTON_SIZE_X хранится в 50 (указанная ширина нескольких вещей)
  • BUTTON_SIZE_Y изменено на 25 (указанная высота командной строки Vista и выше только с одной строкой текста)

чтобы наш ожидаемый размер, основанный на странице макета, был бы 75x41 уроками

GetTextExtentPoint32: Segoe UI 9 | baseX 7 baseY 15 | button 50 x 25 -> 88 x 47
tm.tmAveCharWidth:    Segoe UI 9 | baseX 6 baseY 15 | button 50 x 25 -> 75 x 47
with system font: System 9
GetTextExtentPoint32: Segoe UI 9 | cX 7 cY 15 sysX 8 sysY 16 | button 50 x 25 -> 87 x 46
tm.tmAveCharWidth:    Segoe UI 9 | cX 6 cY 15 sysX 7 sysY 16 | button 50 x 25 -> 85 x 46

Уже мы можем видеть четыре разных возможных преобразования из диалоговых единиц в пиксели.

Вторая программа просто создает фиктивный диалог и вызывает MapDialogRect(), чтобы получить координаты baseX и baseY в приведенном выше. Это дает

Segoe UI 9 weight:400 italic:0 charset:1
[0 0 8 16]

и если мы вручную выполним вычисления, сделанные первой программой:

width  - (50*8)/4 = 100
height - (25*16)/8 = 50

Мне интересно, использовали ли все вычисления (в том числе и для Command Links) Tahoma или MS Sans Serif, шрифты, используемые до Vista... но тогда я не знаю, какой правильный размер!

И это все еще оставляет элементы управления, такие как флажки и элементы управления статическим текстом (и ссылки на команды!), которые не имеют указанной формулы ширины или ширины. Конечно, для статических текстовых элементов я мог просто получить ширину текста и сказать, что предпочтительная ширина, но это не учитывает любые возможные горизонтальные дополнения, предоставляемые элементом управления. И это не отвечает за флажками, где есть дополнительная ширина для части флажка. (Я нашел способы найти эти координаты, особенно в Stack Overflow, но все они имеют свои недостатки). Даже MMC-документы, о которых я упоминал в начале этого вопроса, говорят много (или, что еще хуже, чтобы сделать все как можно шире, если это подходит для диалогового окна, это полностью работает, когда я пытаюсь выяснить, насколько сделайте диалоговое окно в первую очередь!).

Что еще, когда Microsoft создала библиотеку Common Controls версии 6, они решили включить сообщения для определения правильного размера элементов управления!... только некоторые элементы управления:

  • BCM_GETIDEALSIZE - кнопки; перечисленные как неэффективные для других типов кнопок.
  • DTM_GETIDEALSIZE - выбор даты/времени
  • LM_GETIDEALSIZE - гиперссылки; возвращает высоту только для заданной ширины
  • RBBIM_IDEALSIZE - элементы управления ReBar; на самом деле не сообщение, а что-то еще
  • TB_GETIDEALSIZE - панели инструментов

Как насчет сравнения с элементами управления в Windows? Что-то уже выглядит корректно в Windows XP, но диалоги Winodws 7 и другие элементы управления удивительно непоследовательны (некоторые до сих пор используют Tahoma или даже MS Sans Serif в качестве диалогового шрифта!), И я никогда не могу быть уверен, какой размер кнопки прав.

Так что я хочу знать, это любая комбинация:

  • какой из пяти методов расчета действительно прав, если примеры на странице макетов нет?
  • есть/была ли более авторитетная ссылка на размер элемента управления (и в идеале также на шагание), чем на неполных макетах и ​​макетах MMC?
  • была ли такая ссылка, которая предшествовала Vista, которая также могла бы предоставить ключи?
  • или все это просто безнадежно, и я должен выбрать что-то, что хтат просто выглядит неправильно для меня, несмотря ни на что?

Ответ 1

Только некоторые подсказки:

1. Чтобы получить предпочтительный размер управления окнами:

Если визуальный стиль включен, используйте GetThemePartSize, в противном случае вам нужно разработать свою программу для расчета предпочтительного размера. Обратитесь к исходному коду Firefox .

2. Как настроить элементы управления:

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

  • Необходимо измерить размер элемента управления на основе текущего размера окна и его собственных параметров макета (фиксированный/заполняющий-родительский/warp-контент). Для текстовой кнопки необходимо измерить размер текста.
  • Если сумма всех размеров детей переполняет размер окна, необходимо выполнить некоторую координацию.
  • Наконец, установите правильный размер и положение для элемента управления.

Существует множество различных требований к макету для приложения, поэтому у android есть много менеджеров компоновки, таких как LinearLayout, GridLayout и т.д. Так же и для системы компоновки UI для Windows и всех других систем компоновки пользовательского интерфейса.

Вам нужно написать много кода, сделайте это правильно. Пожалуйста, обратитесь к исходному коду системы chrome/firefox UI.

3. Решение:

Я думаю, вам лучше использовать какую-то существующую систему пользовательского интерфейса, такую ​​как QT/Vxwidgets, чтобы сделать макет управления Windows.