Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close; ?) (https://www.delphipraxis.net/190002-messagedlg-ueber-den-default-button-automatisch-schliessen-meincustomdialog-close%3B.html)

RandomDD 18. Aug 2016 19:14


MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close; ?)
 
Ich erzeuge an gewissen Stellen einen MessageDlg in meinem Programm die auch automatisch wieder geschlossen werden.
Das geht ganz einfach über einen Timer und mit
Delphi-Quellcode:
MeinCustomDialog.Close;
Bei ShowModal ist das Resultat demnach immer 2. Also idCancel.
Wie kann ich den Dialog so schließen, dass der Default-Button, welcher übrigens fokusiert ist, als Resultat zurückgeht?

Luckie 18. Aug 2016 19:30

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Welchen Sinn hat ein sich selbst schließender Dialog?

RandomDD 18. Aug 2016 19:32

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
So einige gibt es da. Bei mir hat es aktuell denn Sinn, dass wenn man mein Programm ferngesteuert und ein Dialog aufkommt, er geschlossen wird damit die Fernsteuerung nicht blockiert wird. Es gibt auch einen bestimmten Modus wo keine Dialoge angezeigt werden. Aber ich habe gelernt, dass man immer vom "DAU" ausgehen muss.

Luckie 18. Aug 2016 19:36

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Und wenn der DAU gerade mal kurz auf Toilette ist? Dann sieht er den Dialog doch nicht. Also brauchst du auch keinen. Da ja wohl keine Benutzer Interaktion erforderlich ist.

Sinnvoller wäre es eine Logdatei zu führen und am Ende darauf hinzuweisen. Da kann man sich dann alle Meldungen angucken.

RandomDD 18. Aug 2016 19:40

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Das mit den logs werde ich noch umsetzen, danke für den Hinweis.

Der DAU sieht die Dialoge auch so nicht, wenn die Software ferngesteuert wird. Aber wenn ein Dialog angezeigt wird - er kann ihn ja nicht wegklicken. Daher der Auto-Close, den ich für recht sinnvoll halte.
Nur ich komme nicht dahinter, wie ich ihn so schließe, dass der Default-Button als Wert zurückgegeben wird beim ShowModal. Denn Bei .Close; kommt immer Cancel zurück.

RandomDD 18. Aug 2016 20:35

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Gibt es keine Möglichkeit?
Eventuell mit SendMessage denke ich mir. Aber ich wüsste nicht, wie man herausbekommt, dass der Default-Button geklickt werden soll.

RandomDD 18. Aug 2016 21:06

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Für alle Interessierten, hier meine Lösung:

Delphi-Quellcode:
// Dialog erzeugen
MeinCustomMsgDialog := CreateMessageDialog(DlgText, mtInformation, [mbYes, mbNo], mbNo);
DialogDefaultButton := TButton(MeinCustomMsgDialog.ActiveControl);
Delphi-Quellcode:
// Default Button anklicken
if DialogDefaultButton.Handle <> 0 then
 SendMessage(DialogDefaultButton.Handle, BM_CLICK, 0, 0)
else
 DialogDefaultButton.Close;

Benedikt Magnus 18. Aug 2016 22:14

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Wäre es nicht einfacher, an der Stelle, an der du den Dialog automatisch schließt, dieses festzuhalten (Booleanvariable) und dann beim Abrufen des Dialogergebnisses zu berücksichtigen?

RandomDD 18. Aug 2016 22:18

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Ich habe deine Frage nicht ganz verstanden.

Benedikt Magnus 19. Aug 2016 07:31

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Wenn ich das richtig sehe, klickst du jetzt den gewünschten Button des Dialogs über eine Message. Wäre es nicht eleganter, eine Variable á la "WurdeAutomatischGeschlossen" anzulegen, die nach dem Schließen zusammen mit dem Rückgabewert des Dialogs überprüft wird?

RandomDD 19. Aug 2016 09:39

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Wofür wäre diese Variable denn dann? Komme nicht ganz dahinter.

Den messageDlg muss ich leider über eine Message klicken, da er sonst nur geschlossen wird (Rückgabwert Cancel, 2), auch wenn der Button Cancel nicht existiert.

bra 19. Aug 2016 09:57

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Ich verstehe den Sinn nicht, einen MessageDlg anzuzeigen, der sich automatisch schließt - also nie angeklickt wird. Wäre es nicht sinnvoller, hier stattdessen ein Banner anzuzeigen?

Oder soll das eine Art Nagscreen sein, der nach x Sekunden zugeht, vom Benutzer aber auch schon vorher weggeklickt werden kann?

Luckie 19. Aug 2016 10:05

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Habe ich auch schon gesagt. Nur seine Antwort nicht ganz verstanden. In der Statusleiste einfach die letzte Benachrichtigung anzeigen. Fertig.

Benedikt Magnus 19. Aug 2016 10:30

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Zitat von RandomDD (Beitrag 1345246)
Wofür wäre diese Variable denn dann? Komme nicht ganz dahinter.

Den messageDlg muss ich leider über eine Message klicken, da er sonst nur geschlossen wird (Rückgabwert Cancel, 2), auch wenn der Button Cancel nicht existiert.

Du machst das nun so:
Delphi-Quellcode:
// Dialog erzeugen
MeinCustomMsgDialog := CreateMessageDialog(DlgText, mtInformation, [mbYes, mbNo], mbNo);
DialogDefaultButton := TButton(MeinCustomMsgDialog.ActiveControl);

// Default Button anklicken
if DialogDefaultButton.Handle <> 0 then
 SendMessage(DialogDefaultButton.Handle, BM_CLICK, 0, 0)
else
 DialogDefaultButton.Close;

//Auswertung von MeinCustomMsgDialog
case CreateMessageDialog.ShowModal of
  mbYes: MacheWasBeiJa;
  mbNo: MacheWasBeiNein;
end;
Ich meinte es so:
Delphi-Quellcode:
// Dialog erzeugen
MeinCustomMsgDialog := CreateMessageDialog(DlgText, mtInformation, [mbYes, mbNo], mbNo);

// Dialog schließen:
DialogWurdeAutomatischGeschlossen := true;
MeinCustomMsgDialog.Close;

//Auswertung von MeinCustomMsgDialog
case CreateMessageDialog.ShowModal of
  mbYes: MacheWasBeiJa;
  mbNo: MacheWasBeiNein;
  else if DialogWurdeAutomatischGeschlossen then MacheWasBeiAutomatischemSchließen;
end;
EDIT:
Aber natürlich ist der Vorschlag der anderen, das anders zu realisieren, z.B. über ein Banner, immer noch sinnvoller.

RandomDD 19. Aug 2016 10:44

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Das mit dem Banner halte ich für nicht sinnvoll. Es ist auch kein Nagscreen oder ähnliches.
Es ist einfach eine Nachricht, die angezeigt und bestätigt werden muss. Wird sie nicht innerhalb des Timeouts bestätigt, gilt die Aktion als abgebrochen.

Verstehe nicht, was daran nicht zu verstehen ist. :o

Luckie 19. Aug 2016 11:00

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Und wenn ich da eben mal nicht am Rechner bin, wenn der MessageDlg aufpoppt, muss ich die Aktion von vorne starten? Ich muss also die ganze Zeit auf den Bildschirm starren?

Irgendwie ist das Konzept nicht ganz rund für meine Augen.

RandomDD 19. Aug 2016 11:21

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Die Aktion dauert in etwa 10 bis 20 Millisekunden. So schlimm wird es also nicht sein :-D

Der Nutzen ist ganz einfach: wenn man die Software fernsteuert und warum auch immer nicht den Modus dafür eingeschaltet hat und dann ein Dialog aufpoppt, ist die Fernsteuerung nutzlos und kann nichts mehr ausrichten.

himitsu 19. Aug 2016 13:03

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Also, man kann den Dialog auch z.B. um eine "automatisch schließen"-CheckBox erweitern .

Ich lass auch einen Timer laufen, welcher im Knopf, bzw. in der Title-Caption den TimeOut anzeigt.
Bei Mausbewegung oder Tastenklick wird der TimeOut deakiviert.

Zum Schließen kann man das Click vom Button aufrufen, oder ModalResult der Form/Dialog setzen.
Delphi-Quellcode:
TButton(DialogDefaultButton).Click;
// oder
TButton(MeinCustomMsgDialog.FindComponent('OK')).Click;
// oder
MeinCustomMsgDialog.ModalResult := mrOK;
PS: Bie Buttons heißen so, wie die Parameter.
mbCancel -> Control.Name='Cancel' -> ModalResult:=mrCancel


Bei Dialogen via ShowMessage und Co. kommt es drauf an, ob die "neue" Dialog-API vom Windows oder die eigenen TMessageDialog-VCL-Klassen verwendet werden.
Dementsprechend muß der Code anders sein, also ob VCL oder Windows-Dialog-API.

Via Screen.Forms oder Screen.ActiveForm kommt man auch nachträglich an die VCL-Dialoge ran.

MeinCustomMsgDialog.ActiveControl:
Man kann auch in MeinCustomMsgDialog.Components den TButton/TCustomButton mit TButton().Default=True suchen ... das ist definitiv der Default-Button.

p80286 19. Aug 2016 13:35

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Zitat von RandomDD (Beitrag 1345270)
Die Aktion dauert in etwa 10 bis 20 Millisekunden. So schlimm wird es also nicht sein :-D

Der Nutzen ist ganz einfach: wenn man die Software fernsteuert und warum auch immer nicht den Modus dafür eingeschaltet hat und dann ein Dialog aufpoppt, ist die Fernsteuerung nutzlos und kann nichts mehr ausrichten.

Das was Du haben willst findet man https://de.wikipedia.org/wiki/Totmanneinrichtung
Nur, wenn eine Fernsteuerung (was immer das sein mag) möglich ist ohne den entsprechenden Modus (was darf man darunter verstehen) einzuschalten, solltest Du das Bedienkonzept Deiner Software einmal überdenken.

RandomDD 19. Aug 2016 13:40

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Nur, wenn eine Fernsteuerung (was immer das sein mag) möglich ist ohne den entsprechenden Modus (was darf man darunter verstehen) einzuschalten, solltest Du das Bedienkonzept Deiner Software einmal überdenken.
Der Modus aktiviert nicht die Fernsteuerung sondern er unterbindet das Anzeigen von Dialogen.

Zitat:

Bei Mausbewegung oder Tastenklick wird der TimeOut deakiviert.
Gute Erweiterung. Habe ich soeben auch hinzugefügt.
Delphi-Quellcode:
 procedure MeinCustomMsgDialogOnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

 // ...

 MeinCustomMsgDialog.OnMouseMove := MeinCustomMsgDialogOnMouseMove;

 // ...

 procedure TMeineForm.MeinCustomMsgDialogOnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
 begin
  MeinCustomMsgDialogTimer.Enabled := False;
  MeinCustomMsgDialogCounterLabel.Visible := False;
 end;

p80286 19. Aug 2016 13:57

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Zitat von RandomDD (Beitrag 1345293)
Der Modus aktiviert nicht die Fernsteuerung sondern er unterbindet das Anzeigen von Dialogen.

Und warum gibt es dann keine Zwangskoppelung?

Gruß
K-H

RandomDD 19. Aug 2016 14:00

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Das Wort fällt jetzt zum ersten Mal. Was genau meinst du damit? Klingt interessant.

EWeiss 19. Aug 2016 14:37

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
So wie mir bekannt ist hat ein Dialog seine eigene Message Queue.
Demnach sollte ein einfaches WM_DESTROY reichen.

Dort wird dann PostQuitMessage(0); ausgelöst und die Message Queue beendet.
Zumindest haben meine Selbsterstellten Dialoge diese besagte Message Queue.

gruss

himitsu 19. Aug 2016 14:52

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Zitat von EWeiss (Beitrag 1345303)
So wie mir bekannt ist hat ein Dialog seine eigene Message Queue.

nJAin

VCL-Dialoge haben standardmäßig niemals eine eigene Message-Queue, schon alleine deswegen, da die VCL nicht thread-save ist.
Da läuft alles im Hauptthread und in dessen Queue.

EWeiss 19. Aug 2016 14:57

AW: MessageDlg über den Default-Button automatisch schließen (MeinCustomDialog.Close;
 
Zitat:

Zitat von himitsu (Beitrag 1345304)
Zitat:

Zitat von EWeiss (Beitrag 1345303)
So wie mir bekannt ist hat ein Dialog seine eigene Message Queue.

nJAin

VCL-Dialoge haben standardmäßig niemals eine eigene Message-Queue, schon alleine deswegen, da die VCL nicht thread-save ist.
Da läuft alles im Hauptthread und in dessen Queue.

Das scheint mir aber die (beste) einfachste Lösung..
Example:

Delphi-Quellcode:
function TSkinBrowseForFolder.ShowBrowseFolderDialog: TBrowseFolderDialogConstant;
var
  Msg: TMsg;

begin
  MoveWindow(Handle, x, y, rc.Right + 1, rc.Bottom + 1, True);

  SkinEngine.ShowMainWindow(Handle, 0);
  EnableWindow(HParent, False);

  // Windows Messagen verarbeiten
  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

  EnableWindow(HParent, true);

  Result := DlgConstant;

end;
Wird dann einfach so aufgerufen..
Ausschnitt..
Delphi-Quellcode:
          IDM_AddFolder:
            begin
              if not Assigned(BrowseForFolder) then
                AddBrowseForFolderControls(MainHandle);

              BrowseFolderDialogConstant := BrowseForFolder.ShowBrowseFolderDialog;
              if not (BrowseFolderDialogConstant = bffdcCancel) then
              begin
                dir := BrowseForFolder.OutPutDir;

Der Dialog beendet sich dann selbst nach einem Click als Beispiel auf "Cancel"
Delphi-Quellcode:
          ID_BTN_CANCEL:
            begin
              SkinEngine.SetCTLText(edInput.Handle, '');
              BrowseForFolder.DlgConstant := bffdcCancel;
              SendMessage(WinHandle, WM_DESTROY, 0, 0);
              DriveList.DestroyWindow;
              DriveList := nil;
              BroForFolderHandle := 0;
            end;
Ok hat jetzt weniger mit seinem Problem zu tun..
Daher bin ich raus ;)

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 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