![]() |
Event Pfad an MenuItem übergeben (Problem)
Ich bin auf Win-11 umgestiegen, wie erwartet hat MS wieder noch mehr Möglichkeiten gesperrt.
Ich habe viel portable Programme, die ich gerne über PopUpMenü starte. Früher konnte man ein Verzeichnis mit den Namen \ \ verlinken und schon war ein Menü vorhanden. Das ist leider nur noch Geschichte. MS sei Dank. Ich habe mir selbst etwas gebastelt. TrayIcon mit einem PopUpMenü. Damit es aber flexibel bleibt, sollte es so funktionieren. Einfach das Hauptverzeichnis deklarieren und dann die .lnk Dateien auslesen, aber auch die Unterverzeichnisse lesen, als Untermenü erstellen und die Inhalte (.lnk) als Items zu runtime erstellen. Damit kann man einfach nur die .lnk erstellen, reinkopieren und schon hat man es im Menü. So weit, so gut. Das einzige Problem ist mein Event. Ich habe ein Event auf den Click deklariert. Soweit immer noch so gut. Ich lese die ganzen Infos aus der .lnk Datei, dafür brauche ich aber auch den Pfad. Bei einem einzigen Verzeichnisse wäre es gar kein Problem, ich habe aber viele Unterverzeichnisse. MenuItem bietet mir nicht an, den Pfad zu übergeben. Momentan verbiege ich es über Hints, was natürlich nicht der Sinn der Sache ist. Wie könnte ich es realisieren? (Bitte Rücksicht darauf nehmen, dass ich nur ein HobbyCoder bin) Hier das Relevante vom Code
Delphi-Quellcode:
Hier ist mein Event
TTask.Run(
procedure var Directories : TArray< string>; Dateien : TStringList; Reg : TRegistry; Item : TMenuItem; Bitmap : TBitmap; Icon : TIcon; {Vcl.Graphics} Directory : string; Skin : string; Titel : string; Datei : string; Index : Integer; ItemIndex : Integer; IconOK : Boolean; procedure DateiListe(Path, Ext: string; FileList: TStrings); var Datei : TSearchRec; begin if AnsiLastChar(Path) <> '\' then Path := Path + '\'; if FindFirst(Path + '*.' + Ext, faAnyFile, Datei) = 0 then begin repeat if (Datei.Attr <> faDirectory) and (Pos('_____', Datei.Name) = 0) then FileList.Add(Datei.Name); until FindNext(Datei) <> 0; FindClose(Datei); end; end; begin OleInitialize(nil); Directories := TDirectory.GetDirectories('D:\Tools\*\'); ItemIndex := 1; for Directory in Directories do begin ItemIndex := ItemIndex + 1; Path := Directory; if AnsiLastChar(Path) <> '\' then Path := Path + '\'; TThread.Synchronize(TThread.Current, procedure begin Item := TMenuItem.Create(PopupMenu1); Item.Caption := ExtractFileName(Directory); Item.ImageIndex := 42; PopupMenu1.Items.Add(Item); {MenüItem = Ordner} end); Dateien := TStringList.Create(); try DateiListe(Path, 'lnk', Dateien); {Liste der lnk Dateien erstellen} if Dateien.Count > 0 then begin for Index := 0 to Dateien.Count - 1 do begin Titel := Dateien[Index]; Titel := TPath.GetFileNameWithoutExtension(Titel ); {Titel = Name ohne Erweiterung, damit das Menü sauber aussieht} Datei := LnkDateiLesen(Path + Dateien[Index]); {Exe Datei auf der lnk Datei auslesen} Icon := TIcon.Create; Bitmap := TBitmap.Create; try try Icon := IconVonDatei(Datei); {Icon von der Exe Datei erfassen} Bitmap.Canvas.Brush.Style := bsClear; {Bitmap als Transparent deklarieren} Bitmap.Width := Icon.Width; Bitmap.Height := Icon.Height; Bitmap.Transparent := True; {Transparenz einschalten} Bitmap.Canvas.Draw (0, 0, Icon); except IconOK := False; end; TThread.Synchronize(TThread.Current, procedure begin Item := TMenuItem.Create(PopupMenu1); Item.Caption := Titel ; Item.OnClick := PopupClick; Item.Hint := ExtractFileName(Directory); //DAS IST MISST ImageList16x16.Add(Bitmap, nil); Item.ImageIndex := ImageList16x16.Items.Count - 1; PopupMenu1.Items[ItemIndex].Add(Item); end); finally FreeAndNil(Icon); FreeAndNil(Bitmap); end; end; end; finally FreeAndNil(Dateien); end; end;
Delphi-Quellcode:
Das Teil ist Misst : LnkFolder := Path + MenuItem.Hint;
procedure TForm1.PopupClick(Sender: TObject);
var MenuItem : TMenuItem; Target : string; Datei : string; Folder : string; LnkFolder : string; begin if not (Sender is TMenuItem) then begin Showmessage('Hm, if this was not called by Menu Click, who called this?!') ; ShowMessage(Sender.ClassName); exit; end; MenuItem := TMenuItem(Sender); {MenuItem empfangen} LnkFolder := Path + MenuItem.Hint; {Verzeichnis im dem sich die .lnk Dateien befinden bestimmen} //DAS IST NATÜRLICH AUCH MISST if AnsiLastChar(LnkFolder) <> '\' then LnkFolder := LnkFolder + '\'; {Verzeichnis muss mit \ enden} Target := LnkDateiLesen(LnkFolder + MenuItem.Caption + '.lnk'); {lnk Datei lesen und die exe Datei erfassen} Folder := ExtractFilePath(Target); {Den Ordner von der exe erfassen} Datei := ExtractFileName(Target); {exe datei erfassen} if MenuItem.Caption = 'Close' then Close else if Pos('SANDBOX', LnkFolder.ToUpper) > 0 then begin ShellExecute(Application.Handle, 'open', 'C:\Program Files\Sandboxie\Start.exe', PWideChar('/box:DefaultBox ' + Datei), PWideChar(Folder), SW_SHOWNORMAL); end else ShellExecute(HWND(nil), 'open', PWideChar(Datei), nil , PWideChar(Folder), SW_NORMAL); end; Path ist global deklariert, im Hint übergebe ich den Namen des Ordners, also auch ein Untermenüname. Das möchte ich besser lösen, finde aber keine Methode den Ordnernamen zu übergeben. Soweit es mir bekannt ist,bei Event kann ich keine Variable selbst deklarieren. Bitte um Rücksicht bei den Antworten, Programmieren nur mein Hobby. Damit ich es einfach erweitern kann möchte ich bei dem Aufbau bleiben, also bitte keine Änderungen die komplett neune Aufbau verlangen. Neuen Ordner erstellen, .lnk reinkopieren und schon taugt es in meinem PopUpmenü auf. .lnk auslesen und auf die exe verlinken. Ich bin manchmal etwas paranoid, manche Tools mag ich nur in de Sandboxie starten. Für brauchbare Ansätze wäre ich sehr dankbar. |
AW: Event Pfad an MenuItem übergeben (Problem)
Eigentlich geht vieles immernoch, selbst im Kontextmenü des Explorer/Windows.
PS: Zitat:
dann funktioniert das so nicht!
Delphi-Quellcode:
, bzw. hier mit = anstatt <>
Datei.Attr and faDirectory <> 0
oder
Delphi-Quellcode:
not (Datei.Attr and faDirectory <> 0)
Alternativ kannst du auch erstmal alle anderen Attribute rausfiltern und dann vergleichen
Delphi-Quellcode:
Datei.Attr and faDirectory <> faDirectory)
Delphi-Quellcode:
Datei.Attr and faDirectory = faDirectory)
Aber mit <>0 und = 0 ist es kürzer, übersichtlicher und ohne Doppelung. AnsiLastChar mit +'\' ![]() Und ansonsten kann es nicht schaden den Code "sprechender" zu machen, so er von selbst sagt, was gemeint ist Pos() > 0 ![]() ![]() Ja, bezüglich ToUpper und Co., stattdessen die TEXT-Varianten. :angle: Pos() = 0 not ContainsStr sowie AnsiLastChar ![]() ![]() Zitat:
oder das "Tag" lässt sich auch schön nutzen. Rate mal was passiert, wenn ausversehn die Option für automatische ShortCuts aktiv ist und "irgendwo" im String ein & enthalten ist, oder wenn mal jemand mit Lokalisierung rumspielen möchte. (dann sagt das = NÖ dazu) Psssst, ist dir aufgefallen, dass niemand IconOK verwendet? |
AW: Event Pfad an MenuItem übergeben (Problem)
Danke für die Ansätze, ja man kann einiges verbessern, meine Frage nach dem Event hast du aber nicht mal angesprochen.
Mit Win komme ich klar, dass man altes Menü (Das ist schon lange passiert bei mir) zurückholen kann ist mir auch geläufig. Das ist aber nicht meine Frage. ich erstelle mir ein Menü, rechts unten, für den schnellen Zugriff. Dort parke ich nur portable Programme. Es dient meiner Bequemlichkeit. Natürlich sind die anderen Sachen für mich auch relevant, allerdings verstehe ich nicht was zB. gehen Pos sprechen soll? Nicht alles, was alt ist, ist doch gleich schlecht. Ich mag mich zwar verbessern, für meine Zwecke mag ich aber nicht immer neue Sachen lernen. Das Nötige soll eben reichen. Ein Pos, funktioniert allerdings nach wie vor. Bitte nicht falsch verstehen, ich verstehe es manchmal aber nicht wirklich, warum man alles umkrempeln muss, nur weil Emba etwas geändert hat? Mit Pos habe ich schon immer gearbeitet, es sitzt halt im Kopf. Bis vor Kurzen habe ich nur mit Delphi 7 gearbeitet. Supi finde ich zB : IncludeTrailingPathDelimiter Obwohl meine Art auch funktioniert hat. Zitat:
Ich nehme aus deinem Post ganze menge mit, werde es auch teils umsetzen, meine Frage nach dem Event bleibt aber immer noch bestehen. Ich möchte den Namen von dem Verzeichnis, welches zu Runtime erfasst wurde, an das Event übergeben. Das Ganze funktioniert nämlich schon sehr gut, nur gefallen tut es mir nicht. Ich könnte auch den Pfad in Item.Caption schreiben, danach splitten, darum geht es mir aber nicht. Eine Eventlösung wäre mir lieber. Schon alleine, weil es mich interessiert. Edit: IconOK ist wohl Überbleibstel, kommt weg :) |
AW: Event Pfad an MenuItem übergeben (Problem)
Hey, das Menu ist generell nicht der richtige Ort um Daten zu parken. Was anderes als "Tag" brauchst Du aber auch nicht.
Speicher deine Informationen doch einfach in einem StringGrid. Der bekommt ein weiteres Feld "Index" das Du durchnummerierst. Dann kannst Du mit Hilfe von "Tag" den "Index" finden in dem die Daten stehen die Du brauchst. Eigentlich wäre eine MemTable besser, aber wenn Du schreibst, "Hobby", will ich Dich ja nicht gleich mit Profisachen plätten. |
AW: Event Pfad an MenuItem übergeben (Problem)
Es hatte aber auch niemand geschrieben wo genau das früher war.
Ich weiß zwar noch, dass man z.B. irgendwo eine GUID registrieren konnte, welche sich dann als Dateiname eines Verzeichnisses nutzen und so irgendwas verlinkten kann und das sollte auch immernoch möglich sein. (für Weiteres müsste ich auch erst wieder danach suchen) Beim .Tag oder .Objects in ListenKomponenten kann man Werte (Integer) angeben oder z.B. ein Datenobjekt verlinken. Ebenso kann man eine eigene Liste/Dictionary erstellen und mit Objektzeigern oder Name entsprechend was zu seinen Komponenten abspeichern. Wir haben TMenuItem abgeleitet und es gibt zusätzlich nochmal so was wie .Tag für String und Variant. Bei Menüs/Links im Dateisystem kann man ein Programm/Pfad angeben, teilweise/eventuell mit Parameter(n). |
AW: Event Pfad an MenuItem übergeben (Problem)
Danke für die Ansätze.
Ich werde mal mit .Tag versuchen. Mal schauen, wie es zu machen ist. Das kriege ich aber schon hin. Jetzt muss ich erst das Geschriebene umsetzen, danach sehen wir weiter. Noch mal, vielen Dank. |
AW: Event Pfad an MenuItem übergeben (Problem)
Ich habe gestern, versucht es mit .tag irgendwie zu realisieren.
Es gibt nur die Möglichkeit, mit dem Integer zu arbeiten. Das kriege ich so nicht hin. Mein Problem ganz kurz erklärt. Ich erfasse die .lnk Dateien, die lese ich aus, erfasse den Namen von der exe Datei und natürlich den Pfad zu der Datei. Befindet sich die .lnk Datei in einem Unterordner, wird ein Untermenü mit dem Namen des Ordners erstellt. Menüeinträge entsprechen den Unterordnernamen bzw.den Namen der .lnk Datei, allerdings ohne Erweiterung "lnk" Und hier ist das Problem. Wenn ich den Event auslöse, kann ich nicht erkennen, ob es ein Programm oder nur ein Unterordner ist. Mein Pfad wird global gesetzt, also brauche ich es nicht zu erfassen, allerdings den Namen des Unterordners muss ich im Event haben. Die Idee war, einfach den Namen des Unterordners an mein Event zu übergeben. Damit hätte ich den Namen (Caption) und die Location (Pfad + Unterordner). Ich habe alles probiert, mit dem Event von MenuItem kriege ich es nicht hin. Nun frage ich mich, ob man es nicht irgendwie über ein eigenes Event umbiegen kann. Dazu muss ich aber erst ein wenig lesen. Tipps, wie man eigene Events erstellt (einfach erklärt) wären super. |
AW: Event Pfad an MenuItem übergeben (Problem)
Hallo, du könntest auch TMenuItem ableiten und die Felder hinzufügen, die du benötigst.
Beim Hinzufügen verwendest du diese Klasse und hast dann im OnClick direkten Zugriff auf Informationen, die du benötigst. |
AW: Event Pfad an MenuItem übergeben (Problem)
@BerndS
leider ist deine Antwort zu allgemein, damit kann ich NOCH nichts anfangen. @himitsu Nur noch eine Frage zum .Tag Da ich nicht weiß wie viele Unterordner und wie viele Verknüpfungen in jedem Ordner vorhanden sind, kann ich schlecht eine For Schleife benutzen. In jedem Unterordner wird eigene For Schleife benutzt. ABER Global Index : Integer; Nun einfach fortlaufend eine Liste mit .lnk erstellen, gleichzeitig jedem Item eine .Tag Nummer vergeben, einfach mit Index := Index + 1; Damit hätte ich zu jeder Tag.Nummer eine Adresse. War es so gemeint? Gefallen tut es mir nicht wirklich, wäre aber auch eine Lösung. |
AW: Event Pfad an MenuItem übergeben (Problem)
Ich glaube Du solltest mal einen Tag Pause machen. Sieht bisschen so aus als wenn Du dir gerade selber im weg bist.
Du kannst faktisch mit allem arbeiten, Stringliste, generische (generics TList) Liste oder eben einen StringGrid oder eine Tabelle, etc. Es kommt nur drauf an wie man die Daten in den Listen parkt um alles unterzubekommen. Alle Listen haben automatisch einen Index für jeden Eintrag den Du in deinem Tag verwenden kannst. Und nein, ich bin nicht Himitsu, aber ich denke wir sehen das beide gleich ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 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