Come disegnare su un TPanel
-
03-07-2019 - |
Domanda
Ho bisogno di disegnare su un TPanel, idealmente direttamente, quindi non ho un altro componente sopra di esso che si frappone al trapping di eventi mousevent (voglio disegnare un po 'di "size-grip" su di esso) . Come devo fare per fare questo?
Soluzione
Per farlo davvero bene, probabilmente dovresti scrivere una classe discendente. Sostituisci il metodo Paint
per disegnare il grip di ridimensionamento, e sostituisci i metodi MouseDown
, MouseUp
e MouseMove
da aggiungere ridimensionamento della funzionalità al controllo.
Penso che sia una soluzione migliore rispetto al tentativo di disegnare su un TPanel
nel codice dell'applicazione per un paio di motivi:
- La proprietà
Canvas
è protetta inTPanel
, quindi non puoi accedervi dall'esterno della classe. Puoi aggirare il problema con il cast di tipo, ma questo è barare. - La "quotabilità" " sembra più una caratteristica del pannello che una caratteristica dell'applicazione, quindi inseriscilo nel codice per il controllo del pannello, non nel codice principale dell'applicazione.
Ecco qualcosa per iniziare:
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;
Altri suggerimenti
Questo è uno dei molti modi in cui Raize Components può semplificarti la vita. Vado in Delphi, lancio un TRzPanel e digito:
RzPanel1.Canvas.Rectangle ...
Sono sicuro che ci sono altre soluzioni, ma non devo cercarle con Raize.
(solo un cliente soddisfatto per circa 10 anni ...)
EDIT: dato il tuo obiettivo e la tua affermazione che hai già Raize Components, dovrei anche sottolineare che TRzSizePanel gestisce il ridimensionamento del pannello e eventi utili come OnCanResize (per determinare se vuoi consentire il ridimensionamento a una particolare nuova larghezza o altezza).
Il modo più semplice per farlo è semplicemente mettere una TImage sul pannello. Ma se davvero non vuoi farlo, digita TCanvas nell'editor di codice, premi F1 e divertiti a imparare come funziona sotto il cofano. (Non dire che non ti avevo avvertito ...)
Come aggiungere handle di dimensioni ai controlli che vengono ridimensionati in fase di esecuzione: http://delphi.about.com/library/weekly/aa110105a.htm
TAdvPanel: http://www.tmssoftware.com/site/advpanel.asp