How to draw on a TPanel

走远了吗. 提交于 2019-12-20 02:29:26

问题


I need to draw on a TPanel, ideally directly so I don't have another component on top of it getting in the way of mousevent-event trapping (I want to draw a little "size-grip" on it). How should I go about doing this?


回答1:


To really do it right, you should probably write a descendant class. Override the Paint method to draw the sizing grip, and override the MouseDown, MouseUp, and MouseMove methods to add resizing functionality to the control.

I think that's a better solution than trying to draw onto a TPanel in your application code for a couple of reasons:

  1. The Canvas property is protected in TPanel, so you have no access to it from outside the class. You can get around that with type-casting, but that's cheating.
  2. The "resizability" sounds more like a feature of the panel than a feature of the application, so put it in code for the panel control, not in your application's main code.

Here's something to get you started:

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;



回答2:


This is one of the many many ways that Raize Components can make your life easier. I just go into Delphi, drop on a TRzPanel, and type:

RzPanel1.Canvas.Rectangle...

I'm sure there are other solutions - but I don't have to look for them with Raize.

(just a satisfied customer for about 10 years...)

EDIT: Given your goal, and your statement that you have Raize Components already, I should also point out that TRzSizePanel handles resizing of the panel and useful events like OnCanResize (to determine whether you want to allow resizing to a particular new width or height).




回答3:


The simplest way to do it is to just put a TImage on the panel. But if you really don't want to do that, type TCanvas into the code editor, hit F1, and have fun learning about how it works under the hood. (Don't say I didn't warn you...)




回答4:


How to Add Size Handles to Controls being Resized at Run-Time: http://delphi.about.com/library/weekly/aa110105a.htm

TAdvPanel: http://www.tmssoftware.com/site/advpanel.asp



来源:https://stackoverflow.com/questions/813693/how-to-draw-on-a-tpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!