Einzelnen Beitrag anzeigen

EWeiss
(Gast)

n/a Beiträge
 
#8

AW: FileOpenDialog Ownerdraw

  Alt 11. Okt 2016, 13:39
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

Geändert von EWeiss (11. Jul 2019 um 15:45 Uhr)
  Mit Zitat antworten Zitat