2009-11-02 26 views
2

我有一個TListView的後代,它提供了一些額外的功能,例如排序和從TDataset加載本身的能力。我現在希望進一步擴展該組件,以便在項目添加到列表視圖時指定圖形的某些方面。在TListview後裔中的自定義繪圖

我很難找出重寫哪個程序或程序來控制繪圖。我已經重寫了DrawItem來更改字體樣式以包含刪除線,然後調用繼承的DrawItem。如果我還指定了樣式LVS_OWNERDRAWFIXED(在一個被覆蓋的CreateParams())中,我的函數被調用並按照我的想法工作,除了只繪製了項目而不是子項目。

有誰知道我該如何告訴列表視圖來繪製子項?我發現one example大大增強了列表視圖,但是這一個沒有足夠好的記錄讓我完全瞭解發生了什麼,並且我希望不必像這一個那樣鉤住儘可能多的事件和窗口消息沒有 - 在我看來,簡單地設置畫布筆,畫筆和字體,然後讓項目繪製自己不應該是如此參與。

這是我到目前爲止有:

protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    procedure DrawItem(Item: TListItem; Rect: TRect; State: TOwnerDrawState); override; 

procedure TLookupListView.CreateParams(var Params: TCreateParams); 
begin 

    inherited CreateParams(Params); 

    Params.Style := Params.Style or lvs_OwnerDrawFixed; 

end; 

procedure TLookupListView.DrawItem(Item: TListItem; Rect: TRect; State: TOwnerDrawState); 
var I: Integer; 
    Left: Integer; 
begin 

    Canvas.Font.Style := Canvas.Font.Style + [fsStrikeOut]; 
    inherited DrawItem(Item, Rect, State); 
    //I know the canvas must be restored here, this is just for proof-of-concept. 

end; 

請注意:我沒有興趣做定製使用提供的事件TListView的特定實例繪製。我知道該怎麼做。我試圖將這個功能「烘烤」到我的自定義TListview後代組件中。

回答

2

該組件具有虛擬方法IsCustomDrawn(),調用該組件以確定需要執行哪些代碼路徑。在基類實現中,它會檢查是否分配了任何用於繪製子項目的事件處理程序,但是您可以覆蓋該方法以返回要處理的所有繪製階段的True,即使沒有分配事件處理程序。

如果您想要處理代碼中的所有內容,您應該覆蓋CustomDrawItem()CustomDrawSubItem()並在此處執行所有操作。爲了讓所有的工作都能正常工作,我將使用調試DCU構建應用程序,從事件處理程序中進入並查看可以使用的最小代碼量。檢查出的重要方法是TCustomListView.CNNotify() - 這裏處理所有者繪圖的Windows消息。

編輯:

我忘了補充一點,你應該儘量不要所有者繪製控件中的文本,只是在不同的油漆階段設置畫布屬性 - 的理由是,否則,你將有以確保文本輸出在所有Windows版本中都是像素完美的,這是VCL無法實現的。您可以通過在列表視圖中添加幾列和幾行來查看,並在設計時切換OwnerDraw屬性,文本會跳轉。

+0

謝謝mghie。事實上,我試圖避免自己繪製文本,無論是標題還是子項目。 CustomDrawItem和CustomDrawSubItem看起來像我想要的。我正在進一步調查。 。 。 – 2009-11-02 15:33:57

+0

對,所以也許你甚至可以刪除'LVS_OWNERDRAWFIXED'樣式標誌,因爲繪製階段通知不是(全部)依賴它。 – mghie 2009-11-02 15:38:43

+0

是的,我不需要LVS_OWNERDRAWFIXED。現在我明白了,除了重寫IsCustomDrawn和CustomDrawItem(CustomDrawItem中的畫布更改通過子項目的繪製保持有效)之外,沒有其他更改。我想我留下的只是確保用戶自定義繪圖的任何用戶事件都不會被忽略。 – 2009-11-02 15:49:39

1

您使用的是哪個版本的Delphi?在Delphi 2007中,TListView通過處理NM_CUSTOMDRAW消息支持自定義繪圖,如here所述。 TListView已經爲自定義繪圖子項目定義了事件,以及可以在子項中覆蓋的虛擬方法。

+0

D2007,我很快想把它移到D2010。我會檢查鏈接,非常感謝。 – 2009-11-02 15:18:37