ResFiles + Windows Unit und Programm beenden

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

ResFiles + Windows Unit und Programm beenden

Beitrag von bembulak »

Hallo Freunde!

Ich habe heute wieder mal ein paar Fragen und hoffe, ihr könnt mir helfen. Es geht also nicht um ein spezifisches Problem, als vielmehr um einige grundlegende Fragen zu Lazarus und FPC.

Ich fange also einfach mal an:
  • Ich habe mit Hilfe dieses Tutorials aus dem Wiki eine *.RES Datei erstellt (mit Windres) und auch schon erfolgreich zum Laufen gebracht.
    Meine Frage dazu stellt sich folgendermaßen zusammen: ich muss mit der Compilerdirektive (ist es eine?)

    Code: Alles auswählen

    {$ifdef win32}
      {$R ginttu.res}
    {$endif}
    die *.res-Datei einbinden. Wie das vom Compiler dann gehandhabt wird, kann mir eigentlich egal sein, solange es funktioniert, denn das tut es ja auch wunderbar. Ich muss allerdings die Unit "Windows" einbinden. Meine Frage dazu ist: was tut diese Unit? Stellt sie WinAPI-Sachen zur Verfügung, oder wie? Ohne diese Unit könnte ich beim Erstellen der Form1 das Icon nicht laden.

    Code: Alles auswählen

    procedure TForm1.FormCreate(Sender: TObject);
    const
         IDI_ICON1 = 101;
    begin
         TrayIcon1.Icon.Handle:= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
         TrayIcon1.PopUpMenu := PopupMenu1;
    end;
    Muss diese Konstante (IDI_ICON1) genau diesen Wert haben? Woher weiß ich, dass ich 101 nehmen muss? Und was sind und bewirken

    hInstance und MAKEINTRESOURCE()? Kann mir dazu jemand ein paar Informationen geben? Ich wäre sehr dankbar!
  • Mein Programm hat also ein TrayIcon und die OnClose - Aktion wird mit

    Code: Alles auswählen

    procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    begin
      CloseAction := caNone;
      TrayIcon1.Visible:= True;
      Form1.Visible:= False;
    end;
    ausser Kraft gesetzt und das Fenster nur "versteckt". Dafür habe ich dann das TrayIcon, welches über eine Menü verfügt, über den ich das Fenster wieder anzeigen kann, bzw. das Programm über das TPopupMenu schließen will. Hier nun meine Frage: welcher Weg ist der sauberste, um das Programm zu beenden. Ein Einfaches

    Code: Alles auswählen

    procedure TForm1.MenuItem2Click(Sender: TObject);
    begin
      //Dies ist "Exit" im TPopupMenu
      Close;
    end;
    funktionier leider nicht. Die Applikation läuft weiter (bzw. sieht es nicht so aus, als würde der Debugger das begreifen).
    Eine ander Möglichkeit wäre

    Code: Alles auswählen

    procedure TForm1.MenuItem2Click(Sender: TObject);
    begin
      Application.Terminate;
      // ist Application.Terminate der richtige Weg?
    end;
    , aber ist dies auch der richtige Weg? Ich meine, ist Terminate nicht ein Weg mit dem Holzknüppel?

    Also: wie kann ich das Programm sauber beenden und eventuell noch Aufräumarbeiten (Dateien speichern, Objekte freigeben, ...) durchführen.
    Wieder wäre ich für ein wenig Information sehr dankbar.
Einen schönen Abend wünsche ich euch allen!

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Ich würde im OnClose Event auswerten, per Sender, wer das Schliessen angeforder hat. Wars der richtige, wir geschlossen ansonsten versteckt.

Dein Problem ist, das du mit Close, den OnCloseEvent triggerst, der sagt nein, deshalb kannst du deine Anwendung nur mittels Terminate abwürgen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

Ich habe jetzt leider das Projekt nicht hier und kann es im Moment auch nicht nachbauen, aber nur mal so aus dem Kopf - könnte dies dann so funktionieren?

Code: Alles auswählen

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if Sender = Button1 then
    begin
      CloseAction := caNone;
      TrayIcon1.Visible:= True;
      Form1.Visible:= False;
    end
  else
    begin
      CloseAction := caKEINEAHNUNG; //die IDE bietet mir hier: caFree, caHide, caMinimize,
      Close;
    end;
  end;
end;

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Du musst die CloseAction nicht setzen ...
Lass sie einfach in ruhe wenn du die Anwendung normal schliessen willst ich glaub ist per default auf cafree.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

OK, aber ist "CloseAction" nicht eine Eigenschaft von Form1?
Ich meine, wenn die Prozedur vom Sender "Button1" aufgerufen wird, wird dann nicht das Property "CloseAction" auf "caNone" gesetzt? Oder meinst du, ich soll mir das sparen? Wenn aber CloseAction per default "caFree" ist, kommt meine Prozedur ja gar nicht mehr dazu, das Fenster zu verstecken... (so ist meine Theorie).

Wenn dann die Prozedur von der Form selbst aufgerufen wird, ist "CloseAction" ja immer noch "caNone", da CloseAction ja per "Call by Value" übergeben wird. Und dann funktioniert ein simples "Close" ja wieder nicht. Das ist ja, wie oben schon beschrieben ein gegewärtiges Problem (in einer anderen Prozedur).

Oder habe ich da jetzt was ganz falsch verstanden.
Für jede Info dankbar.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Die CloseAction NUR dann ändern, wenn du das Verhalten auch ändern willst. Falls es zB. nicht von deinem Button kommt, ganze einfach NICHTS machen.

Code: Alles auswählen

procedure TForm1.FormClose%u28Sender%u3a TObject; var CloseAction%u3a TCloseAction%u29;
begin
   // Nur wenn die Anforderung von Button1 kommt verstecken !!
  if Sender = Button1 then
    begin
      CloseAction %u3a= caNone;
      TrayIcon1.Visible%u3a= True;
      Form1.Visible%u3a= False;
    end;
   // Ansonsten nichts tun, denn dann schliesst sich das Formular richtig - das ist default !!
end;
Diese Prozedur wird ja erst dann aufgerufen, wenn es bereits ein Close Anforderung gibt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

Aha, dann war ich ein klein wenig auf dem Holzweg. Aber ich werde es versuchen und dann berichten.

Vielen Dank für die Hilfe!

shokwave
Beiträge: 475
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Beitrag von shokwave »

Das hab ich auch mal so probiert, jedoch war der Sender in FormClose immer Form1, egal ob ich über x oder das MainMenu geschlossen hab.

Ich habs damals aufgegeben und im Menü 'ne Variable gesetzt die das "richtige" schließen abfragt.

Falls das mit dem Sender doch funzt, wär ich an 'ner Lösung interessiert.

mfg Ingo
mfg Ingo

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

shokwave hat geschrieben:Das hab ich auch mal so probiert, jedoch war der Sender in FormClose immer Form1, egal ob ich über x oder das MainMenu geschlossen hab.
Ich fürchte das du recht hast, da das Close nur indirekt vom Button ausgelöst wird, Event aber vom Fenster ausgelöst wird.

Wenn mein System wieder konfiguriert ist, werde ich mir mal genau ansehen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

So, ich habe meine Prozedur nun mal umgeschrieben und das funktioniert vorerst mal.

Code: Alles auswählen

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if Sender = Form1 then
  begin
       CloseAction := caNone;
       TrayIcon1.Visible:= True;
       Form1.Visible:= False;
  end
  else if Sender = MenuItem2 then
  begin
       Close;
  end;
end;
Nur, wie mache ich es nun, dass ich vom MenuItem2 aus die Prozedur FormClose() aufrufe?
Theoretisch müsste es ja in etwa so laufen:

Code: Alles auswählen

procedure TForm1.MenuItem2Click(Sender: TObject);
begin
     Form1Close(MenuItem2, {keine Ahnung wie der 2te Parameter aussieht});
end;
Nur leider hänge ich da komplett. Ich bekomme die FormClose Prozedur einfach nicht dazu von MenuItem2 aus ausgeführt zu werden. Was habe ich übersehen?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

FormClose wird vom Formular selbst aus aufgerufen, wenn es eine Forderung bezüglich Close gibt.

Du darfst somit nur das Close vom Formular aufrufen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Eine Lösung die läuft ist:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  self.Tag:= 1;
  close;
end;
 
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
  if self.Tag <> 1 then CanClose := false;
end;
Bevor wir hier noch viel länger herumdiskutieren. Das wird sicher in der nächsten Ausgabe von LazInfos drinnenstehen - so wie andere Sachen schon jetzt enthalten sind.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

Form1.Close funktioniert aber nicht.
Ich weiß schon nicht mehr, wie ich es angehen soll.
Ausser Application.Terminate will einfach nichts funktionieren.

Und wie gesagt, das kommt mir doch arg brutal vor. Es muss doch eine Möglichkeit geben. :(

Ich habe nun verschiedene Sachen probiert. Ich habe versucht, CloseAction EXPLIZIT wieder auf caFree zu setzen, ich habe versucht, die unsichtbare Form vor dem Schließen nochmals kurz sichtbar zu machen. In der FormClose - Prozedur wird der Sender ausgewertet (wie wir besprochen hatten), aber ausser dem bösen, bösen Terminate (ist es so böse?) will nix funktionieren.
Ich belasse es jetzt einfach mal dabei.

Danke trotzdem.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Die Lösung vorher ist aus einem laufenden Beispiel. Den Code kann ich dir gerne zukommen lassen. Umgekehrt könntest du mir den Code mit dem "bösen" Beispiel schicken und ich sehe mir den mal an.

Terminate ist nicht böse. Es gibt halt der Applikation und den Objekten halt keine Möglichkeit den Heap aufzuräumen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6857
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Nachtrag: Das Trayicon ist lustig - es schliesst mir alles - inklusive Lazarus zur Designzeit. Liegt vermutlich an GTK 2 & 64 Bit
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten