Защита приложений от крупных шрифтов
Вы когда-нибудь проверяли как будет выглядеть
написанная вами с такой любовью программа с системе с крупными
шрифтами? Согласитесь, это неприглядное зрелище. Наползающие
друг на друга метки и поля редактирования, надписи, которые
заканчиваются где то за пределами формы и т.п. После этого
появляется неконтролируемая неприязнь к пользователям, которые
предпочитают режим крупных шрифтов. Но это их право. И ваша
проблема.
Вы наверняка задавались вопросом о том, как
избежать искажений. И находили в сети одни и те же рецепты:
использовать шрифты 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). Тогда не надо лишать их этой возможности.