Autor |
Beitrag |
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: So 10.03.19 20:14
Hallo,
galagher hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure TPopupListEx.PerformMessage(cm_msg: integer; msg : TMessage) ; begin if not (Screen.Activeform = nil) then Screen.ActiveForm.Perform(cm_msg, msg.WParam, msg.LParam) ; end; | |
Selbst wenn da ein Popup zugewiesen wäre würde es doch deutlich mehr Sinn machen den LParam zu verwenden und dann dort den Objektzeiger selber zu übergeben.
Generell ist es aber nicht sinnvoll eine bestehende Message zu verbiegen.
Deutlich sinnvoller ist es via PostMessage(Screen.ActiveForm.Handle, WM_MyNotification, WPraram, LParam) eine neue Message zu generieren auf die man via Messagehandler zugreifen kann ohne selber in WindowProc rumpfuschen zu müssen.
galagher hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| initialization FPopupMenu := TPopupMenu.Create(nil);
Popuplist.Free; PopupList:= TPopupListEx.Create; finalization if Assigned(FPopupMenu) then FPopupMenu := nil; end. |
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! |
initialization und finalization ist Unit level. Diese Abschnitte werden nur einmal beim Starten / Beenden des Programmes ausgeführt.
FPopupMenu ist eine globale Variable in der Du dir merkst welches Popup geclickt wurde. Für diese muss daher weder ein Object erzeugt werden noch muss sie freigegeben werden.
was du mit Popuplist.Free; bezweckst ist mir an der stelle auch schleierhaft. Das würde zumindest im finalization mehr Sinn machen.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Für diesen Beitrag haben gedankt: galagher
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 10.03.19 20:48
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 10.03.19 21:07
Sinspin hat folgendes geschrieben : | Deutlich sinnvoller ist es via PostMessage(Screen.ActiveForm.Handle, WM_MyNotification, WPraram, LParam) eine neue Message zu generieren auf die man via Messagehandler zugreifen kann ohne selber in WindowProc rumpfuschen zu müssen. |
Das übersteigt eindeutig meine Fähigkeiten und auch mein Verständnis!
Sinspin hat folgendes geschrieben : | initialization und finalization ist Unit level. Diese Abschnitte werden nur einmal beim Starten / Beenden des Programmes ausgeführt.
FPopupMenu ist eine globale Variable in der Du dir merkst welches Popup geclickt wurde. Für diese muss daher weder ein Object erzeugt werden noch muss sie freigegeben werden. |
Ok. Aber es ist doch nicht nur eine einfache Variable wie String oder Boolean, sondern ein TPopupMenu, also eine Komponente. Und da dachte ich zuerst, die muss man doch wieder freigeben. Man muss sie (als TPopupMenu) aber noch nicht einmal erzeugen! Ich verstehe das nicht ganz, aber ich akzeptiere es gerne!
Man kann nun nicht mehr von ausserhalb auf FPopupMenu zugreifen, ich habe das aber jetzt geändert. Es ist nun keine globale Variable mehr:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| implementation
uses Messages, Forms;
var FPopupMenu: TPopupMenu; type TPopupListEx = class(TPopupList) |
Sinspin hat folgendes geschrieben : | was du mit Popuplist.Free; bezweckst ist mir an der stelle auch schleierhaft. Das würde zumindest im finalization mehr Sinn machen. |
Ich habe den Code von http: so übernommen, ich kannte Popuplist vorher nicht!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 10.03.19 21:14
Frühlingsrolle hat folgendes geschrieben : | Sinspin hat folgendes geschrieben : | was du mit Popuplist.Free; bezweckst ist mir an der stelle auch schleierhaft. Das würde zumindest im finalization mehr Sinn machen. |
Menus.pas hat folgendes geschrieben: | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var PopupList: TPopupList;
implementation
initialization PopupList := TPopupList.Create; finalization PopupList.Free; | |
|
Der Autor von delphi.cjcsoft.net/v...thread.php?tid=45678 hat das so geschrieben. Ok, viele Leute schreiben irgendwas...
Ich gebe aber zu, dass ich nicht weiss, ob das so korrekt ist. Jedenfalls funktionieren beide Varianten. Aber mir kam es natürlich schon seltsam vor, im initialization-Abschnitt etwas freizugeben...
Zitat: | The new PopupList will be freed by
finalization section of Menus unit. |
Ist das wirklich so? "The new PopupList" wurde doch explizit mit .Create erzeugt und im Originalcode gibt es gar keinen finalization-Abschnitt!
Ich habe den Code jetzt wie von dir vorgeschlagen angepasst.
_________________ 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
|
Verfasst: So 10.03.19 21:27
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 10.03.19 21:36
Frühlingsrolle hat folgendes geschrieben : | Wird die Anwendung beendet, dann wird die Variable Menus.PopupList in der Unit Menus.pas im Bereich FINALIZATION freigegeben. |
Hätte ich ja nur nachschauen müssen dort!
So weit, so gut.
Danke euch allen für die Hilfe!
Bleibt nur noch, dass nicht ohne weiteres erkannt wird, welches PopupMenu gerade aktiv ist. Egal, wie ich es drehe, Screen.ActiveForm.PopupMenu ist niemals zugewiesen, daher kann es natürlich auch keine Eigenschaften (wie zB. Name) davon geben.
Wenn euch dazu etwas einfällt, ich bin ganz Ohr (oder Auge in diesem Fall)!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mo 11.03.19 20:52
galagher hat folgendes geschrieben : | Der Autor von delphi.cjcsoft.net/v...thread.php?tid=45678 hat das so geschrieben. Ok, viele Leute schreiben irgendwas...
Ich gebe aber zu, dass ich nicht weiss, ob das so korrekt ist. Jedenfalls funktionieren beide Varianten. Aber mir kam es natürlich schon seltsam vor, im initialization-Abschnitt etwas freizugeben...
Zitat: | The new PopupList will be freed by
finalization section of Menus unit. |
Ist das wirklich so? "The new PopupList" wurde doch explizit mit .Create erzeugt und im Originalcode gibt es gar keinen finalization-Abschnitt!
Ich habe den Code jetzt wie von dir vorgeschlagen angepasst. |
Ja. Wenn man den Zusammenhang kennt dann macht es so wie dort geschrieben Sinn. Und zwar auch ohne finalization in deiner unit.
Um das aktive Popup rauszubekommen wird dir nix anderes übrig bleiben als deinen Weg zu nutzen.
Was das PerformMessage angeht... das ist Geschmackssache. Wenn Du allerdings länger laufende Aktionen vorhast als wie im Beispiel, das ändern der Caption, dann solltest du mit PostMessage arbeiten.
Die Verarbeitung der Nachrichten bleibt so wie sie ist. Es wird nun allerding wirklich eine Nachricht (Windows-Botschaft) gesendet und diese erst verarbeitet wenn das Zielfenster seinen Nachrichtenstapel abarbeitet.
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TPopupListEx.PerformMessage(cm_msg: integer; msg : TMessage) ; begin if Assigned(Screen.Activeform) then PostMessage(Screen.ActiveForm.Handle, cm_msg, msg.WParam, msg.LParam); end; |
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 11.03.19 21:07
Sinspin hat folgendes geschrieben : | Um das aktive Popup rauszubekommen wird dir nix anderes übrig bleiben als deinen Weg zu nutzen. |
Kann man es denn nicht über PopupList rausbekommen?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mo 11.03.19 23:49
Eigentlich bin ich der Meinung: finds doch einfach raus! Da lernste am meißten.
Andererseits, Du wirst noch ein bisschen Spass haben dich mit meinem Quelltext zu befassen. Der sieht saumäßig aus, da einfach nur zusammen geklatscht was nötig ist.
Daher, siehe Anhang .
Einloggen, um Attachments anzusehen!
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 12.03.19 22:11
Sinspin hat folgendes geschrieben : | Andererseits, Du wirst noch ein bisschen Spass haben dich mit meinem Quelltext zu befassen. |
Macht prinzipiell das, was ich mir vorstelle. Man müsste nur an einer geeigneten Stelle FLatestPopup := nil anbringen, damit, wenn man mit der Maus über ein TMenuItem geht,das PopupMenu erneut erkannt wird. Erst dachte ich, FLatestPopup := nil gehört entweder ins CM_EXIT_MENU_LOOP oder ins CM_MENU_CLOSED, aber beides führt zu einer Zugriffsverletzung.
Und als zweiter Punkt: Warum kann das PopupMenu erst im WM_MENUSELECT erkannt werden und nicht schon im CM_ENTER_MENU_LOOP? TPopupListEx(Popuplist).LatestPopup wird derzeit dort nicht ermittelt.
Ich bekomm's aber nicht so hin, dass es dort funktioniert.
Scheint mir sinnvoller zu sein, das PopupMenu schon im CM_ENTER_MENU_LOOP zu erkennen und nicht erst, wenn man mit der Maus drübergeht!
Bitte nicht falsch verstehen, das ist keine Kritik! Ich dachte nur, ich kann es so hinbasteln, wie ich es möchte, aber dann funktioniert es nicht.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mi 13.03.19 08:59
Ist mir schon klar dass du es anders besser finden würdest. Geht mir auch so. Aber ich habe nix gefunden.
Wobei ich auch nicht ernsthaft gesucht habe ob es auch zusätzliche Informationen für den anderen Events gibt.
Das kannst du ja machen. Tante Google wird dir dabei sicher helfen.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mi 13.03.19 11:50
Ist nur die Frage, warum man das PopupMenu nicht im CM_ENTER_MENU_LOOP erkennen kann.
Und was das FLatestPopupbetrifft: Man könnte doch and (... <> FLatestPopup) (Ich habe den genauen Code jetzt nicht vor mir) weglassen, das muss ich aber noch testen, ob das auch wirklich immer zuverlässig funktioniert.
Und auch das Setzen von FLatestPopup := nil, das zu einer Zugriffsverletzung führt...
Irgendwie verhält sich der Code etwas seltsam.
Sinspin hat folgendes geschrieben : | Tante Google wird dir dabei sicher helfen. |
Wenn ich etwas finde oder auf etwas draufkomme, stelle ich es hier rein!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Sa 16.03.19 22:08
Hallo zusammen!
Ich komme da nicht weiter. Ich dachte mir, warum das Ganze nicht in als eine eigene Komponente TPopupMenuEx realisieren? Gesagt, getan. Ich packe den Code also da rein, aber es tut nicht...
TPopupListEx.PerformMessage und PopupListEx.WndProc arbeiten zwar, PopupListEx.WndProc ruft aber TPopupMenuEx.PopupMenuClosed nicht auf, obwohl alles exakt so ist, wie es war, als ich den Teil, den nun TPopupMenuEx übernehmen soll, noch in Form1 hatte. Verständlich, was ich meine? TPopupMenuEx sollte nach meinem Plan den Part von Form1 übernehmen, TPopupListEx sollte seinen Teil erledigen und gut.
In einem zweiten Schritt hätte ich mir dann überlegt, wie ich ein property OnClose einbaue. So weit kam ich aber zunächst nicht. Es funktionierte einfach nichts richtig.
Dann kam ich auf die Idee, den ganzen PerformMessage-Kram ganz wegzulassen und nur ein property OnClose reinzusetzen. Das hatte ich immerhin schon so hingebracht, dass es funktionierte - allerdings schon gleich beim Popup der Komponente!
Ich krieg's nicht hin.
Wie konnten die Programmierer von Borland und/oder Embarcadero denn nur ein OnClose bei einem PopupMenu weglassen?
_________________ 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
|
Verfasst: So 17.03.19 00:10
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 17.03.19 18:55
Frühlingsrolle hat folgendes geschrieben : | Zeig mal, wie du es umgesetzt hast.
Ich schau es mir frühestens am SO Abend an. |
Ich musste es erst aus dem __history-Ordner rausfischen, hatte es schon gelöscht!
Das ist also die Version, in der immerhin schon mal PerformMessage ausgeführt wird, aber Prozedur PopupMenuClosed nicht.
Ich habe mich hier erstmal nur auf PopupMenuClosed beschränkt.
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:
| unit ExPopupMenu;
interface
uses Vcl.Controls, System.Classes, Menus, Messages, Forms;
const CM_MENU_CLOSED = CM_BASE + 1001; CM_ENTER_MENU_LOOP = CM_BASE + 1002; CM_EXIT_MENU_LOOP = CM_BASE + 1003;
type TPopupMenuEx = class (TPopupMenu) private FPopupMenu: TPopupMenu; procedure PopupMenuClosed(var msg: TMessage) ; message CM_MENU_CLOSED; public constructor Create(AOwner: TComponent); end;
type TPopupListEx = class(TPopupList) protected procedure WndProc(var Message: TMessage) ; override; private procedure PerformMessage(cm_msg : integer; msg : TMessage) ; end;
implementation
uses Unit1; constructor TPopupMenuEx.Create(AOwner: TComponent); begin FPopupMenu := Self; inherited Create(AOwner); end;
procedure TPopupListEx.PerformMessage(cm_msg: integer; msg : TMessage) ; begin if Assigned(Screen.Activeform) then Screen.ActiveForm.Perform(cm_msg, 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(Message) do begin if (Menu = 0) and (Menuflag = $FFFF) then PerformMessage(CM_MENU_CLOSED, Message) ; end; end; inherited; end;
procedure TPopupMenuEx.PopupMenuClosed(var msg: TMessage) ; begin form1.Caption := 'Ja!'; end;
initialization PopupList:= TPopupListEx.Create; end. |
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mo 18.03.19 18:35
galagher hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TPopupMenuEx = class (TPopupMenu) private FPopupMenu: TPopupMenu; procedure PopupMenuClosed(var msg: TMessage) ; message CM_MENU_CLOSED; public constructor Create(AOwner: TComponent); end; | |
Die procedure PopupMenuClosed solltest du dann aber auch in dem Form deklarieren dass du via PerformMessage aufrufst. Im Popup bringt das nix. Zumal ein Popup keine Form zu sein scheint.
Ich habe jedenfalls keine WindowProc gefunden die darauf hindeuten würde.
Windowsbotschaften können nur ausgeführt werden wenn dafür auch eine WindowProc da ist in die die selber deklarierten Botschaftsempfänger vom Compiler eingehangen werden.
Wenn ich Heute Abend noch Kopf für sowas habe schau ich nochmal rein.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 18.03.19 19:23
Sinspin hat folgendes geschrieben : | Die procedure PopupMenuClosed solltest du dann aber auch in dem Form deklarieren dass du via PerformMessage aufrufst. |
Nun, idealerweise gibt es dann in meiner Komponente ein property, das beim Doppelklick im Objektinspektor genau diese Prozedur in dem Form einfügt. Also zB. property OnClose (OnClose - ist das eigentlich ein reservierter Ausdruck? Wenn ja, dann eben zB. OnPopDown). Da doppelklickt man im OI drauf und es wird procedure TForm1.PopupMenuClosed erstellt.
Das ist der Plan, aber wie ich das hinbekomme, weiss ich nicht.
_________________ 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
|
Verfasst: Di 19.03.19 18:59
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: galagher
|
|
galagher
Beiträge: 2527
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Do 21.03.19 09:20
Momentan komme ich nicht dazu, aber ich werde mir das noch anschauen und sehen, wie weit ich komme.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|