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?
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...)
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).
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
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:
- The
Canvas
property is protected inTPanel
, so you have no access to it from outside the class. You can get around that with type-casting, but that's cheating. - 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;