Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Problem mit MessageDlg


Ikkarus13 - Di 21.10.03 07:24
Titel: Problem mit MessageDlg
Hi Leute,

ich habe ein echt seltsames Problem. Ich will innerhalb einer Schleife auf den Tastendruck des Users reagieren, wenn er auf Abbruch klickt. Das funktioniert ja auch noch. Aber ich habe ja dann noch ne Sicherheitsabfrage, ob er das auch wirklich will. Abfragen tut es das ja auch, aber es reagiert nicht auf die Antwort. Egal was ich mache er überspringt die Antwort einfach. Hier mal den Teil des Codes:

Quelltext
1:
2:
3:
      if abbruch = true then
          if MessageDlg('Wirklich abbrechen?', mtConfirmation,[mbYes,mbNo], 0) = mryes then
              exit;


Ich hoffe mir kann da einer helfen. Schon mal vielen Dank.


Delete - Di 21.10.03 08:55

Mit exit springst du aus der ganzen Prozedur raus. Zeig mal die ganze Prozedur, bzw alls was noch kommt.


Ikkarus13 - Di 21.10.03 09:03

Das Problem ist ja, das er gar nicht bis zum Exit kommt. Die Restliche Prozedur besteht nur aus einer "for to do" schleife. In der schleife wird das mit dem MessageDlg abgefragt. Aber er überspringt nach dem Beantworten des Dialogs einfach die Exit Anweisung.

Den Code kann ich gerade nicht Posten, weil ich auf der Arbeit bin.


joerg68 - Di 21.10.03 09:13

Versuchs mal so

Delphi-Quelltext
1:
2:
3:
4:
5:
if Abbruch = true then
 begin
  if MessageDlg('Wirklich abbrechen?', mtConfirmation,[mbYes,mbNo], 0) = mryes then 
                  exit; 
 end;


Gruss
Jörg


Ikkarus13 - Di 21.10.03 09:23

Werde ich mal in der Mittagspause versuchen, aber glaubst du wirklich, das es was bringt???


joerg68 - Di 21.10.03 09:31

poste mal die ganze prozedur falls mein vorschlag nichts bringt
Gruss
Jörg


patrick - Di 21.10.03 09:36

ich hab das grad mal ausprobiert und wie ich erwartet habe funktionieren beide lösungen gleich, ich hab auch ehrlichgesagt nichts anderes erwartet.

schreib doch mal probeweise eine schowmessage hinter den exit befehl und schau ob dieser aufgerufen wird.

die frage ist ob mit exit nur eine schleife oder alle schleifen abgebrochen werden.
das hab ich noch nie ausprobiert, wäre aber eine erklärung.


barfuesser - Di 21.10.03 09:47

@patrick: Exit entzieht der aktuellen Prozedur sofort die Ablaufsteuerung! Um Schleifen abzubrechen gibt es break.

barfuesser


Ikkarus13 - Di 21.10.03 09:48

Währe keine erklärung, weil ich ja nicht mal zum exit komme, er überspringt es, und macht im normalen Code weiter. Weil dann natürlich abbruch = true ist, wird das Fenster dann auch noch andauernd angezeigt, und bei jedem Yes oder no, wird einmal die Schleife weiter durchlaufen.


barfuesser - Di 21.10.03 10:08

@Ikkarus13: Ich bezog mich auf patrick und nicht auf Dich. Um zu Dir etwas mehr sagen zu können, warte ich lieber auf den kompletten Quellcode der entsprechenden Prozedur.

barfuesser


Ikkarus13 - Di 21.10.03 12:48

So, hier mal die ganze Prozedur.

Delphi-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:
procedure TForm1.Button2Click(Sender: TObject);
var
  datei : tid3v1;
  datei2 : tid3v2;
  i, j, k : integer;
begin

abbruch := false;
datei := tid3v1.Create;
datei2 := tid3v2.Create;
j := 0;
k := 0;
for i := 0 to listbox1.items.count -1 do
  Begin

      if abbruch = true then
          if MessageDlg('Wirklich abbrechen?', mtConfirmation,[mbYes,mbNo], 0) = mryes then
              exit;

      try
              if datei.Removefromfile(listbox1.items[i]) then
                  inc(j);
              if datei2.RemoveFromFile(listbox1.items[i]) then
                  inc(k);
      except
          showmessage('Fehler bei Datei'+ listbox1.items[i]);
      end;
      Application.ProcessMessages;
  end;
label4.Caption := inttostr(j);
label6.Caption := inttostr(k);
datei.Free;
datei2.Free;
end;


Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.


barfuesser - Di 21.10.03 13:21

Hier mal mein funktionierender Test:

Delphi-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:
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:
76:
77:
78:
79:
unit DF_TestForm;

interface

uses
  Forms, StdCtrls, ComCtrls, Messages, Controls, Classes;

type
  TDasForm = class(TForm)
    StartBtn: TButton;
    StatusBar: TStatusBar;
    StopBtn: TButton;
    procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean);
    procedure StartBtnClick(Sender: TObject);
    procedure StopBtnClick(Sender: TObject);
  private
    { Private-Deklarationen }
    terminate: Boolean;
  public
    { Public-Deklarationen }
  end;

var
  DasForm: TDasForm;

implementation

uses
  Windows, SysUtils, Dialogs;

{$R *.dfm}

procedure TDasForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  if Msg.CharCode = VK_ESCAPE then
  begin
    Handled := true;
    Close;
  end;
end;

procedure TDasForm.StartBtnClick(Sender: TObject);
var
  idx: Integer;
begin
  StartBtn.Enabled := false;
  StartBtn.Default := false;
  StopBtn.Enabled  := true;
  StopBtn.Default  := true;

  terminate := false;
  for idx := 0 to 250000 do
  begin;
    StatusBar.SimpleText := IntToStr(idx);
    Application.ProcessMessages;
    if terminate then
      case MessageDlg('Wirklich abbrechen?', mtConfirmation,[mbYes,mbNo], 0of
        mrYes: begin
                 StopBtn.Enabled  := false;
                 StopBtn.Default  := false;
                 StartBtn.Enabled := true;
                 StartBtn.Default := true;

                 Exit;
               end;
        mrNo:  begin
                 terminate := false;
                 Application.ProcessMessages;
               end;  
      end;
  end;
end;

procedure TDasForm.StopBtnClick(Sender: TObject);
begin
  terminate := true;
end;

end.

barfuesser


Ikkarus13 - Di 21.10.03 13:32

Also ich habe es mal mit dem Case of versucht, funzt aber auch nicht, er überspringt einfach den exit befehl.


barfuesser - Di 21.10.03 13:41

Versuch mal meinen geposteten Text ohne Änderung auszuführen. Brauchst dazu nur ein Formular names DasForm, darauf eine StatusBar namens StatusBar und zwei Buttons names StartBtn und StopBtn. Die automatisch erzeugte Unit ersetzt Du einfach durch meine Gepostete.
Das sollte dann eigentlich funktionieren. Wenn ja, passe das Ganze an Deine Bedürfnisse an, wenn nein, melde Dich noch mal.

barfuesser


Delete - Di 21.10.03 15:15

barfuesser hat folgendes geschrieben:
Versuch mal meinen geposteten Text ohne Änderung auszuführen. Brauchst dazu nur ein Formular names DasForm, darauf eine StatusBar namens StatusBar und zwei Buttons names StartBtn und StopBtn. Die automatisch erzeugte Unit ersetzt Du einfach durch meine Gepostete.

Alternativ dazu hättest du auch seine Form- und Controlnamen benutzen können. :roll:


Terra23 - Di 21.10.03 16:57

... mag ja sein, daß ich einiges überlesen habe, aber meiner Meinung nach dürfte er dir noch nichtmal die Message geben, denn du sagst ein paar Zeilen vor der Abfrage, daß "Abbruch" False werden soll.. :roll:


barfuesser - Di 21.10.03 17:29

Die Variable Abbruch wird aus einer anderen Procedure heraus auf true gesetzt. Dafür auch das ProcessMessages.

barfuesser


Terra23 - Di 21.10.03 18:47

... OK; mein Fehler.. :oops:


Ikkarus13 - Mi 22.10.03 07:18

:lol:

Ich bin ja so Happy

Habe es endlich geschaft. Es hat nur an etwas gelegen, was ich wohl ausversehen in meine uses geschrieben habe. Dort stand nämlich qdialog, was auch immer das sein soll.

Danke an alle nochmal, die mir helfen wollten.


Delete - Mi 22.10.03 07:36

qdialog ist eine Unit der CLX. Da scheint sich der MessageDlg anders zu verhalten.