Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   FileOpenDialog Ownerdraw (https://www.delphipraxis.net/190339-fileopendialog-ownerdraw.html)

EWeiss 25. Sep 2016 12:37


FileOpenDialog Ownerdraw
 
Habe da kleine Probleme mit meinem OwnerDraw FileDialog.

Hintergrund und die Größe des Dialogs habe ich schon verändert. (siehe Anhang)
Meine 1 Frage wäre wie bekomme ich es hin das der Hintergrund der Labels Transparent wird?

Ich verwende die WM_MESSAGE leider ohne erfolg.

Delphi-Quellcode:
    WM_CTLCOLORSTATIC:
      begin
        SetBkMode(wp, TRANSPARENT);
      end;
Zusätzlich habe ich noch versucht über diese Message den Hintergrund einzufärben.
Seltsamer weise wird aber ein anderer Bereich eingefärbt und zwar der von der Toolbox.
Bei beiden setze ich den Backgroundmode auf Transparent .. kein Erfolg.

Delphi-Quellcode:
    WM_CTLCOLORDLG:
      begin
        SkinEngine.SplitColorARGB(SkinEngine.SK_INACTIVECAPTION, Alpha, Red, Green, Blue);
        Color := RGB(Red, Green, Blue);
        SetBkColor(wp, Color);
        SetBkMode(wp, TRANSPARENT);

        if (brush <> 0) then
          DeleteObject(brush);

        brush := CreateSolidBrush(Color);
        SetProp(WinHandle, 'brush', brush);
        result := brush;
        Exit;
      end;
Müsste eigentlich für STATIC Controls wie Labels zuständig sein.

gruss

EWeiss 25. Sep 2016 16:25

AW: FileOpenDialog Ownerdraw
 
Wirklich niemand eine Idee welche Messagen ich da abfangen könnte um den Text transparent zu machen?

Habe jetzt die Combo eingefärbt und meinen Text draufgezeichnet.
Auch das einfärben des Edit funktioniert soweit.

gruss

EWeiss 25. Sep 2016 17:46

AW: FileOpenDialog Ownerdraw
 
Wenn ich nerve bescheid sagen ;)

Hab jetzt die Button ersetzt.
Muss nur noch das Tastaturkürzel (Unterstrich) entfernen.

Irgendwann werde ich auch noch das Problem mit der Transparenz lösen.
Wenn mir niemand helfen kann.

gruss

EWeiss 26. Sep 2016 12:56

AW: FileOpenDialog Ownerdraw
 
OK das mit den Transparenten Static Texten hat sich erledigt.
ein

Delphi-Quellcode:
GetStockObject(NULL_BRUSH);


hat's gebracht.
Ist noch genug zu tun aber zumindest schon eine Anfang.

Delphi-Quellcode:
    WM_CTLCOLORSTATIC:
      begin
        SkinEngine.SplitColorARGB(SkinEngine.SK_INACTIVECAPTION, Alpha, Red, Green, Blue);
        Color := RGB(Red, Green, Blue);

        SetBkMode(wp, TRANSPARENT);
        SetTextColor(wp, Color);
        result := GetStockObject(NULL_BRUSH);
        Exit;
      end;
gruss

Luckie 26. Sep 2016 13:30

AW: FileOpenDialog Ownerdraw
 
Zitat:

Zitat von EWeiss (Beitrag 1348804)
Muss nur noch das Tastaturkürzel (Unterstrich) entfernen.

Warum willst du die Bedienbarkeit wieder künstlich verktüppeln?

EWeiss 26. Sep 2016 13:48

AW: FileOpenDialog Ownerdraw
 
Zitat:

Zitat von Luckie (Beitrag 1348842)
Zitat:

Zitat von EWeiss (Beitrag 1348804)
Muss nur noch das Tastaturkürzel (Unterstrich) entfernen.

Warum willst du die Bedienbarkeit wieder künstlich verktüppeln?

Tue ich nicht ;)
Mal schaun ob ich den lassen kann hatte vorher ein Problem das da immer ein "&" angezeigt wurde.
An der Funktionalität hat sich nichts geändert auch wenn man den Strich nicht sieht.

gruss

EWeiss 28. Sep 2016 04:50

AW: FileOpenDialog Ownerdraw
 
Das ist der letzte Status..
Das SysListView32 ist noch nicht angepasst.
Mal sehn ob ich das auch noch irgendwie schaffe.

Und die Toolbar ist noch nicht fertig.
Links im Panel wird dann der MP3 tag angezeigt.

gruss

EWeiss 11. Okt 2016 13:39

AW: FileOpenDialog Ownerdraw
 
Nur mal zur Info was für ein Aufwand die ToolBarWindow32 Transparent zu bekommen.

Erst mal das Fenster Subclassen.

Delphi-Quellcode:
// Fenster suchen
hToolbar := FindWindowEx(DlgHandle, 0, 'ToolBarWindow32', nil);
// ExeStyle verändern zu Transparent
ExStyle := GetWindowLong(hToolbar, GWL_EXSTYLE);
ExStyle := ExStyle or WS_EX_TRANSPARENT;
SetWindowLong(hToolbar, GWL_EXSTYLE, ExStyle);
// Subclass erstellen
ToolBarSubClass(hToolbar);
Erstellen der SubClass
Delphi-Quellcode:
procedure ToolBarSubClass(WinHandle: HWND);
begin

  FToolBarInstance := MakeObjectInstance(OpenDialog.ToolBarSubClassProc);

  FPrevToolBarProc := Pointer(GetWindowLong(WinHandle, GWL_WNDPROC));
  SetWindowLong(WinHandle, GWL_WNDPROC, Integer(FToolBarInstance));
end;

procedure ToolBarUnSubClass(WinHandle: HWND);
begin

  SetWindowLong(WinHandle, GWL_WNDPROC, Integer(FPrevToolBarProc));
  FreeObjectInstance(FToolBarInstance);
end;
Weiterleiten der zur Verfügung stehenden Messagen.
Delphi-Quellcode:
procedure TOpenDialog.ToolBarSubClassProc(var Message: TMessage);
begin

  with Message do
  begin
    case Msg of
      WM_DESTROY:
        Result := ToolBarProc(hToolbar, Integer(Msg), Message.WPARAM, Message.LPARAM);
      WM_PAINT:
        Result := ToolBarProc(hToolbar, Integer(Msg), Message.WPARAM, Message.LPARAM);
      WM_PRINT:
        Result := ToolBarProc(hToolbar, Integer(Msg), Message.WPARAM, Message.LPARAM);
      WM_PRINTCLIENT:
        Result := ToolBarProc(hToolbar, Integer(Msg), Message.WPARAM, Message.LPARAM);
      WM_ERASEBKGND:
        Result := ToolBarProc(hToolbar, Integer(Msg), Message.WPARAM, Message.LPARAM);
    end;
    if (Result = 0) then
      Result := CallWindowProc(FPrevToolBarProc, hToolbar, Msg, WPARAM, LPARAM)

  end;
end;
ToolBarProc
Delphi-Quellcode:
function ToolBarProc(WinHandle: HWND; Msg: UINT; wp: WPARAM; lp: LPARAM): longint; stdcall;
var
  hTmpBmp: HBITMAP;
  hDCTemp: HDC;
  hDCMem: HDC;
  rc, rw: TRect;
  ps: TPaintStruct;
  nResult: longint;
  lpt: TPoint;
  DC: HDC;
  hDCBack: HDC;

begin
  Result := 0;

  case Msg of

    WM_ERASEBKGND:
      begin
        SkinEngine.FInvalidateRect(Winhandle, False);
        Result := 1;
        exit;
      end;

    WM_PAINT, WM_PRINTCLIENT:
      begin
        GetClientRect(WinHandle, rc);

        if (wp = 0) then
        begin
          BeginPaint(WinHandle, ps);
          DC := ps.HDC;
        end
        else
          DC := wp;

        // Double Buffer erstellen
        hDCTemp := SkinEngine.DoubleBuffer(ps.HDC, rc.Right, rc.Bottom, CreateBuffer);
        // Kompatiblen DC erstellen
        hDCMem := CreateCompatibleDC(hDCTemp);
        // Compatibles Bitmap erstellen
        hTmpBmp := CreateCompatibleBitmap(DC, rc.Right, rc.Bottom);
        // Object Selektieren
        SelectObject(hDCMem, hTmpBmp);
        // hintergrund aktualisieren
        SendMessage(WinHandle, WM_ERASEBKGND, hDCMem, 0);

        nResult := CallWindowProc(FPrevToolBarProc, WinHandle, Msg, hDCMem, lp);
        //Transparent Blitten
        TransparentBlt(DC, 0, 0, rc.Right, rc.Bottom, hDCMem, 0, 0, rc.Right, rc.Bottom, 0);
        // Objecte freigeben
        DeleteDC(hDCMem);
        DeleteObject(hTmpBmp);
        // Dimensionen der ToolBar auslesen
        GetWindowRect(WinHandle, rw);
        lpt.x := rw.Left;
        lpt.y := rw.Top;
        ScreenToClient(SKDialogHandle, lpt);

        // Hintergrund Kopieren
        hDCBack := CreateCompatibleDC(hDCTemp);
        SelectObject(hDCBack, SkinEngine.GetBackBitmap(SKDialogHandle));
        // Toolbar Hintergrund mit dem Parent Hintergrund füllen
        BitBlt(hDCTemp, 0, 0, rc.Right, rc.Bottom, hDCBack, lpt.x, lpt.y, SRCCOPY);
        // Resourcen freigeben
        DeleteDC(hDCBack);
        // Double Buffer freigeben
        SkinEngine.DoubleBuffer(0, 0, 0, DestroyBuffer);

        if (wp = 0) then
          EndPaint(WinHandle, ps);

        Result := nResult;
        Exit;
      end;

    WM_DESTROY:
      begin
        ToolBarUnSubClass(WinHandle);
        Result := 1;
        Exit;
      end;

  end;
  if (Result = 0) then
    Result := CallWindowProc(FPrevToolBarProc, WinHandle, Msg, wp, lp);
end;
Das Ergebnis unten im Bild.
Vielleicht such ja mal jemand etwas ähnliches..

Alle Controls sind jetzt gesubclassed bis auf die untere Combo und das Edit darüber.
Feinschliff kommt später. :)

gruss

EWeiss 19. Mai 2017 03:14

AW: FileOpenDialog Ownerdraw
 
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

EWeiss 26. Mai 2017 20:24

AW: FileOpenDialog Ownerdraw
 
So! ;)
Endlich fertig der Mist..

Das Problem mit der unteren Combo war nicht so einfach zu analysieren\lösen.
Es lag daran das eine einmal erstellte Combo keine neuen Style mehr annimmt. (Da muss man aber erst mal drauf kommen)
Das hatte dann zur folge das in DrawItem die Combo niemals aufgerufen wurde.

Ich musste also eine vollständige Copy der Vorhandenen mit dem neuen Style erstellen und die alte löschen.

Die Header dann mit Bitmaps zu hinterlegen war dann etwas einfacher.
Die Hintergrundfarben sind noch nicht so das wahre muss mir da noch was überlegen wie ich diese übergebe.
Im Moment werden diese mit der Aktiven und Inaktiven Farbe des Fonts übergeben.


gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz