Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Трехмерные формы с изменяющимися размерами

Delphi , Программа и Интерфейс , Размеры и Положение

Трехмерные формы с изменяющимися размерами

Попробуйте нижеприведенные обработчики событий 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;
  try
    with Canvas do
    begin
      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) do
      begin
        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;
begin
  inherited;
  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)) then
  begin
    HitCode := HTNOWHERE;
  end;
  Msg.Result := HitCode;
end;

Here's the translation of the provided text into Russian:

В этом коде создается форма с настраиваемым размером и стилем рамки, что можно достичь с помощью обработчиков WMNCPaint и WMNCHitTest.

Для улучшения этого кода:

  1. Код должен включать обработку ошибок: Обработка ошибок помогает предотвратить неожиданное поведение или краш при операции, которая fails. Например, если возникает исключение во время операции рисования, это может привести к крашу приложения. Вы можете поймать исключения и обработать их в соответствии с вашим приложением.

  2. Код мог быть сделан более эффективным: Обработчик WMNCPaint повторно вычисляет те же значения (например, Frame_Left, Frame_Right), что может замедлить процесс рисования. Лучше вычислить эти значения раз и хранить их в переменных перед использованием.

  3. Читаемость кода могла быть улучшена: Код не очень читаемый потому, что нет комментариев, объясняющих, что каждый раздел кода делает. Добавление комментариев может сделать его более понятным для других разработчиков.

Вот измененный вариант предоставленного кода:

procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
var
  DC: 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) then
    Menu_Height := GetSystemMetrics(SM_CYMENU)
  else
    Menu_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;

  // Перерисовка рамки в стили 3D
  DC := GetWindowDC(Handle);
  Canvas := TCanvas.Create;
  try
    with Canvas do
    begin
      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)]);

      // Рисование левой и правой границ с эффектом подсветки
      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)]);

      // Вычисление дополнительного пространства для изменения рамки
      for Extra := 2 to (GetSystemMetrics(SM_CXFRAME) - 1) do
      begin
        Brush.Color := clBtnFace;
        FrameRect(Rect(Extra, Extra, Frame_Right - Extra + 1, Frame_Bottom - Extra + 1));
      end;

      // Рисование левой и верхней границ caption-areas
      Pen.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-areas
      Pen.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;
  finally
    Canvas.Free;
    ReleaseDC(Handle, DC);
  end;
end;

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
var
  HitCode: LongInt;
begin
  inherited;
  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)) then
  begin
    HitCode := HTNOWHERE;
  end;
  Msg.Result := HitCode;
end;

В этом измененном коде я добавил комментарии, чтобы объяснить, что каждый раздел кода делает. Я также улучшил читаемость кода, используя более описательные имена переменных и форматирование кода в виде, который легче для чтения.

Трехмерные формы с изменяющимися размерами: при создании 3D-эффекта на границах формы используются обработчики событий WMNCPaint и WMNCHitTest.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Размеры и Положение ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-28 06:33:18/0.0039958953857422/0