Autor Beitrag
matze
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 07.08.02 09:28 
Hallo !!!
Ich habe ein Programm entwickelt, das eine Linkliste besitzt. Wenn ich jetzt aber dieser Linkliste eine Link hinzufügt, muss ich den Leuten jedesmal eine neue Version meines Proggis geben, damit die auch die aktuellen Links haben !!! Das ist umständlich !!!

Ich habe mir daher gedacht, die Links in eine INI auszulagern, die dann nurnoch übers Internet geupdatet wird.

Aber wie mach ich sowas ??

wenn meine INI z.B. so ausschaut:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
 
[1] 
name = Web.de
url = www.web.de

[2]
name = Auq.de
url = www.auq.de


Wie kann ich aus einer InI die so ausschaut ein Menü erzeugen, das mir bei klick auf einen Menüeintrag die URL in dem Browserfenter läd oder per ShellExecute in dem Standardbrowser des systems ausgibt ???

Ich denke mal, dass sich das mit einer for- schleife machen liese, aber ich weiss nicht, wie ich die anzahl der sections rausbekomme und wie ich dann bei klick die URL aufrufe !!!

_________________
In the beginning was the word.
And the word was content-type: text/plain.
wwerner
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 185



BeitragVerfasst: Mi 07.08.02 09:36 
Mit ReadSections bekommst du schon mal die Sectionen:

Auszug asu Hilfe:

Zitat:
Reads the names of all sections in an INI file into a string list.

procedure ReadSections(Strings: TStrings); override;

_________________
Gruß

Wolfgang

----------
zu hause ist es doch am schönsten
cbs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 10:23 
Tag auch

speicher doch einfach vorher die anzahl der sektoren ab
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
[main]
anzahl=3

[1]
name=web.de
url=www.web.de

[2]
name=auq.de
url=www.auq.de

[3]
name=google.de
url=www.google.de

dann weißt du ja wieviele einträge die ini hat und ließt sie entsprechend aus
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  ini: TIniFile;
  cnt, anz: LongInt;
  name, url: string;
begin
  ini:= TIniFile.Create(FileName);
  anz:= ini.ReadInteger('main', 'anzahl', 0);
  for cnt:= 1 to anz do begin
    name:= ini.ReadString(IntToStr(cnt), 'name', '');
    url:= ini.ReadString(IntToStr(cnt), 'url', '');
    // erstelle jetzt den menü eintrag mit name und url
  end;
  ini.Free;
end;


PS: ich glaube zwischen bezeichner dem '=' und dem wert darf kein leerzeichen sein
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 07.08.02 10:53 
jo das wäre ne Idee, mit dem Anzahl abspeichern !!!

Aber wie bekommt ich den Befehl zum URL aufrufen in den Menü eintrag rein ???
Geht das vielleicht, dass man abfragt, welcher Menüeintrag geklickt wuirde und die nummer des menü eintrages der geklickt wurde irgendwie mit der nummer der INI section vergelicht :?

_________________
In the beginning was the word.
And the word was content-type: text/plain.
wwerner
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 185



BeitragVerfasst: Mi 07.08.02 11:03 

_________________
Gruß

Wolfgang

----------
zu hause ist es doch am schönsten
cbs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 11:09 
@matze: könnte so gehen ja. jeder menüeintrag hat doch die eigenschaft tag vom typ integer. diese eigenschaft wird nicht gebraucht, kannst sie also für dich nutzen. darin speicherst du dann zb. den index des eintrags in der ini.

wenn der tag=1 ist dann ließt du die url des ini eintrags 1 aus wenn tag=5 dann den ini eintrag 5 usw.

du kannst natürlich auch die ganzen urls auch gleich in ein TStringList object speichern. so das der index (tag) des menüeintrags dem des index in der StringListe eintspricht.

klickt der user auf ein menüeintag ließt du den tag aus und öffnest dann die url die dem index in der TStringListe entspricht
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 07.08.02 11:12 
hmmm..... das könnt klappen:

hier mal meine überlgeung (noch nicht getestet). könntet ihr die mla bite anschauen und mir sagen ob die funzen täte ??

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.FormCreate(Sender: TObject); 
var 
  NewItem: TMenuItem; 
  ini: TIniFile; 
  cnt, anz: LongInt; 
  name, url: string; 
begin 
  ini:= TIniFile.Create(FileName); 
  anz:= ini.ReadInteger('main', 'anzahl', 0); 
  for cnt:= 1 to anz do begin

    NewItem := TMenuItem.Create(Self); 
    NewItem.Caption := ini.ReadString(IntToStr(cnt), 'name', ''); 
    NewItem.OnClick := ShellExecute (ini.ReadString(IntToStr(cnt), 'URL', ''); //Ich weiss, dass der Befehl schmarrn ist, aber ich weiss momentan den genauen ShellExecute Befehl nicht.
    Fonts1.Add(NewItem); 

  end; 
end;



Ähmm aber in welches Menü schreibt der des dann eigendlich rein ??? Ich will das in ein PopUp menü reinhaben !!!

_________________
In the beginning was the word.
And the word was content-type: text/plain.
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 12:50 
Das extra Abspeichern der Anzahl halte ich (mit Verlaub!) für umständlich. Mit der schon von wwerner erwähnten Funktion ReadSections bekommst du eine Stringliste mit allen gültigen Sektionen der INI.

Sollte aus irgendeinem Grund nämlich die INI mal so aussehen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
[1] 
name = Web.de 
url = www.web.de 

[2] 
name = Auq.de 
url = www.auq.de

[4]
name = Irgendwo
url = www.irgendwo.net

weil irgendwer versehentlich oder aus Dummheit den Punkt #3 entfernt hat, dann wird deine Schleife mit großer Wahrscheinlich nicht mehr funktionieren, da du die Schleifenvariable ja als Sektionsreferenz benutzt. Sie liest also die Sektionen 1, 2 ... findet aber keine 3. :-(

Des Weiteren ließe sich die "Hint"-Variable des Menüeintrags für die URL zweckentfremden. Also, beim Einlesen die Caption auf den Namenseintrag, und den Hint auf die URL setzen, und im "OnClick" nur den Hint an ShellExecute weiterreichen. Ist einfacher und spart den ständigen Zugriff auf die INI-Datei.
wwerner
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 185



BeitragVerfasst: Mi 07.08.02 13:09 
Hey Mathias :!: Gute Idee :D

_________________
Gruß

Wolfgang

----------
zu hause ist es doch am schönsten
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 13:36 
Wie wäre es damit?
ausblenden volle Höhe 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:
uses
  IniFiles, ShellAPI;


// als private Prozedur deklarieren!
procedure TForm1.UrlClick(Sender: TObject);
begin
  with(Sender as TMenuItem) do
    if(Hint <> '') then ShellExecute(self.Handle,'open',pchar(Hint),nil,nil,SW_SHOWNORMAL);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  cIni : TIniFile;
  sl   : TStringList;
  i    : integer;
  mi   : TMenuItem;
begin
  cIni := TIniFile.Create(Filename);
  with cIni do
    try
      sl := TStringList.Create;
      try
        ReadSections(sl);

        if(sl.Count > 0) then
          for i := 0 to sl.Count - 1 do
            begin
              mi         := TMenuItem.Create(nil);
              mi.Caption := ReadString(sl.Strings[i],'name','');
              mi.Hint    := ReadString(sl.Strings[i],'url','');

              if(mi.Caption <> '') and (mi.Hint <> '') then
                begin
                  mi.OnClick := UrlClick;
                  PopupMenu1.Items.Add(mi);
                end;
            end;
      finally
        sl.Free;
      end;
    finally
      Free;
    end;
end;
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 07.08.02 16:03 
ähmmm. nur mal so ne frage: vergisst du nicht am ende die INI zu "free"en ?? oder ist das nicht wichtig, oder wird das mit den FREE gemacht ??

Und nur mal verständnis halber: Wieso muss man das als private Prozedur deklarieren ?

Ansonsten: DANKE MANN !!! Du bist meine Rettung !!! Das ist genau das was ich suche !!!!

_________________
In the beginning was the word.
And the word was content-type: text/plain.
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 18:06 
matze hat folgendes geschrieben:
ähmmm. nur mal so ne frage: vergisst du nicht am ende die INI zu "free"en ?? oder ist das nicht wichtig, oder wird das mit den FREE gemacht ??

Dann noch mal die gekürzte Form:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
cIni := TIniFile.Create(Filename); 
with cIni do 
  try 
    // Mach hier irgendwas mit der INI
  finally 
    Free; 
  end;

Frage beantwortet? :wink:

Das einzige, was man noch machen könnte, wäre, die TMenuItems wieder freizugeben, wenn sie weder Caption noch Hint haben. Dann haben sie nämlich keine Bezeichnung und keine URL und werden ohnehin nicht ins Menü aufgenommen (s. if).

Zitat:
Und nur mal verständnis halber: Wieso muss man das als private Prozedur deklarieren?

Ich hoffe, du meinst jetzt nicht die "OnCreate" der Form. Mit der privaten Prozedur ist nur "UrlClick" gemeint - und die muss man nicht unbedingt so deklarieren. "public" wäre auch okay. Aber wenn du sie nur in der Form1 benötigst, dann ist gegen "private" nichts einzuwenden. Und verkehrt ist es ja auch nicht.

Gruß.
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 07.08.02 20:23 
also reicht es die INI einfach mit free; freizugeben statt mit cINI.free; ??

_________________
In the beginning was the word.
And the word was content-type: text/plain.
cbs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.08.02 20:27 
@matze: ne, wenn dann muss es schon cINI.free; sein.
in dem fall reicht aber auch Free wegen dem with

schau mal in die hilfe wenn de nich weißt was das ist und macht

@MathiasSimmack: hast völlich recht. das mit der anzahl war nich so gut :oops:
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 08.08.02 10:43 
@cbs: Normalerweise wäre das mit der Anzahl auch meine erste Idee gewesen. Allerdings hätte ich sie nicht gespeichert, sondern gleich die for-Schleife von 1 bis X hochgezählt ... und abgebrochen, wenn er die Sektion nicht finden kann. Aber das hätte genau die selben Probleme verursacht, wenn irgendjemand eine Sektion mutwillig entfernt. Deswegen finde ich den Weg über ReadSections sicherer.

@matze: Sorry, für einen Augenblick dachte ich, du willst mich verar.... Ich hatte angenommen, du kennst die Vorteile von with. Kurz gesagt: in diesem Fall sparst du dir die Angabe von
ausblenden Quelltext
1:
cReg.					

Das funktioniert eigentlich bei allen Komponenten und Objekten. Du kannst auch mehrere Eigenschaften durch Komma getrennt angeben, etwa:
ausblenden Quelltext
1:
with TreeView1,Items					

dann kannst du sowohl auf die Membervariablen von "TreeView1" zugreifen (zu denen ja "Items" auch gehört), als auch direkt auf die Membervariablen von "Items".

Eine bessere Erklärung findest du in der Hilfe, denke ich. :-)
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 21.08.02 08:00 
So, nach langer Zeit (urlaub) hab ich mal das getesten und ich habe folgendes Probelm:

Immer wenn ich den Code
ausblenden Quelltext
1:
2:
3:
4:
5:
procedure TForm1.UrlClick(Sender: TObject); 
begin 
 with(Sender as TMenuItem) do 
  if(Hint <> '') then ShellExecute(self.Handle,'open',pchar(Hint),nil,nil,SW_SHOWNORMAL); 
end;

unter private in meinem Quelltext schreibe kommen hein Haufen Fehlermeldungen.

END erwartet aber BEGIN gefunden.
Undefinierter Bezeichner URLklick.
Undefinierter Bezeichner TForm1.
Undefinierter Bezeichner TObject.

usw...

Was mache ich da falsch :cry:

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Mi 21.08.02 09:15 
Du musst natürlich in der Privatesection nur den Procedure-Kopf definieren:
ausblenden Quelltext
1:
2:
Private
  Procedure UrlClick (Sender: tObject);

Und dann kannst Du die Proceduer im Implementations-Teil Deiner Unit hinzufügen.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Implementation

{...}

procedure TForm1.UrlClick(Sender: TObject); 
begin 
  with Sender as TMenuItem do 
    if Hint <> '' then 
      ShellExecute (
          Handle,
          'open',
          PChar (Hint), 
          nil, nil, 
          SW_SHOWNORMAL
        ); 
End;

Du musst tForm1 dann wahrscheinlich noch umbennen. So wie halt das Objekt heißt in dem es definiert wurde.

Gruß
TINO
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 21.08.02 13:36 
jo ich hab alles so gemacht, wie du es gesagt hast, aber wie muss ich das denn umbennen ?? ich hab folgendes probiert:
ausblenden Quelltext
1:
2:
3:
Tpopupmenu1.UrlClick;
Tpopupmenu.UrlClick;
Tform1.UrlClick;

das alles klappt nicht

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Mi 21.08.02 14:14 
Es muss so heißen wie das Objekt in dem die Procedure definert ist. Ansonsten poste mal den Code.

Gruß
TINO
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Mi 21.08.02 15:00 
ich hba den code von MatthiasSimmack (oben) unverändert übernommen !!!

Nur dass ich das procedure TForm1.UrlClick(Sender: TObject); (das ja nicht funzt) in procedure TPopUpMenu1.UrlClick(Sender: TObject); umgeändert habe. Das funzt allerdings auch nicht :cry:

_________________
In the beginning was the word.
And the word was content-type: text/plain.