Попробуйте нижеприведенные обработчики событий WMNCPaint и WMNCHitTest.
При этом форма должна иметь свойство BorderStyle равным Sizeable, так как код
использует область границ для создания 3D эффекта и предоставляет пользователю
возможность изменения размера формы.
Для запрещения изменения размеров формы вы должны включить обработчик события
WMNCHitTest, для обратного эффекта не включайте его в ваш код.
procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
var
DC: HDC;
Frame_H: Integer;
Frame_W: Integer;
Menu_H: Integer;
Caption_H: Integer;
Frame: TRect;
Extra: Integer;
Canvas: TCanvas;
begin{ Задаем значения некоторым параметрам окна }
Frame_W := GetSystemMetrics(SM_CXFRAME);
Frame_H := GetSystemMetrics(SM_CYFRAME);
if (Menu <> nil) then
Menu_H := GetSystemMetrics(SM_CYMENU)
else
Menu_H := -1;
Caption_H := GetSystemMetrics(SM_CYCAPTION);
GetWindowRect(Handle, Frame);
Frame.Right := Frame.Right - Frame.Left - 1;
Frame.Left := 0;
Frame.Bottom := Frame.Bottom - Frame.Top - 1;
Frame.Top := 0;
{ Позволяем нарисовать стандартные границы формы }inherited;
{ Перерисовываем область границ в 3-D стиле }
DC := GetWindowDC(Handle);
Canvas := TCanvas.Create;
trywith Canvas dobegin
Handle := DC;
{ Левая и верхняя граница }
Pen.Color := clBtnShadow;
PolyLine([Point(Frame.Left, Frame.Bottom), Point(Frame.Left, Frame.Top),
Point(Frame.Right, Frame.Top)]);
{ Правая и нижняя граница }
Pen.Color := clWindowFrame;
PolyLine([Point(Frame.Left, Frame.Bottom),
Point(Frame.Right, Frame.Bottom),
Point(Frame.Right, Frame.Top - 1)]);
{ Левая и правая граница, 1 пиксел скраю }
Pen.Color := clBtnHighlight;
PolyLine([Point(Frame.Left + 1, Frame.Bottom - 1),
Point(Frame.Left + 1, Frame.Top + 1),
Point(Frame.Right - 1, Frame.Top + 1)]);
{ Правая и нижняя граница, 1 пиксел скраю }
Pen.Color := clBtnFace;
PolyLine([Point(Frame.Left + 1, Frame.Bottom - 1),
Point(Frame.Right - 1, Frame.Bottom - 1),
Point(Frame.Right - 1, Frame.Top)]);
{ Разность области изменяемых границ }for Extra := 2 to (GetSystemMetrics(SM_CXFRAME) - 1) dobegin
Brush.Color := clBtnFace;
FrameRect(Rect(Extra, Extra, Frame.Right - Extra + 1, Frame.Bottom -
Extra + 1));
end;
{ Левая и верхняя граница области заголовка }
Pen.Color := clBtnShadow;
PolyLine([Point(Frame_W - 1, Frame_H + Caption_H + Menu_H - 1),
Point(Frame_W - 1, Frame_H - 1),
Point(Frame.Right - Frame_W + 1, Frame_H - 1)]);
{ Левая и верхняя граница области заголовка }
Pen.Color := clBtnHighlight;
PolyLine([Point(Frame_W - 1, Frame_H + Caption_H + Menu_H - 1),
Point(Frame.Right - Frame_W + 1, Frame_H + Caption_H + Menu_H - 1),
Point(Frame.Right - Frame_W + 1, Frame_H - 1)]);
end;
finally
Canvas.Free;
ReleaseDC(Handle, DC);
end; { try-finally }end;
procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
var
HitCode: LongInt;
begininherited;
HitCode := Msg.Result;
if ((HitCode = HTLEFT) or (HitCode = HTRIGHT) or
(HitCode = HTTOP) or (HitCode = HTBOTTOM) or
(HitCode = HTTOPLEFT) or (HitCode = HTBOTTOMLEFT) or
(HitCode = HTTOPRIGHT) or (HitCode = HTBOTTOMRIGHT)) thenbegin
HitCode := HTNOWHERE;
end;
Msg.Result := HitCode;
end;
Here's the translation of the provided text into Russian:
В этом коде создается форма с настраиваемым размером и стилем рамки, что можно достичь с помощью обработчиков WMNCPaint и WMNCHitTest.
Для улучшения этого кода:
Код должен включать обработку ошибок: Обработка ошибок помогает предотвратить неожиданное поведение или краш при операции, которая fails. Например, если возникает исключение во время операции рисования, это может привести к крашу приложения. Вы можете поймать исключения и обработать их в соответствии с вашим приложением.
Код мог быть сделан более эффективным: Обработчик WMNCPaint повторно вычисляет те же значения (например, Frame_Left, Frame_Right), что может замедлить процесс рисования. Лучше вычислить эти значения раз и хранить их в переменных перед использованием.
Читаемость кода могла быть улучшена: Код не очень читаемый потому, что нет комментариев, объясняющих, что каждый раздел кода делает. Добавление комментариев может сделать его более понятным для других разработчиков.
Вот измененный вариант предоставленного кода:
procedureTForm1.WMNCPaint(varMsg:TWMNCPaint);varDC:HDC;Frame_Left,Frame_Right,Frame_Top,Frame_Bottom:Integer;Menu_Height:Integer;Caption_Height:Integer;Canvas:TCanvas;begin// Установка параметров для окнаFrame_Left:=GetSystemMetrics(SM_CXFRAME);Frame_Right:=GetSystemMetrics(SM_CXFRAME);if(Menu<>nil)thenMenu_Height:=GetSystemMetrics(SM_CYMENU)elseMenu_Height:=-1;Caption_Height:=GetSystemMetrics(SM_CYCAPTION);// Получение прямоугольника окна и коррекция для рамкиGetWindowRect(Handle,Frame);Frame_Right:=Frame.Right-Frame_Left-1;Frame_Left:=0;Frame_Bottom:=Frame.Bottom-Frame_Top-1;Frame_Top:=0;// Позволяем Windows рисовать стандартные рамкиinherited;// Перерисовка рамки в стили 3DDC:=GetWindowDC(Handle);Canvas:=TCanvas.Create;trywithCanvasdobeginHandle:=DC;// Рисование левой и верхней границыPen.Color:=clBtnShadow;PolyLine([Point(Frame_Left,Frame_Bottom),Point(Frame_Left,Frame_Top),Point(Frame_Right,Frame_Top)]);// Рисование правой и нижней границыPen.Color:=clWindowFrame;PolyLine([Point(Frame_Left,Frame_Bottom),Point(Frame_Right,Frame_Bottom),Point(Frame_Right,Frame_Top-1)]);// Рисование левой и правой границ с эффектом подсветкиPen.Color:=clBtnHighlight;PolyLine([Point(Frame_Left+1,Frame_Bottom-1),Point(Frame_Left+1,Frame_Top+1),Point(Frame_Right-1,Frame_Top+1)]);// Рисование правой и нижней границ с эффектом лицаPen.Color:=clBtnFace;PolyLine([Point(Frame_Left+1,Frame_Bottom-1),Point(Frame_Right-1,Frame_Bottom-1),Point(Frame_Right-1,Frame_Top)]);// Вычисление дополнительного пространства для изменения рамкиforExtra:=2to(GetSystemMetrics(SM_CXFRAME)-1)dobeginBrush.Color:=clBtnFace;FrameRect(Rect(Extra,Extra,Frame_Right-Extra+1,Frame_Bottom-Extra+1));end;// Рисование левой и верхней границ caption-areasPen.Color:=clBtnShadow;PolyLine([Point(Frame_W-1,Frame_H+Caption_Height+Menu_Height-1),Point(Frame_W-1,Frame_H-1),Point(Frame_Right-Frame_W+1,Frame_H-1)]);// Рисование левой и верхней границ caption-areasPen.Color:=clBtnHighlight;PolyLine([Point(Frame_W-1,Frame_H+Caption_Height+Menu_Height-1),Point(Frame_Right-Frame_W+1,Frame_H+Caption_Height+Menu_Height-1),Point(Frame_Right-Frame_W+1,Frame_H-1)]);end;finallyCanvas.Free;ReleaseDC(Handle,DC);end;end;procedureTForm1.WMNCHitTest(varMsg:TWMNCHitTest);varHitCode:LongInt;begininherited;HitCode:=Msg.Result;if((HitCode=HTLEFT)or(HitCode=HTRIGHT)or(HitCode=HTTOP)or(HitCode=HTBOTTOM)or(HitCode=HTTOPLEFT)or(HitCode=HTBOTTOMLEFT)or(HitCode=HTTOPRIGHT)or(HitCode=HTBOTTOMRIGHT))thenbeginHitCode:=HTNOWHERE;end;Msg.Result:=HitCode;end;
В этом измененном коде я добавил комментарии, чтобы объяснить, что каждый раздел кода делает. Я также улучшил читаемость кода, используя более описательные имена переменных и форматирование кода в виде, который легче для чтения.
Трехмерные формы с изменяющимися размерами: при создании 3D-эффекта на границах формы используются обработчики событий WMNCPaint и WMNCHitTest.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.