![]() |
MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Hallo,
ich habe ein optisches Problem. Im MainMenu habe ich sowas wie Status-Anzeigen angelegt. Mit der ImageList habe ich 4 "LEDs" (grau, grün, gelb, rot), die ich je nach Situation einschalte. Startet die Anwendung, werden die "LED" grau gezeigt. Setze ich jetzt ImageIndex:=1 , soll neben dem MenuItem.Caption die Grüne "LED" angezeigt werden. Das funktioniert auch intern ganz gut - nur wird das Menü erst dann neu gezeichnet, wenn ich mit dem Mauszeiger drüberfahre. Ich kann ja von Anwender nicht erwarten, immer mit dem Mauszeiger drüber zu gehen, um die Anzeige zu aktualisieren. Es gibt irgendwie kein Event dafür, auch mit Update, Refresh, Invalidate funktioniert es nicht. Einzig beim komplett neu zeichnen der Anwendung wird auch das Menü neu gezeichnet, aber das flackert blöd... Wie kann ich das Menü bei Änderung des ImageIndex selbst neu zeichnen lassen? |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Nunja, die Setter von z.B. Caption und ImageIndex machen rein garnichts, um der der Componente die Änderung mitzuteilen. :wall:
Im Allgemeinem sucht daher man zuerst nach so einer Methode, hier im Item oder im Menü, aber finden wirst du sowas nur in der Form. (ganze Form neu zeichnen lassen dürfte dein Problem also lösen) > Repaint, Refresh, Update oder Invalidate heißen die meistens. Falls garnichs funktionier: Es gibt im TMenuItem ein RebuildHandle, was eigentlich das Gewünschte bewirken würde, aber da kommst du nicht direkt ran. (ist Private) Aufgerufen wird es z.B. beim Add/Remove, also wenn du mal kurz ein MenuItem im Root einfügst und gleich wieder löschst. |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Ne, nix geht.
Aber wenn man mit der Maus drüber fährt, malt es ein Hover um das Item, dadurch wird dann auch die "LED" korrekt gezeichnet. Wenn man nun irgendwie dies durch ein Postmessage oder so auslösen könnte? Ich hab irgendwoher sowas eingebaut:
Delphi-Quellcode:
Dann kann ich auch schreiben
type
THackedMenuItem = class(TMenuItem);
Delphi-Quellcode:
und das True sollte ein Rebuid auslösen. Macht es aber trotzdem nicht, zumindest hat es keine Auswirkung. Hab ich was übersehen?
THackedMenuItem(myMenuItem).MenuChanged(true);
|
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Zitat:
Es sei denn du erstellst ein eigenes das als Basis ein Normales Fenster erzeugt. Das ist einer der gründe warum ich ein eigenes PopUpMenu erstellt habe wegen diverser Einschränkungen. Es ist nun mal so das ein Menu kein Handle hat somit kannst du auch keine Messagen an das NICHT vorhandene Fenster(Handle) schicken. Da kannst du versuchen zu zaubern wie du willst. gruss |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Zitat:
und da ist die erste Ebene immer sichtbar. :zwinker: Unqualifizierte alternative Antwort: Schmeiß das TMainMenu weg und nimm ein Ribbon. :stupid: |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Das funktioniert doch ganz hervorragend (sowohl im obersten Level, als auch in den Subleveln):
Delphi-Quellcode:
type
TForm210 = class(TForm) MainMenu1: TMainMenu; ImageList1: TImageList; Test1: TMenuItem; Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private end; var Form210: TForm210; implementation {$R *.dfm} procedure TForm210.Timer1Timer(Sender: TObject); { ImageList hat nur zwei Bitmaps } begin Test1.ImageIndex := 1 - Test1.ImageIndex; end; |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Haben die da was geändert?
Im XE sieht es so aus:
Delphi-Quellcode:
Demnach bekommt niemand mit, wenn sich der ImageIndex ändert.
procedure TMenuItem.SetImageIndex(Value: TImageIndex);
begin if Value <> FImageIndex then begin FImageIndex := Value; MenuChanged(True); end; end; procedure TMenuItem.MenuChanged(Rebuild: Boolean); var Source: TMenuItem; begin if (Parent = nil) and (Owner is TMenu) then Source := nil else Source := Self; if Assigned(FOnChange) then FOnChange(Self, Source, Rebuild); end; Der Teil wird hierbei leider nicht ausgeführt.
Delphi-Quellcode:
Nach der Änderung manuell das Protected MenuChanged aufrufen oder direkt
procedure TMainMenu.MenuChanged(Sender: TObject; Source: TMenuItem; Rebuild: Boolean);
var NeedUpdate: Boolean; begin if (FWindowHandle <> 0) then begin NeedUpdate := UpdateImage; // check for changes before CM_MENUCHANGED does if Source = nil then SendMessage(FWindowHandle, CM_MENUCHANGED, 0, 0); if NeedUpdate then DrawMenuBar(FWindowHandle); end; inherited MenuChanged(Sender, Source, Rebuild); end;
Delphi-Quellcode:
//MainMenu.UpdateImage; // ist Private, aber geht vielleicht auch ohne
SendMessage(MainMenu.WindowHandle, CM_MENUCHANGED, 0, 0); DrawMenuBar(MainMenu.WindowHandle); |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Zitat:
|
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Zitat:
gruss |
AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?
Aah cool, so gehts (in Berlin).
Hab im MainMenu1.OnChange gesetzt und da drin geschrieben:
Delphi-Quellcode:
Jetzt geht es ohne weiteres Herumgetrickse... :thumb:
procedure TForm1.MainMenu1Change(Sender: TObject; Source: TMenuItem;
Rebuild: Boolean); begin SendMessage(MainMenu1.WindowHandle, CM_MENUCHANGED, 0, 0); DrawMenuBar(MainMenu1.WindowHandle); end; Danke für Eure Hilfe!! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 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 by Thomas Breitkreuz