Autor Beitrag
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Fr 08.03.19 20:23 
Hallo!

Ich habe nun nach einiger Suche eine Möglichkeit gefunden, auf das Schliessen eine PopupMenus zu reagieren:
www.delphipraxis.net...e-geoeffnet-ist.html

Nur leider komme ich nicht drauf, wie man, wie dort angesprochen, herausfinden kann, um welches PopupMenu es sich handelt:
Zitat:
Wie kann man in CMMenuClosed then NAMEN des betreffenden Popup-Menüs erfahren? Geht das überhaupt?

Zitat:
Ja das geht, wenn man beim Senden der Nachricht auch noch eine zusätzliche Information hinzufügt (z.B. die Referenz auf die Popup-Instanz).

Zitat:
Und wie könnte man in der PRAXIS beim Senden der Nachricht in diesem Beispiel die betreffende Information einfügen?


Weiss jemand, wie das geht?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 08.03.19 21:13 
- Nachträglich durch die Entwickler-Ecke gelöscht -

Für diesen Beitrag haben gedankt: galagher
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Fr 08.03.19 21:36 
Hallo Frühlingsrolle!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Man könnte das noch erweitern und z.B. anstelle des wParam-Parameters, self.Name mitschicken, in etwa:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TExPopupList.WndProc(var Message: TMessage);
  Procedure Send( msg: Integer );
  Begin
    If Assigned( Screen.Activeform ) Then
      Screen.ActiveForm.Perform( msg, WParam(PChar(self.Name)),  //<- hier ist ein Fehler!
Message.lparam );
  End;
begin
  //...
end;



Leider klappt es mit WParam(PChar(self.Name)) nicht. Ich habe etwas herumexperiemtiert und bin auf Message.WParam(PChar(self.Name)) gekommen - .Name wird aber nicht erkannt bzw. gibt es das hier nicht. Auch Message.WParam(PChar(self)) funktioniert nicht, hier meckert der Compiler:
Zitat:
E2066 Operator oder Semikolon fehlt
- hier wird offenbar ein , erwartet, sonst nichts!

Ich verstehe, was du meinst, bekomme es aber nicht hin.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 08.03.19 21:55 
- Nachträglich durch die Entwickler-Ecke gelöscht -

Für diesen Beitrag haben gedankt: galagher
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 06:02 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

Nachtrag

ausblenden Delphi-Quelltext
1:
function GetPopupName(Parent: TWinControl): string;					

Naja, das liefert in jedem Fall das erste gefundenene PopupMenu, egal, welches gerade verwendet wird...

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 06:46 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 07:53 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
So funktioniert es explizit nur für TForm Objekte.

Das nützt mit für meine Zwecke nichts. Ich möchte herausfinden können, welches PopupMenu das Schliessen ausgelöst hat, also von welchem PopupMenu Send( CM_MENUCLOSED ); ausgelöst wurde!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 09:27 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 10:53 
Funktioniert leider auch nicht:
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TExPopupList.WndProc(var Message: TMessage);
  Procedure Send( msg: Integer );
  Begin
    If Assigned( Screen.Activeform ) Then
      Screen.ActiveForm.Perform( msg, Integer(PChar(Screen.ActiveForm.PopupMenu.Name)), 0 );
  (*                                  |
                               Das produziert einen Zugriffsfehler!
  *)

  End;
begin
  // ... wie im verlinkten Post gegeben
end;

Ich krieg's einfach nicht hin!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 11:07 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 11:45 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Kann ich nicht bestätigen

Ich leider doch:
Zitat:
Im Projekt Help.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 006D658E in Modul 'Help.exe'. Lesen von Adresse 00000008' aufgetreten.


Geht das nur mit PopupMenus der TForm? Ich habe PopupMenus, die zu verschiedenen Komponenten gehören. Bei keiner funktioniert es!

//Edit:
Auch bei PopupMenus von TForm kommt es zu dem Fehler!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 17:35 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 20:33 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Hm, führst du Delphi mit Adminrechten aus? Bei mir ist das der Fall.

Nein, eingeschränktes User-Konto. Muss doch aber egal sein, oder?

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Die Eigenschaft .Popupmenu ist keiner Klasse eindeutig zuordenbar, daher muss man den Code auf das jeweilige Parent umschreiben.
Mit RTTI könnte man es zurecht biegen, da bin ich aber nicht so sattelfest darin.

RTTI? Muss ich googeln!
Das Problem ist, dass Screen.ActiveForm.PopupMenu nicht zugewiesen ist, denn wenn man mit if Assigned(Screen.ActiveForm.PopupMenu) prüft, wird der Code nicht ausgeführt - ist also nicht zugewiesen.

Was ich nicht verstehe: Das PopupMenu gibt es ja, es gibt gleich mehrere, die jeweils verschiendene Komponenten haben. Sie existieren also, werden auch nirgendwo im Code "destroyed" oder so was in der Art.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 20:50 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 21:16 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Viele WinAPI Funktionen, die im Delphi allgegenwertig sind, benötigen Lese- und Schreibrechte, die nur mit Adminrechten ein "korrektes" Ergebnis liefern können.

Dann muss ich hier wohl aufgeben. Delphi ist unter meinem Adminkonto nicht eingerichtet. Ich kann mein Projekt nicht kompilieren, weil da diverse Komponenten nicht installiert sind.

//Edit: Klar könnte ich das jetzt alles auch im Adminkonto installieren.
Gibt es keinen einfacheren Weg, an das PopupMenu heranzukommen? Irgendwie, irgendwo muss mein Programm ja "wissen", welches PopupMenu gerade geschlossen wird!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.03.19 21:25 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: Sa 09.03.19 21:31 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Mit RTTI könnte man es zurecht biegen, da bin ich aber nicht so sattelfest darin.

Ich erst recht nicht!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: So 10.03.19 11:14 
Zunächst habe ich einige Methoden in gefälligere Namen umbenannt und zudem einige neue Methoden hinzugefügt:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
unit ExPopupMenu;

interface

uses Controls, Menus;

const
    CM_MENU_CLOSED = CM_BASE + 1001;
    CM_ENTER_MENU_LOOP = CM_BASE + 1002;
    CM_EXIT_MENU_LOOP = CM_BASE + 1003;

var
  FPopupMenu: TPopupMenu;

function GetCurrentPopupMenu: TPopupMenu;
procedure SetCurrentPopupMenu(const PopupMenu: TPopupMenu);

implementation

uses Messages, Forms;

type
    TPopupListEx = class(TPopupList)
    protected
      procedure WndProc(var Message: TMessage) ; override;
    private
      procedure PerformMessage(cm_msg : integer; msg : TMessage) ;
    end;

{ TPopupListEx }
procedure TPopupListEx.PerformMessage(cm_msg: integer; msg : TMessage) ;
begin
    if not (Screen.Activeform  = nilthen
      Screen.ActiveForm.Perform(cm_msg,
        (*Integer(PChar(Screen.ActiveForm.PopupMenu)),*)  //<- Ist nicht zugewiesen und daher nicht verwendbar!
        msg.WParam, msg.LParam) ;
end;

procedure TPopupListEx.WndProc(var Message: TMessage) ;
begin
    case message.Msg of
      WM_ENTERMENULOOP: PerformMessage(CM_ENTER_MENU_LOOP, Message) ;
      WM_EXITMENULOOP : PerformMessage(CM_EXIT_MENU_LOOP, Message) ;
      WM_MENUSELECT :
      with TWMMenuSelect(Messagedo
      begin
        if (Menu = 0and (Menuflag = $FFFFthen
        begin
          PerformMessage(CM_MENU_CLOSED, Message) ;
        end;
      end;
    end;
    inherited;
end;

function GetCurrentPopupMenu: TPopupMenu;
begin
  Result := FPopupMenu;
end;

procedure SetCurrentPopupMenu(const PopupMenu: TPopupMenu);
begin
  FPopupMenu := PopupMenu;
end;

initialization
    FPopupMenu := TPopupMenu.Create(nil);

    Popuplist.Free; //free the "default", "old" list
    PopupList:= TPopupListEx.Create; //create the new one
    // The new PopupList will be freed by
    // finalization section of Menus unit.

finalization
  if Assigned(FPopupMenu) then
    FPopupMenu := nil;  //<- Hier führt .Free zu einem Laufzeitfehler: "Runtime error 217 at 00409495"

end.


Ich habe das nun so gelöst, dass man im OnPopup des jeweiligen PopupMenus eben dieses zuweist, um später auswerten zu können, um welches PopupMenu es sich handelt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
  SetCurrentPopupMenu(TPopupMenu(Sender));
end;

//Hier kann man nun mehrere PopupMenus unterscheiden:
procedure TForm1.PopupMenuClosed(var msg: TMessage) ;
begin
  if GetCurrentPopupMenu = PopupMenu1 then
    Showmessage('PopMenu closed');
end;

procedure TForm1.PopupMenuEnter(var msg: TMessage) ;
begin
  if GetCurrentPopupMenu = PopupMenu1 then
    Showmessage('PopMenu entered');
end;

procedure TForm1.PopupMenuExit(var msg: TMessage) ;
begin
  if GetCurrentPopupMenu = PopupMenu1 then
    Showmessage('PopMenu exited');
end;


Ich habe damit mein Ziel erreicht, aber leider nicht "vollautomatisch"!

Vielleicht könnte mit noch jemand sagem, warum es im finalization-Abschnitt zu einem Laufzeitfehler kommt, wenn ich dort FPopupMenu.Free verwende, und ob es überhaupt notwenig ist, FPopupMenu freizugeben!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 10.03.19 15:53 
- Nachträglich durch die Entwickler-Ecke gelöscht -
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2281
Erhaltene Danke: 44

Windows 7 64 Bit
Delphi XE2 Starter, Delphi 10.1 Starter, Delphi 10.2 Tokyo Community Edition
BeitragVerfasst: So 10.03.19 20:04 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Zu dem Lsufzeitfehler wird es wahrscheinlich deswegen kommen, weil das übergebene Popupmenu1 dadurch an 2 Stellen freigegeben wird, was nicht geht.
Einmal von der Hauptklasse, und dann von deiner Klasse aus.
Es NIL zu setzen, find ich überflüssig.

Ja, das stimmt wohl, denn ich muss es nicht einmal erzeugen: Es funktioniert auch ohne .Create.

Natürlich wäre es noch einfacher, einen String zu verwenden und einfach auf .Name zu prüfen. Es klappt, ist aber dennoch nur eine halbe, oder sagen wir, eine dreiviertel-Lösung, denn ich benötige eben eine Methode, um das PopupMenu erst einmal "bekannt" zu machen. Schön wäre es, wenn das alles automatisch erledigt wird.

Und noch etwas gefällt mir nicht: Man kann auf FPopupMenu von ausserhalb zugreifen!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!