2011-12-13 53 views
3

我試圖從使用Toolbar2000切換到常規工具欄,因爲似乎沒有德爾福XE2版本,它看起來像它使用一些大會,我只是不真的想要處理它,如果我不必。 (我真的很喜歡Delphi工具欄的淡入效果)德爾福toolbuttons剝離效果(TToolbutton)

但是,我不喜歡的是,按鈕的背景獲得了常規的藍色按鈕處理。我知道如何改變顏色,但是我可以不改變顏色並且沒有在按鈕周圍繪製邊框?

我已經實現了'OnAdvancedCustomDrawButton',但可用的標誌看起來不能正常工作,我不確定它們如何與漸變色和熱軌道顏色進行交互,並且發現有一些奇怪的閃爍或怪異的黑色背景。

下面是我如何創建工具欄

ToolBar1 := TToolBar.Create(Self); 
ToolBar1.DoubleBuffered := true; 
ToolBar1.OnAdvancedCustomDrawButton := Toolbar1CustomDrawButton; 
ToolBar1.Transparent := false; 
ToolBar1.Parent := Self; 
ToolBar1.GradientEndColor := $7ca0c2; //RGB(194, 160, 124); 
ToolBar1.GradientStartColor := $edeeed; //RGB(237, 238, 124); 
ToolBar1.Indent := 5; 
ToolBar1.Images := Normal; 
ToolBar1.DrawingStyle := dsGradient; 
ToolBar1.HotImages := Over; 
ToolBar1.AutoSize := True; 
ToolBar1.Visible := False; 

,這裏是我如何創建按鈕(在一個循環中):

ToolButton := TToolButton.Create(ToolBar1); 
ToolButton.Parent := ToolBar1; 
ToolButton.ImageIndex := ToolButtonImages[Index].ImageIndex; 
ToolButton.OnClick := ToolButtonClick; 

,這裏是我的AdvancedCustomDrawButton功能

procedure TMyForm.Toolbar1CustomDrawButton(Sender: TToolBar; Button: TToolButton; 
    State: TCustomDrawState; Stage: TCustomDrawStage; 
    var Flags: TTBCustomDrawFlags; var DefaultDraw: Boolean); 
begin 
    Flags := [tbNoEdges, tbNoOffset]; 
    DefaultDraw := True; 
end; 
+0

因爲它是德爾福可以從父對象繼承並且在initialize()之後,如果你喜歡,你可以通過覆蓋它來設置值嗎?你是否有對象減號的代碼示例或者如何實例化對象...? – MethodMan 2011-12-13 16:58:18

+0

好吧,我添加了我的代碼,我認爲它不一定有幫助,但是你重寫了什麼?我不認爲製作我自己的TToolButton會有幫助,因爲現有的繪畫功能甚至不在我想要擺脫的東西完成。也許我只需要設置`defaultdraw:= false`並自己做所有事情。 – 2011-12-13 17:07:59

回答

2

將工具欄的繪圖風格設置爲dsNormal並設置Flags改爲自定義繪圖處理程序中的[tbNoEdges]。

更新:

雖然2K和XP,Vista和Windows 7上面的工作似乎沒有繪製邊框時不繪製按鈕的背景。不幸的是,使用VCL提供的TTBCustomDrawFlags來實現這一點是不可能的,所以我們無法擺脫自定義繪圖處理程序中的邊框。

如果工具欄的形式本身,我們可以把一個處理程序WM_NOTIFY,因爲通知消息被髮送到父窗口:如果工具欄在另一個窗口父

type 
    TForm1 = class(TForm) 
    .. 
    private 
    procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY; 
    .. 
    .. 

procedure TForm1.WMNotify(var Msg: TWMNotify); 
begin 
    inherited; 
    if (Msg.NMHdr.code = NM_CUSTOMDRAW) and 
     Assigned(Toolbar1) and (Toolbar1.HandleAllocated) and 
     (Msg.NMHdr.hwndFrom = ToolBar1.Handle) then 

    case PNMTBCustomDraw(Msg.NMHdr).nmcd.dwDrawStage of 
     CDDS_PREPAINT: Msg.Result := Msg.Result or CDRF_NOTIFYITEMDRAW; 
     CDDS_ITEMPREPAINT: Msg.Result := TBCDRF_NOEDGES or TBCDRF_NOBACKGROUND; 
          // NOEDGES for 2K, XP, // NOBACKGROUND for Vista 7 
    end; 
end; 

,如面板,然後我們需要繼承的工具欄:(需要注意的是繪畫風格仍需要dsNormal

type 
    TForm1 = class(TForm) 
    .. 
    private 
    FSaveToolbarWndProc: TWndMethod; 
    procedure ToolbarWndProc(var Msg: TMessage); 
    .. 
.. 

uses 
    commctrl; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    .. 
    FSaveToolbarWndProc := ToolBar1.WindowProc; 
    ToolBar1.WindowProc := ToolbarWndProc; 
end; 

procedure TForm1.ToolbarWndProc(var Msg: TMessage); 
begin 
    FSaveToolbarWndProc(Msg); 

    if (Msg.Msg = CN_NOTIFY) and 
     (TWMNotify(Msg).NMHdr.hwndFrom = ToolBar1.Handle) and 
     (TWMNotify(Msg).NMHdr.code = NM_CUSTOMDRAW) then begin 

    case PNMTBCustomDraw(TWmNotify(Msg).NMHdr)^.nmcd.dwDrawStage of 
     CDDS_PREPAINT: Msg.Result := CDRF_NOTIFYITEMDRAW; 
     CDDS_ITEMPREPAINT: Msg.Result := TBCDRF_NOEDGES or TBCDRF_NOBACKGROUND; 
    end; 
    end; 
end; 


使用此解決方案,您無需爲自定義繪圖添加處理程序。但是,如果你需要/想,無論如何,你可能需要「或」該Msg.Result與一個VCL的窗口過程的回報,即「案例」會是什麼樣子:

CDDS_PREPAINT: Msg.Result := Msg.Result or CDRF_NOTIFYITEMDRAW; 
    CDDS_ITEMPREPAINT: Msg.Result := 
        Msg.Result or TBCDRF_NOEDGES or TBCDRF_NOBACKGROUND; 

也是如此,當我們處理WM_NOTIFY上表格。


可能還有其他方法可以實現同樣的效果,自定義繪圖是一個廣泛的話題。如果你想深入研究的話,我建議你從下面的鏈接,手頭的問題開始:

About Custom Draw
NM_CUSTOMDRAW (toolbar) notification code
NMCUSTOMDRAW structure
NMTBCUSTOMDRAW structure