2011-12-13 39 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