Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Handle-konflikt (InsertMenu) (https://www.delphipraxis.net/46471-handle-konflikt-insertmenu.html)

sECuRE 25. Mai 2005 13:09


Handle-konflikt (InsertMenu)
 
Hi,

ich habe eine Anwendung, in der ich mehrere TMDIChilds öffne, wieviele das genau sind, hängt vom Anwender ab. In jedem dieser MDIChilds erweitere ich das Menü mittels InsertMenu() um einen Punkt "Schriftart". Diesem gebe ich ein Handle welches sich aus WM_USER und der Anzahl der bisher vergebenen Handles zusammensetzt. Des weiteren speichere ich in einem Array, welches Handle zu welcher Form gehört, damit ich nachher damit etwas anfangen kann.

Das Problem: anscheinend benutzt Delphi oder Windows (oder beide?) eines "meiner" Handles, wenn ich zum Beispiel ein Popupmenü benutze, kommt der Schriftart-Dialog - welcher Eintrag bei welchem Popupmenü variiert, je nach Uptime des Systems, offenen Anwendungen etc... Daher meine Vermutung, dass hier ein Handle-"Konflikt" vorliegt.

Gibt es eine Möglichkeit, einen Bereich (sagen wir WM_USER..WM_USER+1024) für mich zu "reservieren", "sperren" oder sonstwie frei zu halten? Oder sollte ich die Sache ganz anders angehen?

Danke & cu

PS: Ich dachte, WM_USER sei ein Basishandle für eigene Handles, oder täusche ich mich da?

brechi 25. Mai 2005 13:17

Re: Handle-konflikt (InsertMenu)
 
http://msdn.microsoft.com/library/de...dowmessage.asp
schau mal da nach

jim_raynor 25. Mai 2005 13:24

Re: Handle-konflikt (InsertMenu)
 
Du täuscht dich. WM_USER ist der Startwert für eigene Windows-Nachrichten. Nicht für Handles. Normalerweise kannst du die Handles eigentlich garnicht selbst festlegen, da diese nur Windows intern verwaltet werden.

Es gibt bei TMainMenu ne Eigenschaft Merge oder irgendwie sowas. Damit wird automatisch das Menü des Mainformulars mit dem Menü des aktiven MDI-Childs zusammengeführt. Heisst, du kannst die MDI-Child spezifischen Aktionen in ein TMainMenu des Childs machen. Wird das Child aktiv, wird automatisch das Menu in das des Hauptfensters eingepflegt. Eventuell ersparst du dir dadurch eine menge Verwaltungsaufwand. Leider habe ich nicht verstanden, warum du für jedes MDI-Fenster ein neues Menü erstellst.

sECuRE 25. Mai 2005 13:35

Re: Handle-konflikt (InsertMenu)
 
Hi,

@brechi: Danke für den Link

@jim_raynor: Ich erstelle für jedes Fenster ein neues Handle, damit ich anschließend in meiner WndProc-Procedur erkennen kann, in welchem Fenster das Menü aufgerufen wurde.
Ich habe mir Merge eben angesehen, allerdings glaube ich, dass du es etwas anders meinst als ich ;) Ich möchte nicht im MainForm mit dem MDIChild etwas machen, sondern für jedes MDIChild im Systemmenü (das, welches erscheint, wenn man links oben auf das Icon klickt, mit Schließen/Maximieren/etc...) einen Menüpunkt hinzufüge. Dazu ist ein PopupMenu mehr geeignet, ich hab allerdings keine Möglichkeit außer InsertMenu gefunden um das Systemmenü zu erweitern.

Danke & cu

jim_raynor 25. Mai 2005 13:49

Re: Handle-konflikt (InsertMenu)
 
Da hast natürlich recht. Merge nützt dir in dem Fall nicht. Was mir nicht ganz klar ist, was du mit Handle meinst? Wie gesagt, die Handles werden nur von Windows vergegeben und ich kenne keine Funktion, mit der du ein Objekt mit einem bestimmten Handle anlegen kannst. Deshalb die Verwirrung.

Meinst du mit "Handle" den Paramater uIDNewItem von InsertMenu? Wenn ja, dass ist das ID des Menüeintrages und nicht das Handle ;)

Wenn ich dich jetzt richtig verstanden habe, fügst du in das Systemmenü des Childs immer ein Item ein, oder? Wenn ja, dann kann es doch immer die gleiche ID haben. Im Childfenster kannst du doch theoretisch dann auf die Message WM_COMMAND reagieren, bei der die ID des Menüitems als Paramater übergeben wird.

sECuRE 25. Mai 2005 14:03

Re: Handle-konflikt (InsertMenu)
 
Hi,

ja, genau so meine ich das. Sorry wegen der Verwechselung von ID und Handle. Das Problem ist nur, dass ich unterscheiden muss, von welcher Form der Aufruf kam. Man könnte auch ActiveMDIChild verwenden, das ist aber keine saubere Lösung würde ich sagen. Ich reagiere momentan mit WM_SYSCOMMAND auf die Nachricht.

Wie würdest du das denn realisieren, wenn du für jedes Fenster ein Menüitem einfügen müsstest und das "Herkunftsfenster" beim Aufruf anzeigen müsstest? (Hach, warum gibt's kein "Sender" bei solchen Sachen? Doofe Windows-Messages :P)

Danke & cu

jim_raynor 25. Mai 2005 14:52

Re: Handle-konflikt (InsertMenu)
 
Die Frage ist doch, wo du auf WM_SYSCOMMAND reagierst? In TApplication.OnMessage? Wenn ja ist es dort falsch, weil du dann nicht das Formular rausbekommst.

Hab hier kein Delphi deshalb einfach mal ein Schuss ins Blaue. In deinem MDI-Formular machst ne neue Prozedur mit folgender Deklaration:

Delphi-Quellcode:
procedure WMSysCommand(Message: TWMSysCommand);message WM_SYSCOMMAND;
Damit wird im Child auf die Nachricht reagiert, dementsprechend bekommst dort dann über Self das Formular raus und die Nachricht wird wirklich dort behandelt, wo sie auftritt.

P.S: Ist wirklich ungetestet und ich habs noch nicht gemacht. Deshalb kanns totaler Müll sein. Allerdings bin ich optimistisch.

sECuRE 25. Mai 2005 15:16

Re: Handle-konflikt (InsertMenu)
 
Hi,

Volltreffer! Bisher hab ich in OnMessage abgefragt, mit deinem Code funktioniert es tadellos :)

Manchmal sieht man vor lauter Wald die Bäume nicht ;)

Vielen Dank!

cu

Edit: Das funktioniert prima wenn das MDIChild nicht maximiert ist. Sobald es aber maximiert ist, klappt es nicht mehr :( Wird der Event dann an die Parentform gesendet? Wie soll ich denn dann herausfinden, welches Menü auf Form benutzt wurde?

jim_raynor 25. Mai 2005 15:38

Re: Handle-konflikt (InsertMenu)
 
Zitat:

Zitat von sECuRE
Volltreffer! Bisher hab ich in OnMessage abgefragt, mit deinem Code funktioniert es tadellos :)

Das freut mich schon mal ;)
Zitat:

Zitat von sECuRE
Edit: Das funktioniert prima wenn das MDIChild nicht maximiert ist. Sobald es aber maximiert ist, klappt es nicht mehr :( Wird der Event dann an die Parentform gesendet? Wie soll ich denn dann herausfinden, welches Menü auf Form benutzt wurde?

mmh. ich vermute auch mal stark, das die Message ans Parentform geschickt wird. Allerdings weiß ich da jetzt keine Lösung, aber es muss ja ein generelles Problem sein, dass Windowsnachrichten in Delphi bei maximierten Child-Fenstern nicht in den Childfenstern ankommen.

sECuRE 25. Mai 2005 16:20

Re: Handle-konflikt (InsertMenu)
 
Hi,

nun gut, wenn das nicht so beabsichtigt ist belass ich es mal bei meiner vorläufigen Lösung, ich fange die Nachricht ab (die Übrigens nur im Application.OnMessage ankommt) und leite sie an das aktive MDIChild weiter.

Danke & cu


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:40 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