【问题标题】:How to hide borders created by WS_SIZEBOX using Delphi?如何使用 Delphi 隐藏 WS_SIZEBOX 创建的边框?
【发布时间】:2018-10-31 08:54:24
【问题描述】:

我创建具有运行时调整大小功能的自定义面板 (TMyPanel)。有什么方法可以隐藏边框而不丢失调整大小的功能?

type
  TMyPanel = class(TPanel)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

...

procedure TMyPanel.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or WS_SIZEBOX;
end;

...

var
  MyPanel1: TMyPanel;
begin
  MyPanel1:=TMyPanel.Create(self);
  MyPanel1.Parent:=self;
  ...
end;

【问题讨论】:

  • 那么,您的问题是如何在不添加边框的情况下使面板变大,或者在包含WS_SIZEBOX 样式时如何隐藏边框。
  • 覆盖 WM_NCHITTEST 以告诉系统您在没有 WS_SIZEBOX 的情况下调整大小的“边框”在哪里。
  • 可能通过(不)自己绘制非客户区。不过,它可能会对调整大小的能力产生不利影响。非常违反直觉。. WS_SIZEBOX 通常被称为 WS_THICKFRAME,这些框架可以作为视觉线索来说明它们的用途。

标签: delphi winapi delphi-10.2-tokyo


【解决方案1】:

从您的问题中我可以看出,即使没有非客户端边界,您也希望实现 TPanel 的重新定位。如果我说得对,我可以与您分享一种解决方案。对于我的某些控件,我使用了这种技术并且它有效。
实际上,这里不需要WS_SIZEBOX 样式。

unit PanelEx;

interface

uses
  Windows,
  Messages,
  ExtCtrls;

type
  TPanelEx = class(TPanel)
  protected
    procedure WMNCHITTEST(var Message: TMessage); message WM_NCHITTEST;
  end;


implementation


procedure TPanelEx.WMNCHITTEST(var Message: TMessage);
const
  BorderSize = 10;
var
  P: TPoint;
begin
  Inherited;

  if not Assigned(Parent) then
    Exit;

  P.X := LOWORD(Message.LParam);
  P.Y := HIWORD(Message.LParam);

  // Convert screen coordinates into client
  P := Parent.ScreenToClient(P);

  // Decide what result message should have
  if (Abs(Left + Width - P.X) < BorderSize) and (Abs(Top + Height - P.Y) < BorderSize) then
    Message.Result := HTBOTTOMRIGHT
  else
  if (Abs(Left - P.X) < BorderSize) and (Abs(Top + Height - P.Y) < BorderSize) then
    Message.Result := HTBOTTOMLEFT
  else
  if (Abs(Left + Width - P.X) < BorderSize) and (Abs(Top - P.Y) < BorderSize) then
    Message.Result := HTTOPRIGHT
  else
  if (Abs(Left - P.X) < BorderSize) and (Abs(Top - P.Y) < BorderSize) then
    Message.Result := HTTOPLEFT
  else
  if Abs(Left - P.X) < BorderSize then
    Message.Result := HTLEFT
  else
  if Abs(Top - P.Y) < BorderSize then
    Message.Result := HTTOP
  else
  if Abs(Left + Width - P.X) < BorderSize then
    Message.Result := HTRIGHT
  else
  if Abs(Top + Height - P.Y) < BorderSize then
    Message.Result := HTBOTTOM;
end;


end.

【讨论】:

  • 该代码永远不会以“HTTOPRIGHT”结尾(例如),因为(Abs(Top - P.Y) &lt; BorderSize) 被检测为“HTTOP”。您应该在测试线性对角线之前测试对角线。
  • @HeartWare 谢谢 - 这是我的愚蠢错误。我从我的一个项目中获取了该代码,并删除了我在此消息处理程序中使用的其他代码,这就是我犯了一个可悲的错误的原因。
  • 谢谢迪玛。这太棒了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2012-06-18
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多