2012-06-07 7 views
8

मैं OnAdvancedCustomDrawItem ईवेंट का उपयोग कर स्क्रैच से कस्टम TTreeView ड्राइंग कर रहा हूं, और मुझे आश्चर्य है कि मेरे चयन-ड्रा आइटम की पृष्ठभूमि में इन चयनों और गर्म आयतों को सही ढंग से प्रस्तुत करने का तरीका कैसा है? वे विस्टा/7 स्टाइल हैं इसलिए मैं कुछ ठोस रंग में पृष्ठभूमि को भर नहीं सकता।उन्नतCustomDrawItem के दौरान TTreeView के स्टाइल चयन आयत को कैसे आकर्षित करें?

enter image description here

मैं cdPostPaint चरण में अपने आइटम आकर्षित करने के लिए करने की कोशिश की, लेकिन अगर मैं cdPrePaint स्तर पर DefaultDraw := True छोड़ चयन पृष्ठभूमि आकर्षित करने के लिए, पूरा डिफ़ॉल्ट ड्राइंग वस्तुओं के पाठ सहित, होता है।

procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; 
    Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, 
    DefaultDraw: Boolean); 
begin 
    case Stage of 
    cdPreErase: 
    begin 
     DefaultDraw := True; 
    end; 

    cdPostErase: 
    begin 
     DefaultDraw := True; 
    end; 

    cdPrePaint: 
    begin 
     // I thought this will paint only the selected/hot backgrounds, 
     // however this will paint whole item, including text. 
     DefaultDraw := True; 
    end; 

    cdPostPaint: 
    begin 
     DefaultDraw := False; 

     // painting my owner-draw text 
     // ......... 
    end; 
    end; 

    PaintImages := False; 
end; 
+0

आपको थीम एपीआई, विंडोज के सबसे खराब दस्तावेज क्षेत्र का उपयोग करने की आवश्यकता है। गुड लक उस के साथ कहीं भी हो रही है। वर्चुअल ट्रीव्यूव यहां एक अच्छे विकल्प की तरह दिख रहा है। मुझे लगता है कि अनुकूलित करना आसान है। –

+0

@ डेविड हेफरन मानक ट्री व्यू के ड्राइंग का उपयोग करने का कोई मौका नहीं है? – Andrew

+0

बेशक। लेकिन दस्तावेज़ीकरण के बिना, यह आसान नहीं है। –

उत्तर

12

यहां मेरा समाधान (परीक्षण) है।

ध्यान दें कि ट्री व्यू में सामान्य रूप से गर्म वस्तुओं को आकर्षित करने के लिए HotTrack := True होना चाहिए।

थीम सक्षम होने पर अतिरिक्त ड्राइंग भी होनी चाहिए।

uses 
    UxTheme, 
    Themes; 

const 
    TreeExpanderSpacing = 6; 

procedure TForm1.DrawExpander(ACanvas: TCanvas; ATextRect: TRect; AExpanded: Boolean; 
    AHot: Boolean); 
var 
    ExpanderRect: TRect; 
    Graphics: IGPGraphics; 
    Points: array of TGPPoint; 
    Brush: IGPBrush; 
    Pen: IGPPen; 
    ThemeData: HTHEME; 
    ElementPart: Integer; 
    ElementState: Integer; 
    ExpanderSize: TSize; 
    UnthemedColor: TColor; 
begin 
    if ThemeServices.ThemesEnabled then 
    begin 
    if AHot then 
     ElementPart := TVP_HOTGLYPH 
    else 
     ElementPart := TVP_GLYPH; 

    if AExpanded then 
     ElementState := GLPS_OPENED 
    else 
     ElementState := GLPS_CLOSED; 

    ThemeData := OpenThemeData(TreeView1.Handle, VSCLASS_TREEVIEW); 
    GetThemePartSize(ThemeData, ACanvas.Handle, ElementPart, ElementState, nil, 
     TS_TRUE, ExpanderSize); 
    ExpanderRect.Left := ATextRect.Left - TreeExpanderSpacing - ExpanderSize.cx; 
    ExpanderRect.Right := ExpanderRect.Left + ExpanderSize.cx; 
    ExpanderRect.Top := ATextRect.Top + (ATextRect.Bottom - ATextRect.Top - ExpanderSize.cy) div 2; 
    ExpanderRect.Bottom := ExpanderRect.Top + ExpanderSize.cy; 
    DrawThemeBackground(ThemeData, ACanvas.Handle, ElementPart, ElementState, ExpanderRect, nil); 
    CloseThemeData(ThemeData); 
    end 
    else 
    begin 

    // Drawing expander without themes enabled 

    Graphics := TGPGraphics.Create(ACanvas.Handle); 
    Graphics.SmoothingMode := SmoothingModeHighQuality; 

    ExpanderRect := ATextRect; 
    ExpanderRect.Right := ATextRect.Left - TDPIAware.GetScaledSize(TreeExpanderSpacing96dpi); 
    ExpanderRect.Left := ATextRect.Left - TDPIAware.GetScaledSize(TreeExpanderSpacing96dpi) - 
     TDPIAware.GetScaledSize(Max(TreeExpanderCollapsedWidth96dpi, TreeExpanderExpandedWidth96dpi)); 

    if ASelected then 
     UnthemedColor := ColorToRGB(clHighlightText) 
    else 
     if AExpanded then 
     UnthemedColor := clBlack 
     else 
     UnthemedColor := clGray; 

    SetLength(Points, 3); 
    if AExpanded then 
    begin 
     Points[0] := TGPPoint.Create(ExpanderRect.Right, ExpanderRect.Top + 
     (ExpanderRect.Bottom - ExpanderRect.Top - TreeExpanderExpandedHeight96dpi) div 2); 
     Points[1] := TGPPoint.Create(ExpanderRect.Right, ExpanderRect.Top + 
     (ExpanderRect.Bottom - ExpanderRect.Top + TreeExpanderExpandedHeight96dpi) div 2); 
     Points[2] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderExpandedWidth96dpi, 
     ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top + 
     TreeExpanderExpandedHeight96dpi) div 2); 
     Brush := TGPSolidBrush.Create(TGPColor.CreateFromColorRef(UnthemedColor)); 
     Graphics.FillPolygon(Brush, Points); 
    end 
    else 
    begin 
     Points[0] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderCollapsedWidth96dpi, 
     ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top - 
     TreeExpanderCollapsedHeight96dpi) div 2); 
     Points[1] := TGPPoint.Create(ExpanderRect.Right, 
     ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top) div 2); 
     Points[2] := TGPPoint.Create(ExpanderRect.Right - TreeExpanderCollapsedWidth96dpi, 
     ExpanderRect.Top + (ExpanderRect.Bottom - ExpanderRect.Top + 
     TreeExpanderCollapsedHeight96dpi) div 2); 
     Pen := TGPPen.Create(TGPColor.CreateFromColorRef(UnthemedColor)); 
     Graphics.DrawPolygon(Pen, Points); 
    end; 
    end; 
end; 

procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; 
    Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, 
    DefaultDraw: Boolean); 
var 
    NodeRect: TRect; 
    NodeTextRect: TRect; 
    Text: string; 
    ThemeData: HTHEME; 
    TreeItemState: Integer; 
begin 
    if Stage = cdPrePaint then 
    begin 
    NodeRect := Node.DisplayRect(False); 
    NodeTextRect := Node.DisplayRect(True); 

    // Drawing background 
    if (cdsSelected in State) and Sender.Focused then 
     TreeItemState := TREIS_SELECTED 
    else 
     if (cdsSelected in State) and (cdsHot in State) then 
     TreeItemState := TREIS_HOTSELECTED 
     else 
     if cdsSelected in State then 
      TreeItemState := TREIS_SELECTEDNOTFOCUS 
     else 
      if cdsHot in State then 
      TreeItemState := TREIS_HOT 
      else 
      TreeItemState := TREEITEMStateFiller0; 

    if TreeItemState <> TREEITEMStateFiller0 then 
    begin 
     ThemeData := OpenThemeData(Sender.Handle, VSCLASS_TREEVIEW); 
     DrawThemeBackground(ThemeData, Sender.Canvas.Handle, TVP_TREEITEM, TreeItemState, 
     NodeRect, nil); 
     CloseThemeData(ThemeData); 
    end; 

    // Drawing expander 
    if Node.HasChildren then 
     DrawExpander(Sender.Canvas, NodeTextRect, Node.Expanded, cdsHot in State); 

    // Drawing main text 
    SetBkMode(Sender.Canvas.Handle, TRANSPARENT); 
    SetTextColor(Sender.Canvas.Handle, clBlue); 

    Text := Node.Text; 
    Sender.Canvas.TextRect(NodeTextRect, Text, 
     [tfVerticalCenter, tfSingleLine, tfEndEllipsis, tfLeft]); 

    // Some extended drawing... 

    end; 

    PaintImages := False; 
    DefaultDraw := False; 
end; 
+1

अच्छा। आप निम्न स्तर एपीआई को लपेटने वाली थीम्स में कुछ विधियों का उपयोग करना चाह सकते हैं। विषय हैंडल के साथ गड़बड़ करने के लिए बचाओ। –

+0

@ डेविड हेफरनन जब मैंने ड्राइंग के लिए 'थीम्स' रैपर का उपयोग किया, तो यह Vista-style विस्तारकों और ढाल पृष्ठभूमि को नहीं खींचा, मुझे नहीं पता कि क्यों। हो सकता है कि वे विंडोज संस्करण से 'थीम्स' स्वतंत्र बनाना चाहते हैं ताकि वे कुछ संगत स्थिरांक का उपयोग कर सकें। मैं बाद में 'थीम्स' कोड का निरीक्षण करूंगा। – Andrew

+0

यदि आप ड्रॉइंग-एक्सपेंडर-बिना-थीम कोड दिखा सकते हैं जो बाद में आने वाले अन्य लोगों के लिए सहायक होगा और यह नहीं जानते कि यह कैसे करें। –

संबंधित मुद्दे