2009-05-01 48 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