2013-07-05 61 views
7

我在Delphi中有一個TTreeView,節點在三個級別。在treeview節點中顯示額外的文本,而不僅僅是node.text

我使用節點數據來存儲節點文本以外的另一個標籤。

Type 
    TNodeData = class 
    ExtraNodeLabel: WideString; 
    //... other members 
    end; 

我有一個OnAdvancedCustomDrawItem事件,在這裏我想顯示此ExtraNodeLabel節點文本之前。 我要實現這一點:

  • 藍色的文本將是額外的標籤。
  • 突出顯示的項目:前兩個單詞也是一個額外的標籤

enter image description here

我走到這一步,是這樣的:

enter image description here

問題:

  1. 出於某種原因,我無法繪製如果我使用DrawText/drawTextW(我需要因爲Unicode數據的drawtextW)不同風格的文本
  2. 另一個問題是,虛線焦點矩形以外,任何事情都是不可點擊

什麼需要解決:

  1. 我如何使用DrawText/DrawtextW
  2. 怎麼能即時繪製不同樣式的文本讓全文可點擊?

代碼:

procedure TMainForm.TntTreeView1AdvancedCustomDrawItem(
    Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; 
    Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean); 
var 
    txtrect, fullrect : TRect; 
    DC: HDC; 
    fs: integer; 
    fc: TColor; 
    ExtralabelRect: TRect; 
    nData: TNodeData; 
begin 
    nData := nil; 

    if assigned(Node.Data) then begin 
    nData := TNodeData(Node.Data); 
    end; 

    DC := TntTreeView1.canvas.Handle; 
    txtRect := Node.DisplayRect(True);  
    fullrect := Node.DisplayRect(False); 

    if stage = cdPostPaint then begin 
    TntTreeView1.Canvas.FillRect(txtRect); 
    if (cdsFocused In State) And (cdsSelected in State) then begin 
     DrawFocusRect(DC,txtRect); 
    end; 

    txtRect.Left := txtRect.Left + 1; 
    txtRect.Top := txtRect.Top + 1; 
    txtRect.Right := txtRect.Right - 1; 
    txtRect.Bottom := txtRect.Bottom - 1; 

    ExtralabelRect := txtRect; 

    fs := TntTreeView1.Canvas.Font.size; 
    fc := TntTreeView1.Canvas.Font.Color; 

    if (nData <> nil) And (nData.ExtraNodeLabel <> '') then begin 
     TntTreeView1.Canvas.Font.Size := 7; 
     TntTreeView1.Canvas.Font.color := clBlue; 
     DrawTextW(
     DC, 
     PWideChar(nData.ExtraNodeLabel), 
     Length(nData.ExtraNodeLabel), 
     ExtraLabelRect, 
     DT_LEFT or DT_CALCRECT or DT_VCENTER 
    ); 

     DrawTextW(
     DC, 
     PWideChar(nData.ExtraNodeLabel), 
     Length(nData.ExtraNodeLabel), 
     ExtraLabelRect, 
     DT_LEFT or DT_VCENTER 
    ); 

     txtRect.right := txtRect.Right + ExtraLabelRect.Right + 5; 
     txtRect.Left := ExtraLabelRect.Right + 5; 
    end; 

    TntTreeView1.Canvas.Font.Size := fs; 
    TntTreeView1.Canvas.Font.color := fc; 

    DrawTextW(
     DC, 
     PWideChar((Node as TTntTreeNode).Text), 
     -1, 
     txtRect, 
     DT_LEFT or DT_VCENTER 
    ); 
    end; 
end; 
+2

你的2號可能是與事實做到這一點的樹措施的節點文本的寬度來確定焦點矩形,並不會採取你的額外文本我nto帳戶。要解決這個問題,您必須將文本添加到節點的文本中,或者創建您自己的TTreeview後代,並找到一種方法來覆蓋/鉤入焦點矩形的寬度度量(快速閱讀[documentation](http: /docwiki.embarcadero.com/Libraries/XE4/en/Vcl.ComCtrls.TTreeView)不會引發任何明顯的事件)。 –

+1

正如@Marjan所說。沒有什麼比如'TVM_SETITEMRECT'和'TVM_SETITEMHEIGHT',通知消息或者用於設置節點寬度的宏。我會說,你將需要設置TTreeNode.Text屬性值來適當擴展節點寬度。 – TLama

+0

不幸的是我不能設置TTreeNode.Text屬性,因爲這個值不應該與節點文本一起保存。 – beerwin

回答

2

解由OP

我設法部分地解決自定義繪圖,通過定義變量TFont,以及使用SelectObjectsetTextColor。設置字體顏色和樣式的作品,但設置字體大小不。

var 
    nFont: TFont; 
begin 
    DC := TntTreeView1.Canvas.Handle; 
    NFont := TFont.Create; 

    // rest of the code here ... 

    // i tried to set nFont.Size, but it doesn't seem to work 
    nFont.Size := 7; 
    nFont.Color := colorToRGB(clBlue); 
    nFont.Style := TntTreeview1.Font.Style + [fsBold]; 

    SelectObject(DC,NFont.Handle); 
    SetTextColor(DC,colortoRGB(clBlue)); 

    DrawTextW(
    DC, 
    PWideChar(nData.nodeLabel), 
    Length(nData.nodeLabel), 
    ExtraLabelRect, 
    DT_LEFT or DT_VCENTER 
); 

    // rest of the code here 
end; 

來源: I used the idea from here


更新2

我的TreeView的RowSelect屬性設置爲true解決的第二個問題。 爲此,爲了工作,我必須將ShowLines屬性設置爲false,並自定義繪製線條和按鈕。它現在有效。


更新3

我改進了對第一個問題的解決方案,通過不創建一個新的字體,但選擇在畫布上的字體顯示文本,這樣我能夠改變任何方面字體,並且還應用了系統的ClearType設置:

// set font size for the canvas font (font style can be set the same time) 
TntTreeView1.Canvas.Font.Size := 7; 

// select canvas font for DC 
SelectObject(DC,TntTreeView1.Canvas.Font.Handle); 

// set font color 
SetTextColor(DC,colortoRGB(clBlue)); 
相關問題