![]() |
popupmenu-einträge designen
wie kann ich ein tmenuitem vom popup menu farbig bearbeiten?
mit customdraw oder so? ich will halt den win98 grauen rand durch was anderes ersetzen z.b. xp-style |
Re: popupmenu-einträge designen
Ja, "OnCustomDraw" ist der richtige Ansatz.
|
Re: popupmenu-einträge designen
Liste der Anhänge anzeigen (Anzahl: 1)
ja mit OnCustomDraw geht des aber da krieg ich ja ein TCanvas zum malen aber wenn ich in des canvas was male(mit dem gegebenen parameter aRect) dann kann ich nur den eintrag selber übermalen, nicht aber der Win98 3D-grau rand von dem ganzen popupmenü -> hab ein Beispiel angehängt
|
Re: popupmenu-einträge designen
Liste der Anhänge anzeigen (Anzahl: 1)
Dazu hat mir Hagen Reddmann im Entwicklerforum mal weitergeholfen. Von ihm stammt der Code der folgenden Unit:
Delphi-Quellcode:
Jetzt muss ich nur erst mal gucken, wie das benutzt wurde ... *kram kram* ... Hm, es ist schon ein Weilchen her, darum das folgende ohne Gewähr:
{ Code-Copyright (c) 2001, Hagen Reddmann }
unit flatmenu; interface uses Windows, SysUtils, Messages, Graphics; // // functions // function InitFlatMenuHook: boolean; function FreeFlatMenuHook: boolean; // // variable to handle the menu from the app // var mnuFrameColor : TColor = clGrayText; mnuBgColor : TColor = clMenu; mnuLeftbarColor : TColor = clMenu; HookActive : integer = 0; WinME, Win2k : boolean; implementation { -- procs ------------------------------------------------------------------- } var FHook: hHook = 0; FAtom: TAtom = 0; // // hook proc // function CallWndProcHook(Code: Integer; wParam: WParam; lParam: LParam): LResult; stdcall; // // Win2k, WinME // procedure MenuNCPaint(Wnd: hWnd; DC: hDC; IsClient: Boolean); var D : hDC; bg, frame : hBrush; R : TRect; P : TPoint; begin if(DC = 0) then D := GetWindowDC(Wnd) else D := DC; if(D <> 0) then try bg := CreateSolidBrush(ColorToRGB(mnuBgColor)); frame := CreateSolidBrush(ColorToRGB(mnuFrameColor)); try if(IsClient) then SetWindowOrgEx(D, 0, 0, @P); SelectClipRgn(D, 0); GetWindowRect(Wnd, R); OffsetRect(R, -R.Left, -R.Top); FrameRect(D, R, frame); InflateRect(R, -1, -1); FrameRect(D, R, bg); InflateRect(R, -1, -1); FrameRect(D, R, bg); finally if(IsClient) then SetWindowOrgEx(D, P.X, P.Y, @P); DeleteObject(frame); DeleteObject(bg); end; finally if(DC = 0) then ReleaseDC(Wnd, D); end; end; function IsPopupMenu(Wnd: hWnd): Boolean; var N : array[0..8] of Char; begin Result := (HookActive > 0) and IsWindow(Wnd) and ((GetClassLong(Wnd, GCW_ATOM) = 32768) or (StrLIComp(@N, '#32768', GetClassName(Wnd, @N, SizeOf(N))) = 0)); end; // // Win9x/NT // function DoNCPaint(Wnd: hWnd): Boolean; var DC: hDC; bg, frame: hBrush; R: TRect; begin Result := False; DC := GetWindowDC(Wnd); if(DC <> 0) then try GetWindowRect(Wnd, R); OffsetRect(R, -R.Left, -R.Top); bg := CreateSolidBrush(ColorToRGB(mnuBgColor)); frame := CreateSolidBrush(ColorToRGB(mnuFrameColor)); try FrameRect(DC, R, frame); InflateRect(R, -1, -1); FrameRect(DC, R, bg); InflateRect(R, -1, -1); FrameRect(DC, R, bg); Result := True; finally DeleteObject(frame); DeleteObject(bg); end; finally ReleaseDC(Wnd, DC); end; end; procedure MarkWindowAsPopup(Wnd: hWnd); begin if (HookActive > 0) and (IsWindow(Wnd)) and (GetProp(Wnd, MakeIntResource(FAtom)) <> MainThreadID) then SetProp(Wnd, MakeIntResource(FAtom), MainThreadID); end; begin // // hook functions for Win9x/NT // if(not(WinME)) and (not(Win2k)) then begin if lParam <> 0 then with PCWPStruct(lParam)^ do begin case Message of wm_NCPaint : if(HookActive = 1) then begin if(GetProp(hWnd, MakeIntResource(FAtom)) = MainThreadID) and DoNCPaint(hWnd) then begin Message := wm_Null; Result := 0; exit; end; end; wm_NCDestroy, wm_Destroy : if GetProp(hWnd, MakeIntResource(FAtom)) = MainThreadID then RemoveProp(hWnd, MakeIntResource(FAtom)); wm_InitMenuPopup: MarkWindowAsPopup(FindWindow(MakeIntResource(32768), nil)); wm_Create : with PCreateStruct(lParam)^ do // ist eine #POPUP# class if(lpszClass = MakeIntResource(32768)) then MarkWindowAsPopup(hWnd); end; end; Result := CallNextHookEx(FHook, Code, wParam, lParam); end // // hook functions for ME and 2000 // else begin Result := CallNextHookEx(FHook, Code, wParam, lParam); if(lParam <> 0) then with PCWPStruct(lParam)^ do case Message of wm_PrintClient: if IsPopupMenu(hWnd) then MenuNCPaint(hWnd, wParam, True); wm_EraseBkGnd : if IsPopupMenu(hWnd) then MenuNCPaint(hWnd, 0, False); end; end; end; { -- hook functions ---------------------------------------------------------- } // // init hook // function InitFlatMenuHook: boolean; begin // // unregister first // if(FHook <> 0) then FreeFlatMenuHook; // // now, play it again, Sam! // if(not(WinME)) and (not(Win2k)) then FAtom := GlobalAddAtom(PChar(Format('POPUPMENU_IDENTIFY_%0.8x', [MainThreadID]))); FHook := SetWindowsHookEx(WH_CALLWNDPROC, CallWndProcHook, 0, MainThreadID); // // function´s result // Result := (FHook <> 0); end; // // free hook // function FreeFlatMenuHook: boolean; begin if(FHook <> 0) then begin Result := UnhookWindowsHookEx(FHook); if(not(WinME)) and (not(Win2k)) then GlobalDeleteAtom(FAtom); end else Result := false; end; initialization WinME := ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and (Win32MajorVersion = 4) and (Win32MinorVersion >= 90)); Win2k := ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion = 5) {and (Win32MinorVersion = 1)}); finalization WinME := false; Win2k := false; end. 1. Die Unit ins Projekt einbinden und dann die gewünschten Farben setzen, bspw.
Delphi-Quellcode:
Damit gestaltest du den Hintergrund und den Rahmen (um den es dir ja hauptsächlich geht). Die beiden Variablen stammen aus o.g. Unit. Ich habe die damals herausgezogen (public), weil man in meinem Programm das Aussehen (= die Farbe) des Menüs ändern konnte. Demzufolge musste ich natürlich auch den Hintergrund und Rahmen anpassen.
flatmenu.mnuBgColor := clRed;
flatmenu.mnuFrameColor := clGreen; 2. Dann aufrufen:
Delphi-Quellcode:
3. Wenn du das Programm beendest, dann
InitFlatMenuHook;
Delphi-Quellcode:
Deinen Dank richtest du bitte an Hagen hier in diesem Forum.
FreeFlatMenuHook;
Zum Beweis noch das Foto meines Programms, und das ist Windows 98! |
Re: popupmenu-einträge designen
Funktioniert! Danke!
Allerdings musste ich noch
Delphi-Quellcode:
aufrufen.
HookActive:=1;
Kannst du mir nochmal den Code posten, mit dem du dein Popupmenü mit XP-Style gemacht hast? (Ich krieg das irgendwie nicht hin :( ) |
Re: popupmenu-einträge designen
Hi,
bei funktioniert es leider nicht. Wo genau muß ich denn flatmenue.mnuBgColor := clRed; flatmenue.mnuFrameColor := clGreen; reinpacken. Ich habe es jetzt in formshow Vielen Dank Das S |
Re: popupmenu-einträge designen
:shock: Ist das ´ne alte Gurke ... Nee, nicht du, Das S, sondern der Beitrag! :lol: Da musste ich doch tatsächlich in meinem Archiv kramen. Um deine Frage zu beantworten, ich habe das in meinem Programm an drei verschiedenen Stellen aufgerufen. Es handelt sich dabei um eine Funktion, die nur die Aufgabe hatte, die Farben im Programm neu einzustellen. Darunter eben auch die Menüfarben. Und diese Funktion habe ich aufgerufen:
1. Beim Programmstart. Logisch. :) 2. Beim Bearbeiten der Nachricht WM_SYSCOLORCHANGED. Das bedeutet, der Anwender hat irgendwie die eingestellten Systemfarben verändert, und daher lädt das Menü die Farben neu. 3. Bei der speziellen XP-Nachricht WM_THEMECHANGED, was bedeutet, dass der User das Theme von Windows geändert hat, wobei sich ebenfalls die Farben ändern können. Ich habe aber schon ewig nichts mehr mit diesem Menüdesign gemacht. Mittlerweile ist mir die Funktionalität wichtiger. Hast du es schon mal mit der ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:25 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