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 ohne ganzes Menü neu zu zeichnen
Thema durchsuchen
Ansicht
Themen-Optionen

MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

Ein Thema von StephanR · begonnen am 1. Mai 2018 · letzter Beitrag vom 2. Mai 2018
Antwort Antwort
Seite 1 von 2  1 2      
StephanR

Registriert seit: 1. Mai 2018
6 Beiträge
 
#1

MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 1. Mai 2018, 10:51
Hallo DPler,

in meinem aktuellen Projekt muss ich während ein PopUpMenü bereits geöffnet ist und dargestellt wird den Caption mehrerer MenuItems ändern.
Die Änderung selbst ist weiters unproblematisch, allerdings löst das Ändern der Caption das Kommando MenuChanged(true) aus, welches dann das
ganze Menü neuzeichnet. Dabei wird aber bei jeder Änderung das PopUp geschlossen und neu geöffnet, was ganz nervig "flackert".
Ich habe daraufhin eine Childklasse erstellt (ThackedMenuItem) und darin die SetCaption-Funktion so überschrieben, dass ich MenuChanged blockieren kann.

Leider habe ich bislang keinen Weg gefunden, trotzdem das Neuzeichnen des jeweiligen MenuItem auszulösen (und nur dieses). Erst wenn der Nutzer mit der Maus darüberfährt wird über das Hover-Ereignis der Menüeintrag neu gezeichnet.

Gibt es irgend einen anderen Weg, das Neuzeichnen auch ohne Mausereignis auszulösen? Invalidate etc. gibt es ja leider nicht, da TMenuItem kein zeichenbares Control ist... Kann man Hover oder Mouseleave an ein MenuItem senden, so dass dann neu gezeichnet wird?

Alternativ habe ich versucht, in der SetCaption-Funktion die Routine DrawItem aufzurufen (ist OwnerDraw). Dabei habe ich es aber bislang nicht geschafft den dazugehörigen Canvas des Menüfensters zu ermitteln. Somit klappt das neu selber darüber zeichnen bislang nicht.

Es wäre toll, wenn Ihr für eine der beiden Varianten eine Lösung kennen solltet und diese hier posten könntet.

Vielen Dank
Stephan
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 05:53
if (PDis.itemAction and ODA_DRAWENTIRE) <> 0 then

und vielleicht noch etwas mit dem DC rumspielen.
GetClipBox(PDis.HDC, Rect);

Aber ohne WM_DRAWITEM geht wohl gar nichts.

gruss
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 08:25
Hallo,
hilft vielleicht EnableMenuItem (oder MnuItem.Enabled)?
Das einmal auf False und dann wieder auf True zurück.
Das müsste ja eigentlich das Neuzeichnen aufrufen.

Das Popupmenu wird zumindestens schon mal nicht neu aufgebaut.
Heiko

Geändert von hoika ( 2. Mai 2018 um 08:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 08:44
Nur mal aus Neugier:
Warum Items neu zeichnen?

Was hat sich den geändert, was nicht in der MS vor dem öffnen nicht schon bekannt war?
  Mit Zitat antworten Zitat
StephanR

Registriert seit: 1. Mai 2018
6 Beiträge
 
#5

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:04
if (PDis.itemAction and ODA_DRAWENTIRE) <> 0 then

und vielleicht noch etwas mit dem DC rumspielen.
GetClipBox(PDis.HDC, Rect);

Aber ohne WM_DRAWITEM geht wohl gar nichts.

gruss
Hallo EWeiss,

um ein WM_DRAWITEM manuell auszulösen benötige ich aber wenigstens das Handle des Canvas, auf dem das Menü(item) gezeichnet werden soll. Und genau das habe ich bislang nicht herausgefunden. Nächstes Problem wäre dann die genaue Position des Rect, indem das Menuitem gezeichnet werden soll. Aber das könnte ich zur not noch ausrechnen...

Viele Grüße
Stephan
  Mit Zitat antworten Zitat
StephanR

Registriert seit: 1. Mai 2018
6 Beiträge
 
#6

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:06
Hallo,
hilft vielleicht EnableMenuItem (oder MnuItem.Enabled)?
Das einmal auf False und dann wieder auf True zurück.
Das müsste ja eigentlich das Neuzeichnen aufrufen.

Das Popupmenu wird zumindestens schon mal nicht neu aufgebaut.
Hallo hoika,

leider löst das Ändern von Enabled wieder MenuChanged aus und das schließt und öffnet das PopUp zur Aktualisierung.
Genau das möchte ich umgehen...

VG
Stephan
  Mit Zitat antworten Zitat
StephanR

Registriert seit: 1. Mai 2018
6 Beiträge
 
#7

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:14
Zur Erläuterung, warum ich denn einzelne Menuitems aktualisieren möchte/muss.

Bei meinem Projekt handelt es sich um eine Software für Sportwettbewerbe, die auf mehreren Clients im Netzwerk parallel betrieben wird. Die Daten liegen dabei zentral auf einem Fileserver.
Das Menü, welches zum Öffnen der einzelnen Wettbewerbe verwendet wird, soll neben dem Namen des einzelnen Wettbewerbs zu jedem Wettbewerb den aktuellen Status anzeigen (x Starter gemeldet, Wettbewerb in der x. Runde mit y Startern,...). Das Sammeln dieser Daten ist jedoch im Netzwerkbetrieb so langsam, dass der Nutzer ziemlich lange auf das Öffnen des Menüs warten müsste (sollte ich diese Daten erst Sammeln und dann das Menü anzeigen).
Deshalb habe ich das Zusammenstellen dieser Daten in einen parallelen Thread ausgelagert, der noch läuft während das Menü bereits geöffnet ist. Das Menü ist somit zunächst nur mit den Namen der Wettbewerbe bestückt und wenn dann die Statusdaten bereitstehen sollen diese mit angezeigt werden.
Aktuell geschieht diese Aktualisierung/das Neuzeichnen des MenuItems durch die Bewegung der Maus über die einzelnen Menüpunkte (Hover-Ereignis).
Dies ist aber nicht sonderlich intuitiv... Deshalb möchte ich gerne das Neuzeichnen der MenuItems anstoßen, sobald die jeweilige Info verfügbar wurde.

VG
Stephan
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#8

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:14
if (PDis.itemAction and ODA_DRAWENTIRE) <> 0 then

und vielleicht noch etwas mit dem DC rumspielen.
GetClipBox(PDis.HDC, Rect);

Aber ohne WM_DRAWITEM geht wohl gar nichts.


gruss
Hallo EWeiss,

um ein WM_DRAWITEM manuell auszulösen benötige ich aber wenigstens das Handle des Canvas, auf dem das Menü(item) gezeichnet werden soll. Und genau das habe ich bislang nicht herausgefunden. Nächstes Problem wäre dann die genaue Position des Rect, indem das Menuitem gezeichnet werden soll. Aber das könnte ich zur not noch ausrechnen...

Viele Grüße
Stephan
hMenuWnd := WindowFromDC(PDis.HDC);
und

PDis.hwndItem
Bei dem Rect musst du gar nichts berechnen diesen gibt dir
GetClipBox zurück.. und zwar den vom selektierten HDC


gruss

Geändert von EWeiss ( 2. Mai 2018 um 09:25 Uhr)
  Mit Zitat antworten Zitat
StephanR

Registriert seit: 1. Mai 2018
6 Beiträge
 
#9

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:48
hMenuWnd := WindowFromDC(PDis.HDC);
und

PDis.hwndItem
Bei dem Rect musst du gar nichts berechnen diesen gibt dir
GetClipBox zurück.. und zwar den vom selektierten HDC


gruss[/QUOTE]

Hallo EWeiss,

Danke für Deine schnelle Antwort. Kannst Du mir bitte noch erklären, worauf genau sich "PDis" bezieht?
Ich steh da nämlich gerade etwas auf dem Schlauch...
Aktuell hatte ich vor, in meiner Child-Routine des SetCaption eine WM_DRAW-Message zusammenzubauen beziehungsweise DrawItem direkt aufzurufen.
Dort habe ich zwar Zugriff auf das Handle des TMenuItem aber PDis und sein HDC sind mir dort nicht bekannt.
Vielleicht kannst Du mir etwas mehr Info rund um Deinen Tipp geben

Vielen Dank
Stephan
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#10

AW: MenuItem neu zeichnen ohne ganzes Menü neu zu zeichnen

  Alt 2. Mai 2018, 09:55
Sollte selbst erklärend sein.

  PDis: PDrawItemStruct absolute lP; Initialisierung..

Delphi-Quellcode:
    WM_DRAWITEM:
      begin
        PDis := Pointer(lP);
        case PDis^.CtlType of
          ODT_MENU: // 1 Ownerdrawn menu item
            begin
              hMenuWnd := WindowFromDC(PDis.HDC);

gruss
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

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 15:06 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