Автор: greenpc
Дата сообщения: 19.03.2007 12:03
HOUPE
Пробуй. Источник _www.interface.ru
[more]
Масштабирование формы при изменении размера системного шрифта. При переносе приложения с одного компьютера на другой часто происходят нежелательные искажения форм: часть заголовков контролей перестают быть видимыми или контроли начинают перекрываться друг с другом и.т.д. Это происходит при изменении размера системного шрифта и приложение пытается изменить размеры и позиции контролей с тем, чтобы в том же масштабе разместить на них заголовки. В доступных мне приложениях, помимо того что в некоторых приложениях происходят безобразные искажения, я наблюдал три способа решения этой проблемы:
1. Приложение устанавливает новый системный шрифт. От таких я немедленно избавляюсь, так как непонятно что будет когда аналогичное, но другое приложение, захочет изменить системный шрифт для себя…
2. Приложение не изменяет позиций и размеров контролей при изменении величины системного шрифта, но размеры контролей достаточно большие, чтобы разместить на них надписи при больших размерах системного шрифта. Формы в таких приложениях часто производят плохое впечатление при малых размерах системного шрифта. Кроме того, если пользователь установит системный шрифт больше, чем стандартный «Large Font» Windows большого графического разрешения, то надписи часто не помещаются на контролях…
3. Наконец в ряде приложений величина и размеры контролей меняются пропорционально размеру системного шрифта. Это, на мой взгляд, наиболее корректный способ масштабирования и ниже пойдет об этом способе масштабирования.
Форма имеет два свойства, которые регулируют масштабирование: Scaled и PixelsPerInch. Если установить свойство Scaled в False, то форма не будет масштабироваться при изменении системного шрифта. Если при этом заранее сделать контроли большими, то получится тот самый результат, что и в п. 2 выше. Поэтому значение свойства Scaled должно быть True.
Свойство PixelsPerInch непонятно зачем выведено в Инспектор Объектов. Перед показом формы PixelsPerInch пересчитывается в соответствии с реальным размером системного шрифта и выставленное в Инспекторе Объектов значение затирается. Но именно пересчитанное значение важно анализировать для корректного масштабирования формы.
Если форма имеет толстые границы (ее размер в этом случае может изменяться пользователем во время выполнения приложения) или если форме разрешено иметь каретки для скроллирования, то размер клиентной области формы останется таким же, как и был на этапе разработки. При этом часть контролей уйдет за пределы клиентной области и пользователь вынужден будет пользоваться каретками для прокрутки формы или же менять границы при ее показе что приводит к лишним операциям.
Поэтому перед показом форм иногда необходимо писать код для пересчета ширины и высоты. Я это делаю в обработчике события OnShow. Использование OnShow гарантирует, что все ресурсы (в том числе и размеры контролей) уже загружены.
procedure TDialogForm.FormShow(Sender: TObject);
var
I,XMax,YMax:integer;
PT:TPoint;
begin
if not FFirstRun then Exit;
{Resizing of form}
if (Screen.PixelsPerInch<>96) and (ComponentCount>0) then begin
XMax:=0;
YMax:=0;
for I:=0 to ComponentCount-1 do if Components[I] is TControl then with Components[I] as TControl do begin
PT:=Self.ScreenToClient(ClientToScreen(Point(Width,Height)));
if PT.X>XMax then XMax:=PT.X;
if PT.Y>YMax then YMax:=PT.Y;
end;
XMax:=XMax+2*GetSystemMetrics(SM_CXDLGFRAME)+4;
YMax:=YMax+2*GetSystemMetrics(SM_CYDLGFRAME) +GetSystemMetrics(SM_CYCAPTION) +4;
Width:=XMax;
Height:=YMax;
end;
FFirstRun:=False;
end;
Этот код можно использовать в большинстве форм. Исключение – использование компонента TScrollBox – его детей не надо учитывать для определения размеров формы. Классовая переменная FFirstRun используется для однократного запуска данного кода.
Если контроли создаются динамически, то есть во время выполнения, а не на этапе разработки, то при установки границ контролей нельзя пользоваться абсолютными координатами – только относительными! Например, если контроль MyControl должен располагаться под кнопкой BitOK, иметь такую же ширину, а по высоте на 4 пиксела не доходить до края формы, то следует писать код: MyControl.SetBounds(BitOK.Left, BitOK.Top+BitOK.Height+4, BitOK.Width, ClientWidth-BitOK.Top-BitOK.Height-8); но не следует писать, например, так: MyControl.SetBounds(10,60,70,180);
Все сказанное выше о масштабировании работает только при совпадении шрифтов формы и установленных на ней контролях. Поэтому не рекомендуется определять отдельные шрифты для контролей. Если же это необходимо, то размеры таких контролей должны быть пересчитаны в явном виде перед показом формы. При этом для расчета масштабного коэффициента нельзя пользоваться свойством Height (или Size) шрифта! Необходимо вызвать Win API функцию GetTextMetrics и использовать поле tmHeight структуры TTextMetric.
Для создания полноценного интерфейса необходимо также корректно использовать меню и панели инструментов, создать систему помощи и подсказок, использовать информацию о версии.
[/more]