Масштабировать элементы еще проще, чем перемещать их. За образец мы снова возьмем соответствующий механизм режима конструирования Delphi. Чтобы изменить размер выделенного элемента, вы щелкаете на одном из черных квадратиков-маркеров, расположенных по краям элемента, и перетаскиваете его до тех пор, пока измененные размеры элемента вас не устроят.
Аналогичный способ будет использован и в нашем случае. Единственное отличие заключается в том, что для простоты (и для уменьшения объема кода) мы ограничимся лишь одним из восьми возможных маркеров.
Поскольку класс TSizingRect уже используется для перемещения элемента, он поможет нам и при масштабировании. Правый нижний угол TSizingRect назначается «активной областью», на которой пользователь будет щелкать для масштабирования элемента.
Кроме того, для упрощения дизайна мы обозначим «активную область» маленьким белым квадратиком и будем изменять вид курсора всякий раз, когда он проходит над ним. Вся настоящая работа выполняется в обработчике MouseMove, полностью приведенном в листинге12.3. Код обработчика подробно рассматривается в последующем тексте.
Листинг 12.3. Обработчик события MouseMove для объекта SizingRect
procedure TFrmMain.SizingRect1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin { ControlDC и ControlRect - глобальные переменные, используемые в нескольких процедурах. } ControlDC := GetDC(TWinControl(Sender).Handle); GetWindowRect(TWinControl(Sender).Handle, ControlRect); if ((X > TControl(Sender).Width -SizeVal) and (Y > TControl(Sender).Height -SizeVal)) then begin TWinControl(Sender).Cursor := crSizeNWSE; Rectangle(ControlDC, TWinControl(Sender).Width - SizeVal, TControl(Sender).Height -SizeVal, TControl(Sender).Width, TControl(Sender).Height); end else begin TWinControl(Sender).Cursor := crDefault; end; if ((TWinControl(Sender).Cursor = crSizeNWSE) and (ssLeft in Shift)) then begin TWinControl(Sender).Width := X; TWinControl(Sender).Height := Y; end; end;
После подготовки переменных обработчик проверяет, находится ли курсор в пределах области масштабирования. Константа SizeVal, определяющая размеры белого маркера, определена в модуле DynamicForm. Если курсор находится внутри области, обработчик изменяет его внешний вид и, конечно, рисует прямоугольник:
if ((X > TControl(Sender).Width -SizeVal) and (Y > TControl(Sender).Height -SizeVal)) then begin TWinControl(Sender).Cursor := crSizeNWSE; Rectangle(ControlDC, TWinControl(Sender).Width - SizeVal, TControl(Sender).Height -SizeVal, TControl(Sender).Width, TControl (Sender).Height); endЕсли курсор находится за пределами области масштабирования, мы просто восстанавливаем его вид по умолчанию:
else begin TWinControl(Sender).Cursor := crDefault; end;Наконец, мы проверяем, продолжает ли пользователь масштабировать элемент. Если используется курсор crSizeNWSE и нажата левая кнопка мыши, значит, масштабирование продолжается. В этом случае обработчик перемещает правый нижний угол элемента за курсором:
if ((TWinControl(Sender).Cursor = crSizeNWSE) and (ssLeft in Shift)) then begin TWinControl(Sender).Width := X; TWinControl(Sender).Height := Y; end; end;Пока кнопка мыши остается нажатой, а курсор находится над активной областью, угол элемента перемещается вслед за курсором.