Schöne Tag auch!
Wie der Titel schon sagt, versuche ich einen Treeview mit nem Hintegrundbild zu versehen. Ich hab mich schon damit abfunden, dass ich alle Einträge und Images selber zeichnen muss, da dieses Control keinen transparenten Text ausgeben mag.
Am besten gebe ich mal den Code Preis, mit das Bild und die Texte zeichne:
Delphi-Quellcode:
Function HandleCustomDraw(hWndTV: HWnd; pNMTVCD:PNMTVCustomDraw):LongInt;
Var
hItem:HTreeItem;
tvi:TTVItem;
Rc:TRect;
DC:HDC;
szText:
Array[0..255]
of Char;
Begin
if (pNMTVCD=NIL)
Then Begin Result:=-1; Exit;
End;
hItem:=HTreeItem(pNMTVCD.nmcd.dwItemSpec);
Zeromemory(@tvi,SizeOf(TTVItem));
DC:=pNMTVCD.nmcd.hdc;
Case (pNMTVCD.nmcd.dwDrawStage)
of
CDDS_PREPAINT:
Begin
GetClientRect(hWndTV,Rc);
FillRect(pNMTVCD.nmcd.hdc,Rc,Br);
Result:=(CDRF_NOTIFYITEMDRAW);
End;
CDDS_ITEMPREPAINT:
Begin
tvi.mask:=TVIF_HANDLE
Or TVIF_PARAM
Or TVIF_TEXT
Or TVIF_IMAGE
Or
TVIF_SELECTEDIMAGE;
tvi.hItem:=hItem;
FillChar(szText,255,0);
tvi.pszText:=szText;
tvi.cchTextMax:=255;
TreeView_GetItem(hWndTV, tvi);
SetTextColor(
DC,0);
SetBKMode(
DC,TRANSPARENT);
TreeView_GetItemRect(hWndTV,hItem,Rc,TRUE);
DrawText(
DC,tvi.pszText,Length(tvi.pszText),Rc,DT_LEFT);
Result:=(CDRF_SKIPDEFAULT);
End;
// CDDS_ITEMPREPAINT
Else Result:=0;
End;
End;
Das klappt alles soweit ganz gut. Probleme gibt es jedoch beim Expandieren von Einträgen. Dann kopiert Windows den kompltten Fensterinhalt eine Zeile nach unten, damit nicht alle Einträge neu gezeichnet werden müssen. Danach sieht mein Bild natürlich ziemlich bekloppt aus. Abhilfe kann ich nur durch Subclassing schaffen, indem ich bei jeder WM_PAINT Message den gesamten Fensterinhalt für ungültig erkläre. Dummerweise zieht eben dieses ein gar fürchterliches Flackern nach sich:
Delphi-Quellcode:
Function TVWndProc(AWnd:HWnd; AMsg:DWord; wparam:WParam; lparam:LParam):LResult; STDCALL;
Var Rc:TRect;
Begin
Case AMsg of
WM_ERASEBKGND:Begin
Result:=1; Exit;
End;
WM_PAINT:Begin
GetClientRect(AWnd,Rc);
InvalidateRect(AWnd,@Rc,TRUE);
End;
End;
Result:=CallWindowProc(OldTVProc,AWnd,AMsg,wparam,lparam);
End;
Gibt es eine Lösung für diese Geschichte? Irgendeinen Window oder Klassenstyl setzen / löschen?
Vielen Dank für Eure Hilfe
Gruss
OLLI