AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Diverse Fokusprobleme

Ein Thema von himitsu · begonnen am 22. Apr 2014 · letzter Beitrag vom 16. Sep 2014
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

AW: Fokusproblem (MDI)

  Alt 23. Apr 2014, 10:14
Einen bekannten Fehler bin ich grade noch am Suchen, der sich bei den Kunden auch nett auswirkt ... danach würde ich die Fehler dann nochmal zusammengefassen.

Das mit dem Suchen-dialog fällt uns seit knapp einem halben jahr auf die Füsse, wobei wir nie rausfanden, warum es in manchen Fenstern ging und in Anderen nicht.
Es war auch bisher nie Zeit da jetzt tagelang zu suchen, bis ich am Donnerstag mal wieder Zeit hatte und dann zufällg drüber gestolpert bin.

Seit der Umstellung von D7 auf XE suche ich jetzt derartige Fehler und das ist auch einer der Hauptgründe, warum wir da immernoch auf XE festhängen, weil wir uns nicht trauten das komplette und jahrzehnte alte Projekt weiter hochzuportieren (wer weiß was dann zusätzlich auch nicht läuft).
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (23. Apr 2014 um 10:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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)
Ein Therapeut entspricht 1024 Gigapeut.

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

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Fokusproblem (MDI)

  Alt 23. Apr 2014, 12:48
Statt dem Timer wäre auch TApplicationEvents.OnIdle möglich (find ich in dem Zusammenhang sogar besser)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Diverse Fokusprobleme

  Alt 23. Apr 2014, 13:11
OK, OnIdle wäre vielleicht auch gegangen.

Es wurde aber absichtlich ein Timer, damit ich ein zeitlich einheitliches und nachvollziehbares Verhalten hinbekomm.
Welcher aktuell mit einem 100ms-Intervall nach je 10 Durchläufen den Status prüft, also alle 1 Sekunde.

Wenn das Programm hängt (z.B. irgendwas Laden oder eine SQL-Abfrage), dann verlängert sich das Intervall entsprechend und löst nicht sofort nach dem Hängen aus.
Das verhinderte recht zuverlässig, daß der Code auch auslöst, wenn dieses wirklich mal kurzzeitig nil ist (z.B. beim Wechsel von Fenstern), aber kurz danach von "alleine" wieder in einen korrekten Zustand gerät, womit mein Reparaturcode sonst den "korrekten" Fokus überschreiben würde.

Und im Grunde war es nur ein "kurzfristiger" Bugfix (seit vielleicht 2 Jahren), bis die Fehler behoben sind.
Ein Therapeut entspricht 1024 Gigapeut.

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

Registriert seit: 18. Mär 2005
Ort: NRW
117 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Diverse Fokusprobleme

  Alt 30. Apr 2014, 10:58
Ich kenne das Problem auch schon lange bei TFindDialog. Zum Beispiel in anderen Forms als in der Mainform. Ich habe dafür folgenden Workaround in Application on Message:

Code:
procedure TfmGeMail.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
  Shift: TShiftState;
  Key: Word;

  procedure GetShiftState(var Shift: TShiftState);
  var
    KeyboardState: TKeyboardState;
  begin
    Shift := [];
    GetKeyboardState(KeyboardState);
    if (KeyboardState[vk_Shift] and 128 = 128) then
      Shift := Shift + [ssShift];
    if (KeyboardState[VK_CONTROL] and 128 = 128) then
      Shift := Shift + [ssCtrl];
    if (KeyboardState[vk_Menu] and 128 = 128) then
      Shift := Shift + [ssAlt];
  end;


begin
  GetShiftState(Shift);
  Key := Msg.WParam;
  case Msg.Message of
    WM_KEYDOWN:
      case Key of
        Ord('F'): if (Shift=[ssCtrl]) then
                  begin
                    SetWindowPos (Application.handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE+SWP_NOSIZE or SWP_NOREDRAW);
                    SetWindowPos(Application.Handle, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOREDRAW );
                  end;


...
Dann werden die Fenster wieder in der richtigen Reihenfolge und der FindDialog verschwindet nicht und ist focussiert
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Diverse Fokusprobleme

  Alt 30. Apr 2014, 15:42
Den TopMost-Schrott haben wir das letzte halbe/ganze Jahr über wieder komplett ausgebaut, da es mehr Probleme machte, als es löste.
Vorallem da dann ständig immer wieder mit Application.NormalizeTopMosts und Co. rumgepfuscht werden muß, wenn man einen Dialog/Fehlermeldung anzeigen will, damit die nicht hinter TopMost-Fenstern verschwinden.

Eigentlich lässt sich das inzwischen besser über den PopupMode regeln (wenn es denn auch überall korrekt verwendet würde).


Und bei Application.Handle musst du auch aufpassen, denn das "versteckte" Application-Message-Window wird von Delphis nicht mehr für die Anzeige verwendet, seitdem Delphi sich kompatibler zu Vista+ verhällt.
Den in alten Delphis funktioniert z.B. das Aero-Preview nicht, da man in der Taskleiste nur das "leere" Application-Fenster sieht und nicht die MainForm.
siehe Application.MainFormOnTaskBar
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (30. Apr 2014 um 15:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Diverse Fokusprobleme

  Alt 3. Mai 2014, 11:35
Gerade bei SO gefunden

Hast du schon einen QC Eintrag verfasst?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:15 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 by Thomas Breitkreuz