FreeBasic
Главная
Вход
Регистрация
Понедельник, 30.12.2024, 18:54Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
как расчитать размеры элементов управления в Window9
electrikДата: Среда, 19.01.2022, 18:48 | Сообщение # 1
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Привет. Есть задача, рассчитать размеры элементов управления, кнопок, едитбоксов, и т п, при условии, что я буду использовать стандартный шрифт. Конечно, методом подбора я найду, но каждый раз для нового GUI уже подзадолбало. Предположим, я делаю кнопку "Hello world", она занимает 11 символов. сколько пикселей по оси X и Y занимает кнопка? так же сколько пикселей занимает стандартный символ в Window9 по оси X и Y? Как я понимаю, у кнопки ещё есть контуры, которые тоже надо учитывать. В пурике, я выработал примерную тактику, если кнопка 20 символов, 10 умножаем на 20. высоту я обычно ставлю 20. Мне супер подгонки не надо, главное чтобы элементы не наезжали друг на друга. Вот и хочу выработать методику, в которой точно не промахнусь.
 
WQДата: Среда, 19.01.2022, 20:46 | Сообщение # 2
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Цитата electrik ()
Привет. Есть задача, рассчитать размеры элементов управления, кнопок, едитбоксов

В Windows можно использовать конструкции вроде такой:


Код
#Define UNICODE
#Include "windows.bi"

Function StringSizeEx (ByVal sText As String, ByVal iSize As Double, ByVal iWeight As Integer, _
    ByVal iAttrib As Integer, ByVal sFontName As String, ByVal iQuality As Integer) As SIZE
    Static hDC As HDC
    Static hOldFont As HDC
    Static hFont As HFONT
    Static tSIZE As SIZE
    hDC = GetDC(0)
    hFont = CreateFont(-GetDeviceCaps(hDC, 90) * iSize / 72,0,0,0,iWeight,False,0,0,DEFAULT_CHARSET,0,0,0,0, WStr(sFontName))

    hOldFont = SelectObject(hDC, hFont)
    GetTextExtentPoint32(hDC,sText, Len(sText), @tSIZE)
    SelectObject(hDC, hOldFont)
    DeleteObject(hFont)
    ReleaseDC(0,hDC)
    Function =  tSIZE
End Function

Dim As SIZE temp1= StringSizeEx("Hello world", 12, 400, 0, "MS Sans Serif", 2)

? temp1.cy,  temp1.cx
Sleep
 

Код получает размеры строки в пикселях при указанном шрифте
Когда использовал Window9, использовал функции вроде такой, в некоторых случаях перебирал размер шрифта в цикле на уменьшение\увеличение

Потом перешел на IUP, там многие из этих параметров рассчитываются автоматически + есть специальные функции для расчетов длины, высоты текста, многострочного текста и т.д. (для winapi - по сути обертки для тех же функций, что в приведенном коде, для linux, наверное, что-то из GTK)
 
haavДата: Среда, 19.01.2022, 20:49 | Сообщение # 3
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
Контролы (button , edit и пр.) в window9 и в пурике одинаковы , потому что их основа такая же (под windows winapi , под linux gtk). И в пурике и в window9 используется шрифт по умолчанию , если сам не поменяешь. Так что , если у тебя нормально отображалось в пурике , то точно так же будет отображаться и window9. Для вычисления ширины букв и в винде и в линуксе есть средства. Я сейчас точно не могу сказать , но вроде под винду GetTextExtentPoint32 ,  а в linux рисуешь текст с помощью pango_layout_set_text и дальше вычисляешь с помощью pango_layout_get_pixel_extents. Но я обычно действую на глазок. Кстати под linux советую высоту кнопок делать не меньше 25 , я обычно ставлю 30.

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Четверг, 20.01.2022, 10:54 | Сообщение # 4
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
При стандартном масштабе кнопки должны быть в высоту 23 пикселя и в ширину 75 пикселей.
Если масштаб изменён, то необходимо пересчитать размеры.

Или 50 на 14 диалоговых единиц в шаблоне ресурсов. За что люблю диалоги из ресурсов — их не надо пересчитывать, менеджер диалогов автоматически увеличивает рамзеры.

Корпорация Микрософт разработала руководства по размерам и расположению элементов управления, кнопок, рамок, надписей, текстовых полей и прочего:
Command Buttons in Windows 7 - Win32 apps | Microsoft Docs
 
electrikДата: Четверг, 20.01.2022, 11:33 | Сообщение # 5
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Всем большое спасибо. А как это кнопка в ширину 75 пикселей, а если на ней текст длинный, к примеру: "Обзор средств редактирования".
 
zamabuvaraeuДата: Пятница, 21.01.2022, 12:33 | Сообщение # 6
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Тогда следует переработать интерфейс и текст кнопки.
Например, группу элементов, отвечающих за редактирование, поместить в рамку с заголовком «Средства редактирования». Текст кнопки сделать «Обзор». Если после нажатия на кнопку выскакивает какое‐нибудь диалоговое окно вроде выбора файла, то к тексту следует добавлять многоточие:
Код
╔═Средства редактирования═════════════════╗
║                    ║
║  ┌──────────────────────────────────┐   ║
║  │                ┌───────────────┐ │   ║
║  │ Список         │    Обзор…     │ │   ║
║  │ средств        └───────────────┘ │   ║
║  │                    │   ║
║  └──────────────────────────────────┘   ║
║                    ║
║  ┌──────────────┐    ┌──────────────┐   ║
║  │      ОК      │    │    Отмена    │   ║
║  └──────────────┘    └──────────────┘   ║
╚═════════════════════════════════════════╝
 
haavДата: Понедельник, 07.02.2022, 22:15 | Сообщение # 7
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
Блин , я уже успел набить шишек. Пробую получить системный шрифт для GUI , но нифига не выходит.

Если получать с помощью GetStockObject , то возвращается System 12. Судя по сообщениям с форумов , этот метод никогда не возвращал нормального имени и размера для системного шрифта.
Если получать с помощью SystemParametersInfo , то возвращается Segoe UI 9. Имя правильное , но размер неверный. Я точно знаю , что у меня Segoe UI 10

Еще блин хвалят винду с ее винапи. Вон в линуксе все точно со шрифтами.

Может кто просветит?


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
WQДата: Вторник, 08.02.2022, 00:41 | Сообщение # 8
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Цитата haav ()
Если получать с помощью SystemParametersInfo , то возвращается Segoe UI 9
В IUP используется SystemParametersInfo
 
haavДата: Вторник, 08.02.2022, 06:24 | Сообщение # 9
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
Цитата WQ ()
В IUP используется SystemParametersInfo


Так я бы тоже бы использовал , но понимаешь в чем дело. Я же вижу , что система для кнопок , лейбелов и пр. ставит по умолчанию Segoe UI 10. Вот и получается такая штука:
Возвращаем хендл системного шрифта с помощью GetStockObject. Используем этот хендл для расчетов - все хорошо. Но получить реальное имя и размер этого шрифта не можем.
Получаем имя и размер шрифта с помощью SystemParametersInfo , далее создаем шрифт на основе этих данных и в итоге получается маленький шрифт, отличающийся от того , что система ставит по умолчанию для элементов окна. Все надписи мелкие. Похоже лучше использовать вариант GetStockObject и плевать , что нельзя получить реальное имя и размер для системного шрифта.

Есть еще один косяк в винде (точнее в заголовках , которые содраны с GCC). Вот есть структура NONCLIENTMETRICS. Для систем vista и выше, ее размер должен учитывать поле iPaddedBorderWidth , а для более ранних систем этого поля не должно быть. В заголовках используется такое:

Код

  #if _WIN32_WINNT >= &h0600
  iPaddedBorderWidth as long
    #endif


Но проблема в том , что пока ты сам не установишь макрос _WIN32_WINNT нужным значением , он возвращает 0x501 (то есть windows xp). То есть программист заранее должен знать какая система и ставить соответствующее значение для макроса. Но блин как программист узнает это до компиляции? Получается , что при этой методе, для каждой системы программисту нужно компилировать отдельный EXE, либо придумывать какой-то костыль.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Вторник, 08.02.2022, 09:30 | Сообщение # 10
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Для систем вроде Икспи и 2003 корпорация Микрософт рекомендует использовать шрифт «MS Shell Dlg 2» размером 8.
Начиная с Висты корпорация перешла на «Segoe UI» размером 9.

Fonts - Win32 apps | Microsoft Docs

«MS Shell Dlg 2» — это ненастоящее имя шрифта, когда указан такой шрифт, система автоматически использует какую‐нибудь Тахому, Ариэль или что там указано в настройках панели управления.

Также в ресурсы следует включать манифест для поддержки высокого DPI, иначе система начнёт автоматически масштабировать текст, что приведёт к его замыливанию.

Если используют шаблоны диалога, то для диалога указываем флаг DS_SETFONT.
 
haavДата: Вторник, 08.02.2022, 10:01 | Сообщение # 11
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
@zamabuvaraeu

Ну и как это мне поможет? Да есть документация и гуглить я тоже умею , если что. Есть SystemParametersInfo , которая возвращает казалось бы то , что описано в документации. Но на деле , я же вижу , что у меня контролы по умолчанию имеют размер шрифта несколько больший, чем написано в доке и возвращает SystemParametersInfo.

Вот скрин:



Для верхней кнопки никаких шрифтов не устанавливается (шрифт по умолчанию)
Для нижней кнопки устанавливается шрифт , полученный с помощью SystemParametersInfo (Segoe UI 9). Как бы тоже по умолчанию , но что-то эти умолчания разные...
Прикрепления: 6868586.png (4.7 Kb)


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Вторник, 08.02.2022, 10:01 | Сообщение # 12
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline

Цитата
Но блин как программист узнает это до компиляции?
Это пример древнейшего варианта полиморфизма структур. У таких структур есть поле с названием вроде cbSize, которое показывает сколько байт занимает сама структура.
Каждая версия структуры имеет определённую длину, которую следует записывать в cbSize. Система знает какому размеру какая версия структуры соответствует.


Цитата
Но проблема в том , что пока ты сам не установишь макрос _WIN32_WINNT нужным значением , он возвращает 0x501 (то есть windows xp)
Здесь ничего удивительного. Уже в икспихе появились функции, которых не было в 2000 виндоуз, например, тот же выпуклый интерфейс, который в некоторых случаях был несовместим с интерфейсом 2000.
Мы не можем написать дуальный екзешник, который будет использовать новые функции и одинаково работать как на 2000 так и на икспи.
 
haavДата: Вторник, 08.02.2022, 10:13 | Сообщение # 13
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
Цитата zamabuvaraeu ()
Уже в икспихе появились функции, которых не было в 2000 виндоуз, например, тот же выпуклый интерфейс, который в некоторых случаях был несовместим с интерфейсом 2000.
Мы не можем написать дуальный екзешник, который будет использовать новые функции и одинаково работать как на 2000 так и на икспи.


Так никто про это речи не ведет. В самом начале , я описал:

Есть еще один косяк в винде (точнее в заголовках , которые содраны с GCC).

Теперь получается , что использовать этот заголовок (в части этой функции) бесполезно. Надо выдирать эту структуру , переименовывать или переопределять так , чтобы все поля указывались без макросов , а в cbSize записывать значение в зависимости например от того , что вернет GetVersion.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Вторник, 08.02.2022, 10:19 | Сообщение # 14
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline

Цитата
Как бы тоже по умолчанию , но что-то эти умолчания разные...
Да, по умолчанию на окне шрифт как будто из 98 виндоуз, его необходимо менять на современный, который подходит для икспихи или семёрки.

Добавлено (08.02.2022, 10:33)
---------------------------------------------


Цитата
а в cbSize записывать значение в зависимости например от того , что вернет GetVersion
Должно быть так:

foo.cbSize = SizeOf(название структуры)

Там в винапи вообще почти у всех структур разные названия в зависимости от определения дефиниции UNICODE, например, WNDCLASSEXA и WNDCLASSEXW, и это нормально работает.

Насчёт «точнее в заголовков , которые содраны с GCC» — они же не с потолка взялись, они в оригинальных виндовых заголовках так написаны, и нам нужно руками ставить макрос для совместимости с новой версией виндоуз.

Добавлено (08.02.2022, 10:36)
---------------------------------------------
Я так понимаю, что задача — написать дуальный екзешник, которая будет работать и на икспи и на семёрке одинаково, лишь проверяя версию системы?

Сообщение отредактировал zamabuvaraeu - Вторник, 08.02.2022, 10:22
 
haavДата: Вторник, 08.02.2022, 10:50 | Сообщение # 15
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Репутация: 50
Статус: Offline
Цитата zamabuvaraeu ()
Я так понимаю, что задача — написать дуальный екзешник, которая будет работать и на икспи и на семёрке одинаково, лишь проверяя версию системы?


Решение задачи я описал выше и все будет работать , надо лишь вытащить структуры для юникода и ascii , переписать их без макросов. А в cbSize записывать так:

Код
.cbSize = SizeOf(MY_REPLACE_NONCLIENTMETRICS)

if LOBYTE(LOWORD(GetVersion())) < 6 then

   .cbSize -= 4

endif


И все будет работать как минимум начиная с XP. Теперь вопрос: нахера засунули макрос , если различия для разных систем задаются числом в параметре cbSize?


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: