Habe jetzt ein funktionierte Lösung erarbeitet um den Hintergrund des SysListView32 Farbig zu gestalten.
1. Subclass und UnSubclass erstellen.
Delphi-Quellcode:
procedure SysListSubClass(WinHandle: HWND);
begin
FSysListInstance := MakeObjectInstance(OpenDialog.SysListSubClassProc);
FPrevSysListProc := Pointer(GetWindowLong(WinHandle, GWL_WNDPROC));
SetWindowLong(WinHandle, GWL_WNDPROC, Integer(FSysListInstance));
end;
procedure SysListUnSubClass(WinHandle: HWND);
begin
SetWindowLong(WinHandle, GWL_WNDPROC, Integer(FPrevSysListProc));
FreeObjectInstance(FSysListInstance);
end;
2. Die Winproc dafür
Delphi-Quellcode:
function SysListProc(WinHandle: HWND; Msg: UINT; wp: WPARAM; lp: LPARAM): longint; stdcall;
begin
Result := 0;
case Msg of
WM_ERASEBKGND:
begin
UpdateColors(WinHandle); // Das ist der Trick
ListView_SetSelectedColumn(WinHandle, -1); // und das!
Result := 1;
Exit;
end;
WM_DESTROY:
begin
SysListUnSubClass(WinHandle);
Result := 1;
Exit;
end;
end;
if (Result = 0) then
Result := CallWindowProc(FPrevSysListProc, WinHandle, Msg, wp, lp);
end;
3. Die Farben zuweisen.
Delphi-Quellcode:
procedure UpdateColors(
Handle: HWND);
var
Color1, Color2: COLORREF;
begin
SkinEngine.SplitColorARGB(SkinEngine.SK_INACTIVECAPTION, Alpha, Red, Green, Blue);
Color1 :=
RGB(Red, Green, Blue);
SkinEngine.SplitColorARGB(SkinEngine.SK_ACTIVECAPTION, Alpha, Red, Green, Blue);
Color2 :=
RGB(Red, Green, Blue);
ListView_SetBkColor(
Handle, Color1);
ListView_SetTextBkColor(
Handle, Color1);
ListView_SetTextColor(
Handle, Color2);
end;
Die Weiterleitung der Messagen
Delphi-Quellcode:
procedure TOpenDialog.SysListSubClassProc(var Message: TMessage);
begin
with Message do
begin
case Msg of
WM_DESTROY:
Result := SysListProc(hSysList, Integer(Msg), Message.WPARAM, Message.LPARAM);
WM_ERASEBKGND:
Result := SysListProc(hSysList, Integer(Msg), Message.WPARAM, Message.LPARAM);
end;
if (Result = 0) then
Result := CallWindowProc(FPrevSysListProc, hSysList, Msg, WPARAM, LPARAM)
end;
end;
Das ganze läuft so ab.
Wenn ein Folder geändert wird zerstört sich das Windows selbst.
In dem Fall wird dann WM_DESTROY aufgerufen was zur folge hat das die SubClass entladen wird über UnSubclass.
Damit die Farben aber erhalten bleiben muss man logischerweise die SubClass neu generieren.
Das geht so.
Delphi-Quellcode:
WM_NOTIFY:
begin
case (POFNotify(lp)^.hdr.code) of
CDN_FOLDERCHANGE:
begin
// Handles zurücksetzen
hSysList := 0;
hDefview := 0;
// Handles neu einlesen
hDefview := FindWindowEx(DlgHandle, 0, 'SHELLDLL_Defview', nil);
hSysList := FindWindowEx(hDefview, 0, 'SysListView32', nil);
// Neue SubClass erstellen
if hSysList <> 0 then
SysListSubClass(hSysList);
end;
end;
end;
Das Ergebnis sieht dann so aus.
Die Header mache ich demnächst noch..
Der Dialog kann auch ohne Skins gestartet werden siehe das OverTheTaskBar Projekt.
gruss