Thema: Delphi Diverse Fokusprobleme

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#5

AW: Diverse Fokusprobleme

  Alt 23. Apr 2014, 12:37
falscher Fokus von Delphi gemerkt und gesetzt, bei neuen Common-Dialogen
  • Fokus in einem MDI-Fenster (z.B. auf Edit oder Button)
  • neuen Common-Dialog anzeigen (z.B. MessageDlg)
  • nach dem Schließen sagt Screen.ActiveForm und Screen.ActiveControl der Fokus sei richtig
  • aber in Wirklichkeit ist der Fokus direkt bei beim MDI-Parent (die HauptForm in der Demo)
Grund: TCustomTaskDialog.DoExecute wird am ende der Fokus auf die Top-Level-Form gesetzt und nicht auf die eingebettete MDI-Form, bzw. nicht auf das aktive Control.

Demo: Fokus ins Memo -> SpeedButton: New CommonDialog -> OK -> Fokus landet beim MDI-Parent (egal ob mit externem Fenster "New Form" oder nicht)


Fokus falsch von Delphi gesetzt, bei Dialogen
  • externe Form erstellen (New Form)
  • Fokus in Hauptform, älterer Form oder MDI
  • FindDialog anzeigen und wieder schließen
  • Fokus landet bei zuletzt erstellter Form (egal ob die Sichtbar ist oder nicht)
  • Wenn Ziel-Form nicht sichtbar, dann verliert das ganze Programm den Fokus und verschwindet im Hintergrund
Grund: Der gewünschte Ziel-Fenster wird ignoriert. (per ParentWnd-Parameter übergeben, oder richtig über TCommonDialog.Execute bestimmt)
Stattdessen wird in TFindDialog.Execute(ParentWnd) über EnumThreadWindows "irgendein" zuletzt erstelltes Fenster genommen, welches auch unsichtbar oder deaktivert sein kann. (wird garnicht geprüft)

Demo 1: New Form -> FindText -> Abbrechen -> Fokus bei falscher Form
Demo 2: New Form -> pmAuto1 schließen -> FindText -> Abbrechen -> Fokus ist komplett weg


Zerstörung der PopupParent-Beziehung beim Schließen einer eingebetteten Form
  • nicht-modale Form hängt via PopupMode=pmExplicit und PopupParent=MainForm immer über der Hauptform
  • weitere nichtmodale Form wird erstellt
  • PopupParent-Verbindung wird manchmal getrennt und die erste Form kann hinter der Hauptform verschwinden
Grund: noch unbekannt


Fokus-Setzten beim Schließen von Fenstern -> Fokus darf nicht umgesetzt werden, wenn er manuell wo anders hingelegt wurde
  • neuer Fokus wird ignoriert -> Delphi setzt den Fokus dennoch auf die Form, wo es denkt da solle er hin. (bei modaler Fenstern ... bei nichtmodal weiß ich es jetzt grade nicht)
    Delphi-Quellcode:
    AndereForm.SetFocus;
    Close;
  • über die WinAPI funktioniert es komischer Weise aber dennoch
    Delphi-Quellcode:
    Windows.SetFocus(AndereForm.Handle);
    Close;
  • Ein SetFocus, egal ob Delphi oder WinAPI, nach dem TForm.Close ausgeführt, wird immer ignoriert, bzw. wieder überschrieben. (nur via WinAPI davor geht es)
Grund: keine Ahnung (hab nicht rausgefunden ob und wo da der Fokus gesetzt wird)

Demo 1: New Form -> New Form -> Fokus auf MainForm/MDIForm -> pmAuto1 oder pmAuto2 schließen -> Fokus bei der anderen pmAuto* und nicht in der MainForm
Demo 2: New Form -> New Form -> New Form -> Fokus auf irgendein pmAuto* -> ein anderes pmAuto* schließen -> Fokus ist beim richtigen Fenster


__________________________________________________ ____________________________________________


Sobald das Zielfenster nicht sichtbar ist, und es wird dennoch versucht den Fokus da hinzusetzen, dann verliert das Programm den Focus.
Das wird halt über Windows.SetFocus gemacht, ohne den Rückgabewert auszuwerten, und nicht über TControl.SetFocus. (TControl.SetFocus wirft ja eine Exception wenn das Fenster/Control nicht fokusierbar ist)


Wenn beim Fokuszurücksetzen seitens Delphi etwas total schief lief und dadurch das Programm im Hintergrund verschwindet, dann ist oftmals Screen.ActiveForm/Screen.ActiveCustomForm = nil.
Selbst wenn das Programm absichtlich im Hintergrund landet, da ein anderes Programm den Fokus bekommt, dann gibt es eigentlich nie ein nil dort.
Derartige Fehler konnten wir "beheben", indem ein Timer regelmäßig auf dieses nil prüft und dann das Programm wieder vor holt.
  • Erst Application.BringToFront; und dann wird in Screen.CustomForms das erste "sichtbare" Fenster gesucht (ja, im gegensatz zu Emba hatte ich das damals schon geprüft), da ebenfalls BringToFront und wenn IsWindowEnabled auch noch SetFocus. (windosseitig sind Forms disabled, wenn z.B. ein modaler Dialog davor liegt)
    Dann ist vielleicht eine "falsche" Form aktiv, aber die Kunden beschwerten sich wenigstens nicht mehr, dass das Programm komplett (im Hintergrund) verschwindet. (die sind es inzwischen eh gewohnt, daß der Fokus nicht immer dahin geht, wo er zuletzt war)
Angehängte Dateien
Dateityp: 7z DemoProjekt+Quellcode.7z (595,4 KB, 32x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (23. Apr 2014 um 13:57 Uhr)
  Mit Zitat antworten Zitat