![]() |
Menu Ownerdraw
Kann mir jemand sagen wie ich das Menu ändern kann? bzw. wie ich da dran komme.
Die einzige Message die ich ermitteln kann ist WM_PRINTCLIENT. Nur was hat diese mit dem Menu zu tun. Habe leider keine Mail um Rodrigo Ruz mal zu kontaktieren gruss |
AW: Menu Ownerdraw
Wenn man sich den Dialog mithilfe des Tools Window Detective anschaut, dann erkennt man beim Aufklappen des Ansichtsbuttons, dass dynamisch zwei Sachen erzeugt werden (unter Windows 10 1809):
Einmal
Delphi-Quellcode:
und
#32768 (Menu)
Delphi-Quellcode:
. Letzteres stellt den Schatten am rechten und unteren Rand dar.
SysShadow
Ersteres ist wiederum interessant, weil es das Menü ist, wonach du suchst. Wenn wir in den Quelltexten der VCL.Styles.Utils suchen, finden wir in Vcl.Styles.Utils.Menus.pas die Anmeldung des StyleHooks für dieses Menü. ![]() Am Ende der Unit unter initialization befindet sich:
Delphi-Quellcode:
TSysStyleManager.RegisterSysStyleHook('#32768', TSysPopupStyleHook);
In den folgenden Methoden der Hook-Klasse befinden sich wahrscheinlich die Dinge, die du wissen möchtest:
Delphi-Quellcode:
Die Definitionen für die von Microsoft undokumentierten Messages befinden sich als Konstanten ganz oben in der Unit.
procedure MNSELECTITEM(var Message: TMessage); message MN_SELECTITEM;
procedure WMPRINT(var Message: TMessage); message WM_PRINT; procedure WndProc(var Message: TMessage); override; |
AW: Menu Ownerdraw
Zitat:
Werde es damit mal versuchen und melde mich dann wieder hoffentlich mit einer Erfolgsmeldung. :) gruss |
AW: Menu Ownerdraw
Was genau willst du denn wissen?
|
AW: Menu Ownerdraw
Zitat:
Ich Subclass im Moment meine Toolbar auf diesem weg.
Delphi-Quellcode:
Was ich jetzt wissen muss wann bekomme ich das Window Handle um das Menu zu subclassen das ist ja erst bei WM_LBUTTONDOWN bzw. UP sichtbar.
{$REGION 'procedure ToolBarSubClass'}
procedure ToolBarSubClass(WinHandle: HWND); begin FToolBarInstance := MakeObjectInstance(OpenDialog.ToolBarSubClassProc); FPrevToolBarProc := Pointer(GetWindowLongPtr(WinHandle, GWL_WNDPROC)); SetWindowLongPtr(WinHandle, GWL_WNDPROC, LPARAM(FToolBarInstance)); end; {$ENDREGION} {$REGION 'procedure ToolBarUnSubClass'} procedure ToolBarUnSubClass(WinHandle: HWND); begin SetWindowLongPtr(WinHandle, GWL_WNDPROC, LPARAM(FPrevToolBarProc)); FreeObjectInstance(FToolBarInstance); end; {$ENDREGION} {$REGION 'procedure ToolBarSubClassProc'} procedure TSkinOpenSaveDialog.ToolBarSubClassProc(var Message: TMessage); begin with Message do begin case Msg of WM_DESTROY: Result := ToolBarProc(hToolbar, LRESULT(Msg), Message.WPARAM, Message.LPARAM); WM_PAINT: Result := ToolBarProc(hToolbar, LRESULT(Msg), Message.WPARAM, Message.LPARAM); WM_PRINTCLIENT: Result := ToolBarProc(hToolbar, LRESULT(Msg), Message.WPARAM, Message.LPARAM); WM_ERASEBKGND: Result := ToolBarProc(hToolbar, LRESULT(Msg), Message.WPARAM, Message.LPARAM); end; if (Result = 0) then Result := CallWindowProc(FPrevToolBarProc, hToolbar, Msg, WPARAM, LPARAM) end; end; {$ENDREGION} {$REGION 'function ToolBarProc'} function ToolBarProc(WinHandle: HWND; Msg: UINT; wp: WPARAM; lp: LPARAM): LRESULT; stdcall; var hDCTemp: HDC; rc, rw: TRect; ps: TPaintStruct; lpt: TPoint; DC: HDC; hDCBack: HDC; begin Result := 0; case Msg of WM_ERASEBKGND: begin RedrawWindow(WinHandle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN); 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(DC, rc.Right, rc.Bottom, CreateBuffer); // 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); DeleteDC(hDCTemp); if (wp = 0) then EndPaint(WinHandle, ps); Result := 0; Exit; end; WM_DESTROY: begin ToolBarUnSubClass(WinHandle); Result := 1; Exit; end; end; if (Result = 0) then Result := CallWindowProc(FPrevToolBarProc, WinHandle, Msg, wp, lp); end; {$ENDREGION} Vorher kann ich das Handle nicht erreichen. Etwas kompliziert. (Umständlich) Das zeichnen selbst ist das kleinste Problem sobald ich das Handle habe. PS: Überlege noch ob ich diese Subclass verwenden kann oder für das Menu eine neue erstellen muss. Muss es testen. ;) gruss |
AW: Menu Ownerdraw
Guck dir mal GetMenuFromHandle an und die Stellen wo es verwendet wird.
|
AW: Menu Ownerdraw
Zitat:
Delphi-Quellcode:
Innerhalb der ToolbarProc.
WM_PAINT, WM_PRINTCLIENT:
begin HToolBarMenu := HMENU(SendMessage(GetParent(WinHandle), MN_GETHMENU, 0, 0)); if HToolBarMenu <> 0 then ToolBarSubClass(hToolbarMenu); Handle ist immer 0. GetParent(WinHandle) und nur WinHandle immer 0. Kann ich mit den VCL Styles nicht vergleichen. Hmmm... gruss |
AW: Menu Ownerdraw
Messagen die ich bekomme und das Menu siehe im Anhang.. hat bei den VCL Styles nichts mit einem Popupmenu zu tun.
Deshalb scheint MN_GETHMENU nicht das richtige zu sein. gruss |
AW: Menu Ownerdraw
Wo kommt denn der Wert für hToolbar in procedure TSkinOpenSaveDialog.ToolBarSubClassProc(var Message: TMessage); her?
|
AW: Menu Ownerdraw
Zitat:
Delphi-Quellcode:
hMain = Handle der Class #32700 Dialog Box
hToolbar := FindWindowEx(hMain, 0, 'ToolBarWindow32', nil);
GetWindowRect(hToolbar, rc); lpt.x := rc.Left; lpt.y := rc.Top; ScreenToClient(hMain, lpt); MoveWindow(hToolbar, lpt.x, lpt.y, (rc.Right - rc.Left) + 3, rc.Bottom - rc.Top, false); ExStyle := GetWindowLongPtr(hToolbar, GWL_EXSTYLE); ExStyle := ExStyle or WS_EX_TRANSPARENT; SetWindowLongPtr(hToolbar, GWL_EXSTYLE, ExStyle); ToolBarSubClass(hToolbar); gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz