-
При различных DPI возникают проблемы с размерами отображаемых компонентов, например
http://pda.delphimaster.net/?id=1194860002&n=18
Итак, как же проследить изменение DPI, автоматически (!) подготовить форму и компоненты к отображению на экране (с учётом DPI!), а также учесть границу (рамку, бордюр) окна, чтобы не возникло проблем? -
Игорь Шевченко © (04.12.07 15:08) [1]Scaled:=true ?
-
Reindeer Moss Eater © (04.12.07 15:10) [2]DPI известно. DPI бывшее при дизайне известно.
Остается делить/умножать и менять размеры фонта у формы что бы она всегда выглядела одинаково красиво. -
DPI Получаеться только с помощью линейки. Разрешение монитора можно получить через GetDeviceCaps. Клиентскую облать формы сооветсвенно ClientWidth/ClientHeight.
-
Игорь Шевченко © (04.12.07 15:39) [4]
> DPI Получаеться только с помощью линейки
DPU получается с помощью свойства PixelsPerInch, или я здорово ошибаюсь ? -
KSergey © (04.12.07 16:02) [5]> Игорь Шевченко © (04.12.07 15:39) [4]
> DPU получается с помощью свойства PixelsPerInch, или я здорово ошибаюсь ?
Позволю себе крамольную мысль - да.
Однако автора конечно же вполне оно устроит, т.к. если у пользователя пиксель на стере отображается два на два миллиметра - то это его проблемы :) -
KSergey © (04.12.07 16:03) [6]> KSergey © (04.12.07 16:02) [5]
> пиксель на стере
> пиксель на стене -
Получить-то DPI я получил, а как асвтоматически подогнать размер всех компонентов? И формы? И гланое, рамки окна? Вручную прописывать для каждого компонта - идиотизм, по-моему.
-
Reindeer Moss Eater © (04.12.07 16:48) [8]наследование и полиморфизм не отменяли
-
и от чего мне всё это наследовать?
-
Reindeer Moss Eater © (04.12.07 17:18) [10]От одной формы конечно. В которой все и реализовать.
-
Делаешь себе ветку VCL начиная с Tcontrol добавляя событие OnChangeDPI и например ScaledTop/Width/height. По ним и ресайзишь.
-
> Делаешь себе ветку VCL начиная с Tcontrol добавляя событие
> OnChangeDPI и например ScaledTop/Width/height. По ним и
> ресайзишь.
оригинально, но долго.
Нельзя ли побыстрее и ... попроще? Неужели нет ничего готового? Или никому это никогда не было нужно? -
Игорь Шевченко © (05.12.07 17:10) [13]
> Неужели нет ничего готового?
Было. В Globus VCL -
> Было. В Globus VCL
название не подскажете (наглею :-)))))) )? -
Защита приложений от крупных шрифтов.
Вы когда-нибудь проверяли как будет выглядеть написанная вами с такой любовью программа с системе с крупными шрифтами? Согласитесь, это неприглядное зрелище. Наползающие друг на друга метки и поля редактирования, надписи, которые заканчиваются где то за пределами формы и т.п. После этого появляется неконтролируемая неприязнь к пользователям, которые предпочитают режим крупных шрифтов. Но это их право. И ваша проблема.
Вы наверняка задавались вопросом о том, как избежать искажений. И находили в сети одни и те же рецепты: использовать шрифты TrueType и отключать свойство Scaled у форм. Рецепт, предлагающий использовать только шрифты TrueType + Scaled = False для форм - верен. Однако тут есть некоторые неудобства.
Дело в том, что ни один из стандартных TrueType шрифтов не сравнится по качеству отображения с MS Sans Serif, который по умолчанию используется в вашем приложении. Самый близкий - Arial все же имеет довольно заметные отличия и проигрывает MS Sans Serif по читаемости.
Искажений форм так же полностью избежать не удастся. Особенно это может повлиять на компоновку сложных форм, а также при использовании в интерфейсе изображений и прочих немасштабируемых элементов. Иногда хочется просто запретить масштабирование и защитить программу от влияния крупных шрифтов. Но использовать MS Sans Serif в этом случае нельзя, так как в режиме крупных шрифтов система "сдвигает" их на 2 пункта вверх и шрифт 8pt MS Sans Serif выглядит как 10pt MS Sans Serif при мелких шрифтах.
для справки
В режиме стандартных размеров шрифтов в качестве системного используется, в основном, MS Sans Serif - рубленый шрифт без засечек. Он имеет размеры 8pt, 10pt, 12pt, 14pt, 18pt и 24pt. В основном используется размер 8pt. В режиме крупных шрифтов система увеличивает все шрифты на 120%. ( С 96 pixels per inch до 120 pixels per inch). Шрифт MS Sans Serif имеет всего 6 размеров. Поэтому 8pt становится 10pt, 10pt - 12pt и т.д. Шрифт 8pt MS Sans Serif выглядит как 10pt MS Sans Serif при мелких шрифтах. Шрифты же TrueType могут имеют произвольные размеры и шаг изменения равен 1pt. Поэтому при крупных шрифтах размеры TrueType и не-TrueType шрифтов изменяются по разному.
Предлагаемое решение способно защитить программу от влияния режима крупных шрифтов и не отказываться от шрифта MS Sans Serif при разработке программы. Подход состоит в том, чтобы заменять все шрифты MS Sans Serif на Arial при запуске программы при крупных шрифтах. Создавать программу, естественно, следует при мелких шрифтах.
Можно написать невизуальный компонент и добавить его на каждую форму. Компонент при загрузке проверяет режим и при обнаружении режима "Big Fonts" "обходит" все визуальные компоненты для замены шрифта. Также компонент заботится о том, чтобы свойство Scaled у форм было отключено.unit glSmallFontsDefence;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TglSmallFontsDefence = class(TComponent)
private
procedure UpdateFonts(Control: TWinControl);
{ Private declarations }
protected
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
end;
procedure Register;
implementation
function IsSmallFonts: boolean;{Значение функции TRUE если мелкий шрифт}
var DC: HDC;
begin
DC:=GetDC(0);
Result:=(GetDeviceCaps(DC, LOGPIXELSX) = 96);
{ В случае крупного шрифта будет 120}
ReleaseDC(0, DC);
end;
procedure Register;
begin
RegisterComponents('Gl Components', [TglSmallFontsDefence]);
end;
{ TglSmallFontsDefence }
constructor TglSmallFontsDefence.Create(AOwner: TComponent);
begin
inherited;
if (Owner is TForm) then (Owner as TForm).Scaled := false;
end;
procedure TglSmallFontsDefence.Loaded;
begin
inherited;
if (Owner is TForm) then (Owner as TForm).Scaled := false;
if csDesigning in ComponentState then
begin
if not IsSmallFonts then
ShowMessage('Проектирование приложения в режиме крупных' +
' шрифтов недопустимо!'#13#10+
'Компонент TglSmallFontsDefence отказывается' +
' работать в таких условиях.');
end else
UpdateFonts((Owner as TForm));
end;
procedure TglSmallFontsDefence.UpdateFonts(Control: TWinControl);
var
i: integer;
procedure UpdateFont(Font: TFont);
begin
if CompareText(Font.Name, 'MS Sans Serif') <> 0 then exit;
Font.Name := 'Arial';
end;
begin
if IsSmallFonts then exit;
UpdateFont(TShowFont(Control).Font);
with Control do
for i:=0 to ControlCount-1 do
begin
UpdateFont(TShowFont(Controls[i]).Font);
if Controls[i] is TWinControl then UpdateFonts(Controls[i] as TWinControl);
end;
end;
end.
Вы можете добавить свойство Options типа перечисления, в котором задать опции исключения некоторых классов компонентов. К примеру, можно добавить возможность отключать замену шрифтов для потомков TCustomGrid. Очень часто пользователи используют режим крупных шрифтов, чтобы улучшить читаемость таблиц данных (TDBGrid). Тогда не надо лишать их этой возможности.
составление статьи: Андрей Чудин, ЦПР ТД Библио-Глобус.
Перейти: Список всех статей
Сохранение коллекций | RTTI
HotLog -
Альф (06.12.07 14:09) [16]Относясь трогательно к Globus lib, но должен признать - этот способ один из самых дурацких.
Не IncDay конечно но близко к этому... -
TIF © (06.12.07 14:38) [17]А поумнее ничего нет?
Тут ведь только половина проблемы решается: шрифты. А размер компонентов? А граница окна? -
Игорь Шевченко © (06.12.07 15:46) [18]TIF © (06.12.07 14:38) [17]
А самому поискать мозгов не хватает ? -
я ничего путного найти не смог. всё что пробовал - не идёт, там только scalrd меняет и всё.
-
Альф (07.12.07 12:46) [20]Не смог найти - попробуй подумать...
Как будешь думать - учти еще что DPI може быть по вертикали и горизонтали разными :) -
> учти еще что DPI може быть по вертикали и горизонтали разными
> :)
ё-моё, Вы меня убили 8-0 -
Anatoly Podgoretsky © (07.12.07 14:51) [22]> TIF (07.12.2007 14:38:21) [21]
Есть такое понятие как соотношение сторон экрана 3x4, 4x5, 16x9, 16x10 - на любом из этих соотношений я могу включить одно и тоже разрешение, например 600Х800
Дальше ты сам можешь постчитать -
Уже легче стало :-)
А всё-таки, что делать с границей окна? -
istok (07.12.07 16:32) [24]а что делать с anchors контролов, которые при нестандартных dpi улетают?
например, смещаются вверх на 50 пикселей...ужас... не юзать их, а юзить align=alclient? -
> а что делать с anchors контролов, которые при нестандартных
> dpi улетают?
> например, смещаются вверх на 50 пикселей...ужас... не юзать
> их, а юзить align=alclient?
это вопрос, ответ или мнение? :-) -
TIF © (15.12.07 12:55) [26]Удалено модератором
Примечание: Создание пустых сообщений -
Подскажите, что делать с границей окна? С остальным вроде получается, а граница глючит :-(
-
> а граница глючит
Это как? У тебя теперь уже и граница заглючила? -
если в висте сделал один стиль окна (передал параметры) и всё нормально, то когда делаю стиль "классический" или запускаю прогу в ХР, на форме начинают оставаться следы от правой границы окна и изменении размера. Что такое?
-
> У тебя теперь уже и граница заглючила?
Суть бага такова: если приложение проектируется и компилируется в XP а запускается в висте, то в ряде случаев появляется смещение компонентов. И наоборот, если делали в висте а запускали в xp тоже. -
TIF © (28.12.07 11:40) [31]
> Суть бага такова: если приложение проектируется и компилируется
> в XP а запускается в висте, то в ряде случаев появляется
> смещение компонентов. И наоборот, если делали в висте а
> запускали в xp тоже.
что ты тупишь? в корне тупишь! Суть в том, что ЕСЛИ ПРИЛОЖЕНИЕ РАЗРАБАТЫВАЕТСЯ ПРИ РАЗЛИЧНЫХ DPI, то могут возникнуть проблемы с подложением и размерами компонентов. Вот и всё. Хоть 98 поставь, хоть 2000 - дело не в ОС. -
> TIF © (28.12.07 11:40) [31]
Я почему то подумал, что у тебя проблемы в висте. Там и при одинаковом DPI смещение наблюдается. Как раз из-за изменившегося бордюра окна. -
> и при одинаковом DPI смещение наблюдается
виноват, не видел, не проверял...