AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi MenuItem neu zeichnen, wenn ImageIndex sich ändert?

MenuItem neu zeichnen, wenn ImageIndex sich ändert?

Ein Thema von SearchBot · begonnen am 11. Sep 2017 · letzter Beitrag vom 14. Sep 2017
Antwort Antwort
Seite 1 von 2  1 2   
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#1

MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 11. Sep 2017, 15:05
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?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.146 Beiträge
 
Delphi 12 Athens
 
#2

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 09:42
Nunja, die Setter von z.B. Caption und ImageIndex machen rein garnichts, um der der Componente die Änderung mitzuteilen.

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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#3

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 13:06
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:
type
  THackedMenuItem = class(TMenuItem);
Dann kann ich auch schreiben
 THackedMenuItem(myMenuItem).MenuChanged(true); und das True sollte ein Rebuid auslösen. Macht es aber trotzdem nicht, zumindest hat es keine Auswirkung. Hab ich was übersehen?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 13:21
Zitat:
Wie kann ich das Menü bei Änderung des ImageIndex selbst neu zeichnen lassen?
Gar nicht.. so lange es geöffnet ist.

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

Geändert von EWeiss (12. Sep 2017 um 13:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.146 Beiträge
 
Delphi 12 Athens
 
#5

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 13:50
Gar nicht.. so lange es geöffnet ist.
MainMenu, nicht PopupMenu
und da ist die erste Ebene immer sichtbar.


Unqualifizierte alternative Antwort: Schmeiß das TMainMenu weg und nimm ein Ribbon.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.

Geändert von himitsu (12. Sep 2017 um 15:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.474 Beiträge
 
Delphi 12 Athens
 
#6

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 15:19
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.146 Beiträge
 
Delphi 12 Athens
 
#7

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 15:33
Haben die da was geändert?

Im XE sieht es so aus:
Delphi-Quellcode:
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;
Demnach bekommt niemand mit, wenn sich der ImageIndex ändert.

Der Teil wird hierbei leider nicht ausgeführt.
Delphi-Quellcode:
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;
Nach der Änderung manuell das Protected MenuChanged aufrufen oder direkt
Delphi-Quellcode:
//MainMenu.UpdateImage; // ist Private, aber geht vielleicht auch ohne
SendMessage(MainMenu.WindowHandle, CM_MENUCHANGED, 0, 0);
DrawMenuBar(MainMenu.WindowHandle);
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.

Geändert von himitsu (12. Sep 2017 um 15:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.474 Beiträge
 
Delphi 12 Athens
 
#8

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 15:38
Demnach bekommt niemand mit, wenn sich der ImageIndex ändert.
In Tokyo ist das FOnChange verlinkt auf das SubItemChanged des Parent (ist ja auch private). Kann man leicht sehen, wenn man im Debugger durchstept.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#9

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 12. Sep 2017, 17:53
Zitat:
MainMenu, nicht PopupMenu
und da ist die erste Ebene immer sichtbar.
Oh.. Entschuldige.

gruss
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#10

AW: MenuItem neu zeichnen, wenn ImageIndex sich ändert?

  Alt 13. Sep 2017, 09:57
Aah cool, so gehts (in Berlin).

Hab im MainMenu1.OnChange gesetzt und da drin geschrieben:
Delphi-Quellcode:
procedure TForm1.MainMenu1Change(Sender: TObject; Source: TMenuItem;
  Rebuild: Boolean);
begin
 SendMessage(MainMenu1.WindowHandle, CM_MENUCHANGED, 0, 0);
 DrawMenuBar(MainMenu1.WindowHandle);
end;
Jetzt geht es ohne weiteres Herumgetrickse...
Danke für Eure Hilfe!!
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:59 Uhr.
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