【问题标题】:How to draw on a TPanel如何在 TPanel 上绘图
【发布时间】:2010-10-23 06:10:42
【问题描述】:

我需要在 TPanel 上绘制,最好是直接绘制,这样我就不会在它上面有另一个组件妨碍 mousevent 事件捕获(我想在它上面绘制一点“尺寸控制”)。我该怎么做呢?

【问题讨论】:

  • 我想知道您是如何创建组件标签的? ;) 喜欢你的问题 +1
  • 感谢@MasterPeter 的微笑和@Mason Wheeler 的修复。
  • 我在这里提出了一个类似(更全局,适用于 VCL 中的任何控件)的问题:stackoverflow.com/questions/65050463/…

标签: delphi canvas components tpanel


【解决方案1】:

这是Raize Components 可以让您的生活更轻松的众多方式之一。我只是进入 Delphi,放在 TRzPanel 上,然后输入:

RzPanel1.Canvas.Rectangle...

我确信还有其他解决方案 - 但我不必通过 Raize 寻找它们。

(只是大约 10 年的满意客户......)

编辑:鉴于您的目标以及您已经拥有 Raize 组件的声明,我还应该指出 TRzSizePanel 处理面板的大小调整和 OnCanResize 等有用事件(以确定您是否要允许调整到特定的新宽度或高度)。

【讨论】:

  • 太棒了——我HAVE Raize,所以会研究这个(之前没有因为想要开始“尽可能简单/低级” ”,但这可能是最好的路线)。感谢您抽出宝贵时间发布此内容。
  • Raize 如何使这比在普通的 TPanel 上绘图更容易?除非 Raize 控件出于某种原因使 Canvas 属性公开而不是受保护。
  • 从代码示例看来,这正是原因。
  • 我发现使用 Raize 组件简化了我的编码并使我的应用程序在视觉上保持一致。 Ray 几乎考虑了所有事情,他对 raize.public.rzcomps.support 新闻组的支持非常出色 - 我阅读了他在该新闻组中写的所有内容,因为他的编码实践非常干净。出于同样的原因,他的源代码值得一读。
【解决方案2】:

要真正做到这一点,您可能应该编写一个后代类。覆盖 Paint 方法以绘制大小控制夹点,并覆盖 MouseDownMouseUpMouseMove 方法以向控件添加调整大小功能。

我认为这比尝试在您的应用程序代码中使用 TPanel 更好的解决方案,原因如下:

  1. Canvas 属性在TPanel 中受到保护,因此您无法从类外部访问它。你可以通过类型转换来解决这个问题,但这是作弊。
  2. “可调整大小”听起来更像是面板的一项功能,而不是应用程序的一项功能,因此请将其放在面板控件的代码中,而不是应用程序的主代码中。

以下是帮助您入门的内容:

type
  TSizablePanel = class(TPanel)
  private
    FDragOrigin: TPoint;
    FSizeRect: TRect;
  protected
    procedure Paint; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
  end;

procedure TSizeablePanel.Paint;
begin
  inherited;
  // Draw a sizing grip on the Canvas property
  // There's a size-grip glyph in the Marlett font,
  // so try the Canvas.TextOut method in combination
  // with the Canvas.Font property.
end;

procedure TSizeablePanel.MouseDown;
begin
  if (Button = mbLeft) and (Shift = []) 
      and PtInRect(FSizeRect, Point(X, Y)) then begin
    FDragOrigin := Point(X, Y);
    // Need to capture mouse events even if the mouse
    // leaves the control. See also: ReleaseCapture.
    SetCapture(Handle);
  end else inherited;
end;

【讨论】:

  • 谢谢罗伯!您所描述的(并慷慨地提供了一些“入门代码”)是我想要做的,但我意识到我需要弄清楚绘图/画布部分,所以直接在应用程序代码中探索它。非常感谢您在这里的输入——非常有帮助! :-)
  • 请注意,这也是明智的,因为例如非 Windows 上的 Lazarus(也可能是 Kylix),不允许在 .PAINT 事件之外在画布上绘画。因此,直接强制执行确保仅在绘制事件中完成绘制的结构可能是明智之举。
【解决方案3】:

如何为在运行时调整大小的控件添加大小句柄: http://delphi.about.com/library/weekly/aa110105a.htm

TAdv 面板: http://www.tmssoftware.com/site/advpanel.asp

【讨论】:

    【解决方案4】:

    最简单的方法是在面板上放置一个 TImage。但是,如果您真的不想这样做,请在代码编辑器中键入 TCanvas,按 F1,然后愉快地了解它是如何工作的。 (别说我没警告过你……)

    【讨论】:

    • 我实际上认为我可以做 TCanvas 部分,给定一些我必须使用的示例代码......但是我如何公开面板本身的 TCanvas?我找到了这个,但听起来好像缺少了什么:mail-archive.com/delphi@elists.org/msg00582.html
    • 该链接中的 TMyPanel(panel) 代码是关键。如果您在要访问画布的同一单元中定义继承类,则可以访问该类的任何受保护属性。这是德尔福“单元内的类是朋友”原则的一部分。这也是一个黑客。 :-)
    • 当您说“这也是一种黑客行为”时——这是否意味着您认为这种方法不合适? (只是想从我在这个问题上得到的这些好答案中尽我所能学习)。
    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多