Чтение онлайн

на главную - закладки

Жанры

Шрифт:

Как же достигнут подобный эффект? Очень даже просто. Ведь вы уже знаете, что элементы управления рисуются внутри своих собственных окон (дочерних по отношению к окну формы). Окна элементов отличает отсутствие в их стиле флагов (по – дробнее в гл. 2), позволяющих отображать рамку, изменять размер окна элемента управления. Это легко исправить, самостоятельно задав нужные флаги в стиле окна при помощи API-функции SetWindowLong. Для удобства можно написать отдельную процедуру, которая будет дополнять стиль окна флагами, необходимыми для перемещения и изменения размера (как, собственно, и сделано в примере) (лис – тинг 1.22).

...

Листинг 1.22.

Разрешение перемещения и изменения размера

procedure MakeMovable(Handle: HWND);

var

style: LongInt;

flags: UINT;

begin

//Разрешаем перемещение элемента управления

style := GetWindowLong(Handle, GWL_STYLE);

style := style or WS_OVERLAPPED or WS_THICKFRAME or WS_CAPTION;

SetWindowLong(Handle, GWL_STYLE, style);

style := GetWindowLong(Handle, GWL_EXSTYLE);

style := style or WS_EX_TOOLWINDOW;

SetWindowLong(Handle, GWL_EXSTYLE, style);

//Перерисуем в новом состоянии

flags := SWP_NOMOVE or SWP_NOSIZE or SWP_DRAWFRAME or

SWP_NOZORDER;

SetWindowPos(Handle, 0, 0, 0, 0, 0, flags);

end;

Как можно увидеть, задание дополнительных флагов происходит в два этапа. Сначала считывается старое значение стиля окна. Потом при помощи двоичной операции ИЛИ стиль (а это целочисленное значение) дополняется новыми флагами. Это делается для того, чтобы не пропали ранее установленные значения стиля окна.

Вообще, процедура MakeMovable изменяет два стиля окна: обычный и расширенный. Расширенный стиль окна изменяется лишь для того, чтобы строка заголовка получившегося окна занимала меньше места (получаем так называемое окно панели инструментов). Полный перечень как обычных, так и расширенных стилей можно посмотреть в приложении 2.

Логично также реализовать процедуру, обратную MakeMovable, запрещающую перемещение окон элементов управления (листинг 1.23).

...

Листинг 1.23.

Запрещение перемещения и изменения размера

procedure MakeUnmovable(Handle: HWND);

var

style: LongInt;

flags: UINT;

begin

//Запрещаем перемещение элемента управления

style := GetWindowLong(Handle, GWL_STYLE);

style := style and not WS_OVERLAPPED and not WS_THICKFRAME

and not WS_CAPTION;

SetWindowLong(Handle, GWL_STYLE, style);

style := GetWindowLong(Handle, GWL_EXSTYLE);

style := style and not WS_EX_TOOLWINDOW;

SetWindowLong(Handle, GWL_EXSTYLE, style);

//Перерисуем в новом состоянии

flags := SWP_NOMOVE or SWP_NOSIZE or SWP_DRAWFRAME or

SWP_NOZORDER;

SetWindowPos(Handle, 0, 0, 0, 0, 0, flags);

end;

Осталось только реализовать вызовы процедур MakeMovable и MakeUnmovable в нужном месте программы. В нашем примере вызовы заключены внутри обработчика изменения состояния флажка на форме (листинг 1.24).

...

Листинг 1.24.

Управление перемещаемостью элементов управления

procedure TfrmMovingControls.chkSetMovableClick(Sender: TObject);

begin

if chkSetMovable.Checked then

begin

//Разрешаем перемещение элементов управления

MakeMovable(Memo1.Handle);

MakeMovable(ListBox1.Handle);

MakeMovable(Button1.Handle);

end

else

begin

//Запрещаем перемещение элементов управления

MakeUnmovable(Memo1.Handle);

MakeUnmovable(ListBox1.Handle);

MakeUnmovable(Button1.Handle);

end;

end;

1.6. Масштабирование окон

Возможность масштабирования окон (форм) является интересным приемом, который может быть заложен в дизайн приложения.

При этом имеется в виду масштабирование в буквальном смысле этого слова: как пропорциональное изменение размера элементов управления формы, так и изменение размера шрифта.

Использовать масштабирование при работе с Delphi крайне просто, ведь в класс TWinControl, от которого наследуются классы форм, встроены методы масштабирования. Вот некоторые из них:

• ScaleControls – пропорциональное изменение размера элементов управления на форме;

• ChangeScale – пропорциональное изменение размера элементов управления с изменением шрифта, которым выводится текст в них.

Оба приведенных метода принимают два целочисленных параметра: числитель и знаменатель нового масштаба формы. Пример задания параметров для методов масштабирования приводится в листинге 1.25.

...

Листинг 1.25.

Масштабирование формы с изменением шрифта

procedure TfrmScaleBy.cmbSmallerClick(Sender: TObject);

begin

ChangeScale(80, 100); //Уменьшение на 20 % (новый масштаб – 80 %)

end;

procedure TfrmScaleBy.cmbBiggerClick(Sender: TObject);

begin

ChangeScale(120, 100); //Увеличение на 20 % (новый масштаб – 120 %)

end;

Чтобы размер шрифта правильно устанавливался, для элементов управления нужно использовать шрифты семейства TrueType (в нашем примере это шрифт Times New Roman).

На рис. 1.16 приводится внешний вид формы до изменения масштаба.

Рис. 1.16. Форма в оригинальном масштабе

Внешний вид формы после уменьшения масштаба в 1,25 раза (новый масштаб составляет 80 % от первоначального) демонстрируется на рис. 1.17.

Рис. 1.17. Форма в масштабе 80 %

То, что форма не изменяет своего размера при масштабировании, можно легко исправить, установив, например, свойство AutoSize в True при помощи редактора свойств объектов (Object Inspector).

Если по каким-либо причинам использование свойства AutoSize вас не устраивает, то можно рассчитать новый размер формы самостоятельно. Только пересчитывать нужно размер не всего окна, а его клиентской области, ведь строка заголовка при масштабировании остается без изменений. Расчет размера окна можно выполнить так:

1. Получить прямоугольник клиентской области окна (GetClientRect).

2. Посчитать новый размер клиентской области.

3. Рассчитать разницу между новой и первоначальной шириной, новой и первоначальной высотой клиентской области; сложить полученные значения с первоначальными размерами самой формы.

Пример расчета приводится ниже (для увеличения размера клиентской области в 1,2 раза):

...

GetClientRect(Handle, rc);

newWidth := (rc.Right – rc.Left) * 120 div 100;

newHeight := (rc.Bottom – rc.Top) * 120 div 100;

Width := Width + newWidth – (rc.Right – rc.Left);

Height := Height + newHeight – (rc.Bottom – rc.Top);

...

Примечание

Чтобы после уменьшения или увеличения масштаба формы можно было вернуться в точности к первоначальному масштабу (при помощи соответствующей обратной операции), нужно для уменьшения или увеличения использовать коэффициенты, произведение которых равно 1. Например, при уменьшении масштаба на 20 % (в 0,8 раза) его нужно увеличивать при обратной операции на 25 % (в 1/0,8 = 1,25 раза).

Поделиться:
Популярные книги

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Последний Паладин. Том 7

Саваровский Роман
7. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 7

Курс 1. Декабрь

Фокс Гарри
4. Маркатис
Фантастика:
аниме
фэнтези
сказочная фантастика
5.00
рейтинг книги
Курс 1. Декабрь

Предопределение

Осадчук Алексей Витальевич
9. Последняя жизнь
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Предопределение

Эпоха Опустошителя. Том X

Павлов Вел
10. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Эпоха Опустошителя. Том X

Казачий князь

Трофимов Ерофей
5. Шатун
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Казачий князь

Железный Воин Империи VII

Зот Бакалавр
7. Железный Воин Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Железный Воин Империи VII

Кодекс Охотника. Книга XXXVI

Винокуров Юрий
36. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVI

Кодекс Императора III

Сапфир Олег
3. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора III

Семь Нагибов на версту

Машуков Тимур
1. Семь, загибов на версту
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Семь Нагибов на версту

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8