2009-05-01 65 views
3

我需要在TPanel上绘制,理想情况下是直接绘制,所以我没有其他组件在它上面进行鼠标事件捕捉(我想绘制一个“尺寸 - 抓住“)。我应该如何去做这件事?如何在TPanel上绘图

+0

我不知道你们是怎么管理创建compoennts标签? ;)像你的问题+1 – 2009-05-01 23:32:11

+0

这是一个错字。我修好了...... – 2009-05-02 00:23:26

+0

谢谢 - @MasterPeter的微笑,以及@梅森惠勒的修复。 – Jamo 2009-05-02 01:00:07

回答

9

要真正这样做的权利,你应该写一个子类。重写Paint方法绘制尺寸控制柄,并覆盖MouseDown,MouseUpMouseMove方法以向控件添加调整大小功能。

我认为这是比试图在应用程序代码上绘制一个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; 
+0

谢谢Rob!你所描述的(并且慷慨地提供了一些“入门代码”)正是我想要做的,但是我意识到我需要弄清楚绘图/ Canvas部分,所以直接在应用代码中进行探索。非常感谢您的意见 - 超级有用! :-) – Jamo 2009-05-02 15:40:30

+0

请注意,这也是明智的,因为例如非窗口上的拉撒路(也可能是Kylix),不允许在.PAINT事件之外的画布上绘画。 因此,直接强制执行一个确保唯一绘图在绘画事件中完成的结构可能很明智。 – 2009-05-02 19:27:41

4

最简单的方法就是在面板上放置一个TImage。但是,如果你真的不想这么做,那么在代码编辑器中输入TCanvas,点击F1,并且乐于了解它在底层如何工作。 (不要说我没有提醒你...)

+0

我实际上认为我可以做TCanvas部分,因为我必须从一些示例代码开始工作...但是我如何暴露面板本身的TCanvas?我发现这一点,但它听起来像缺少它:http://www.mail-archive.com/[email protected]/msg00582.html – Jamo 2009-05-02 00:59:30

+1

该链接的TMyPanel(面板)代码是关键。如果您在想要访问画布的同一单元中定义继承的类,则可以访问该类的任何受保护属性。它是德尔福“单元内的班级是朋友”原则的一部分。这也是一个黑客。:-) – 2009-05-02 06:13:14

+0

当你说“这也是一个黑客” - 这是否意味着你认为这种做法是不恰当的? (只是试图从这些问题中学到所有我可以从这个问题中得到的答案)。 – Jamo 2009-05-02 16:23:54

7

这是Raize Components可以让你的生活更轻松的许多方法之一。我刚进入德尔福,在TRzPanel下降,和类型:

RzPanel1.Canvas.Rectangle ...

我敢肯定有其他的解决方案 - 但我没有与Raize一起寻找他们。

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

编辑:鉴于你的目标,你有Raize组件已经在你的说法,我也应该指出的是,TRzSizePanel处理面板的大小调整和像OnCanResize这样有用的事件(以确定您是否允许调整大小到特定的新宽度或高度)。

+0

伟大的 - 我* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *(因为想要开始的原因,“尽可能简单/低级”,但这可能是最好的路线)感谢您花时间发布此信息。 – Jamo 2009-05-02 03:41:04

+0

Raize如何让它比绘制普通的TPanel更简单?除非Raize控件由于某种原因使Canvas属性公开而不受保护。 – 2009-05-02 04:56:45

+1

从代码示例看来,这就是为什么。 – 2009-05-02 12:14:46