![]() |
Aktionen zur Laufzeit einfügen?
Hi,
ich habe mir nach ![]() Ich denke, ich muss also eine TCustomAction erzeugen und diese in den ActionManager einfügen. Dazu habe ich den Befehl TActionManager.AddAction gefunden; er erwartet jedoch einen ActionClient - wozu brauche ich den? Wie regele ich das dann später mit der Kategorie? Wenn ich TCustomAction benutzen muss, wie schaffe ich es, dass die Anzahl dynamisch bleibt und dass ich möglichst die TCustumAction s nicht global erzeugen muss? mfg fortuneNext |
Re: Aktionen zur Laufzeit einfügen?
Zitat:
|
Re: Aktionen zur Laufzeit einfügen?
Jep, das hatte ich auch schon probiert - hat mir leider aber nicht besonders weitergeholfen. Da ich Actions / Actionmanager das erste mal verwende, blicke ich da grundsätzlich noch relativ wenig durch... Mit den Google-Ergebnissen konnte ich daher leider relativ wenig anfangen, da ich nichtmal genau weiss, was eine Actionlist ist - werde ich noch nachschlagen, aber evtl. findet sich ja hier jemand, der mir allgemeiner weiterhelfen kann, evtl. durch ein anschauliches Codebeispiel :)
Was zB bei AddAction unklar bleibt: Wird die Action in den Manager kopiert, oder wird bloß ein Verweis gelegt, sodass ich tatsächlich für jede Action eine Variable brauche? All diese Fragen sind noch relativ verworren bei mir, und Google spuckt leider kein klares Beispiel aus, nur mehrere Schnipsel, deren ich aber nicht vermag, sie passend zu meinen Zwecken zusammenzusetzen... |
Re: Aktionen zur Laufzeit einfügen?
|
Re: Aktionen zur Laufzeit einfügen?
Oh, ein super Link mkinzler, danke! :-) Ich denke, nun habe ich das Prinzip von Actions soweit verstanden. Was aber leider nicht erwähnt wurde, ist, wie nun Aktionen zur Laufzeit erstellt werden...
Wenn ich das richtig verstanden habe: TCustomAction createn und einstellen In die Actionlist einfügen TCustomAction destroyen (und evtl. den Variablenplatz wiederverwerten) -> Action ist in der Liste. Wenn ichs richtig verstanden habe, speichert die Liste die Aktionen tatsächlich und enthält nicht nur verweise auf andere Objekte/Variablen. Problem bleibt weiterhin bestehen: Was muss ich als TActionClient beim AddAction übergeben? Sind damit die Buttons gemeint? Ich benutze nämlich soetwas eigentlich garnicht, sondern nutze wie gesagt das Menü. Das wird allerdings als Client nicht akzeptiert. mfg fortuneNext |
Re: Aktionen zur Laufzeit einfügen?
Übrigens, ich hab grad nochmal TActionManager.AddAction in Google eingegeben und auf gut Glück gedrückt... ratet mal wo ich gelandet bin <>_<>
|
Re: Aktionen zur Laufzeit einfügen?
Ich mache das so:
Delphi-Quellcode:
Allerdings verwende ich ActionLists pur ohne ActionManager - k.A., ob das einen Unterschied macht.
function TEineForm.CreateAction(const AName, ACategory, ACaption: string;
AShortCut: TShortCut; AOnExecute: TNotifyEvent; AOnUpdate: TNotifyEvent = nil): TAction; begin Result := TAction.Create(Self); Result.Name := AName; Result.Category := ACategory; Result.Caption := ACaption; Result.ShortCut := AShortCut; Result.OnExecute := AOnExecute; Result.ActionList := EineActionList; end; |
Re: Aktionen zur Laufzeit einfügen?
Ok Danke erstmal, das scheint zu funktionieren :)
Allerdings bin ich etwas verwirrt. Wieso funktioniert dieser Code? Wie wird Result eigentlich nach dem Funktionsaufruf behandelt? Würde man den Code einfach als Schnipsel so einfügen und result als Variable behandeln, würde sie ja schon beim nächsten Aufruf wieder überschrieben werden. Warum funktioniert das in einer separierten Funktion? Funktioniert das Result so wie die Instanz bei Create ohne Variable, in die das gepackt wird - also irgendwo ins Nirvana geschossen ohne Zugriff? In diesem Fall bleibt der Zugriff natürlich über die Liste enthalten. Wenn ich das richtig verstehe, dann - würde man die Aktion nicht in die Liste eintragen, würde sie im Datennirvana verschwinden? Wäre es nicht eleganter, das als Constructor einzubauen? Nichts als Fragen... |
Re: Aktionen zur Laufzeit einfügen?
Ich habe mal rumexperimentiert und nun das gebastelt:
Delphi-Quellcode:
Wie genau muss ich nun TNotifyEvent übergeben? Wie kann ich OnExecute Ereignisse festlegen? Muss ich den Namen der Dynamisch erzeugten Aktion vorher schon kennen, um ein Name.OnExecute statisch festzulegen?
function TfMain.CreateLanguageAction(const AName, ACaption: string; AOnExecute: TNotifyEvent):TAction;
begin Result := TAction.Create(MainMenu_ActMan); Result.Name := AName; Result.Category := 'Language'; Result.Caption := ACaption; Result.OnExecute := AOnExecute; Result.ActionList := MainMenu_ActMan; end; procedure TfMain.MainMenu_ActManBarClick(Sender: TObject); var x:integer; begin for x := 1 to length(FNAGBasicControl.Lg_LanguageFileList) - 1 do begin CreateLanguageAction(FNAGBasicControl.Lg_LanguageFileList[x], copy(FNAGBasicControl.Lg_LanguageFileList[x], 1, pos('.ini', FNAGBasicControl.Lg_LanguageFileList[x]) - 1), showmessage('test')); end; end; Zur Info: Lg_LanguageFileList ist ein Array aus String, der verschiedene Dateinamen enthält. Diese dateinamen sollen dann ohne '.ini' als Optionen im Menü erscheinen. mfg fortuneNext |
Re: Aktionen zur Laufzeit einfügen?
Den OnExecute-Handler musst du manuell erstellen, etwas wie LanguageActionExecute hier:
Delphi-Quellcode:
(Ungetestet, da ich mich mit dem ActionManager-Kram nicht auskenne.)
procedure TfMain.LanguageActionExecute(Sender: TObject);
begin Assert(Sender is TAction); ShowMessage(TAction(Sender).Caption); end; procedure TfMain.MainMenu_ActManBarClick(Sender: TObject); var i: Integer; begin // Das Löschen musst du evtl. anpassen: for i := Pred(MainMenu_ActMan.ActionCount) downto 0 do MainMenu_ActMan.Actions[i].Free; for i := Low(Lg_LanguageFileList) to High(Lg_LanguageFileList) do CreateLanguageAction('LanguageAction' + IntToStr(i), ExtractFileName(Lg_LanguageFileList[i]), LanguageActionExecute); end; |
Re: Aktionen zur Laufzeit einfügen?
Wow,
so langsam läufts echt :) Danke nochmal allen bisherigen Helfern! Nun habe ich mir folgende - zugegeben sehr verworrene Codezeilen - zurechtgepflückt. (Aufs Wichtige reduziert)
Delphi-Quellcode:
Wenn man die Struktur des Actionmanagers erst einmal durchschaut hat, ergibt plötzlich alles einen Sinn 8-)
for x := 3 to MainMenu_ActMan.ActionCount do
MainMenu_ActMan.Actions[x].Free; for x := 1 to length(FNAGBasicControl.Lg_LanguageFileList) - 1 do MainMenu_ActMan.AddAction(CreateLanguageAction(AllesAufNameZusammengefasst, LanguageActionExecute), MainMenu_ActMan.ActionBars[0].Items[0].Items[3].Items[x - 1]); Nun das (wahrscheinlich letzte) Problem: Damit die LanguageFiles im Submenu "Languages" aufgelistet werden, muss das Teil ja als Client mit Verweis auf die Action gespeichert werden. Gekürzte Struktur: MainMenu_ActMan --ActionBars ----ActionBars[0] ------Items --------Items[0] "Options" ----------Items ------------Items[0] "Eine Option" ------------Items[1] "Eine andere Option" ------------Items[2] "Eine dritte Option" ------------Items[3] "Languages" --------------Items -> Hier müssten die Clients ja eigentlich hin, denke ich. Wie krieg ich sie also dort rein? Mit der Zeile im MainMenu_ActMan.AddAction habe ich ja den genauen Ort zur Speicherung bereits spezifiziert - also eigentlich sollte nichts mehr im Wege stehen. Nun bekomme ich aber die Fehlermeldung: "Listenindex überschreitet das Maximum (3)" in der AddAction Zeile. Ich schließe daraus: Items[0], Items[1] etc gibt es noch überhaupt nicht - macht ja auch Sinn. Wie aber erstelle ich sie? SetLength klappt nicht, TActionClients und Array of TActionClient stimmen nicht überein... |
Re: Aktionen zur Laufzeit einfügen?
Mal so am Rande - habe ich die Frage in der falschen Kategorie gestellt? Bin mir nicht ganz sicher...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz