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/)
-   -   Delphi CanFocus and Active: Probleme (https://www.delphipraxis.net/126060-canfocus-active-probleme.html)

blackdrake 17. Dez 2008 08:58


CanFocus and Active: Probleme
 
Hallo.

Ich habe Probleme mit dem .SetFocus .

Zuerst hatte ich überall ".SetFocus" stehen, bis ich die Exception mit dem deaktivierten Control oder unsichtbares Fenster erhielt.

Deswegen wechselte ich später zu

Delphi-Quellcode:
if x.CanFocus and Active then x.SetFocus;
Nun habe ich herausgefunden, dass in meinem Programm im OnShow-Ereigniss "Active" unwahr ist, weswegen .SetFocus nicht ausgeführt wird.

Also habe ich "and Active" einfach auskommentiert.

Delphi-Quellcode:
if x.CanFocus {and Active} then x.SetFocus;
Jetzt wird auch im OnShow-Ereignis der Focus korrekt gesetzt.

Aber: Benutzer meldeten mir, dass genau in dieser Version, bei der ich die Änderungen durchgeführt habe, wieder die Exception kommt "Unsichtbares Fenster oder deaktivertes Control kann nicht den Focus erhalten". (Seltsam: Ich erhalte den Fehler (im Moment) nicht)

Was mache ich nun? Ich verstehe die Funktion von "Active" nicht genau und vor allem, wieso "CanFocus" nicht ordentlich kontrolliert, ob "SetFocus" erfolg haben wird oder nicht. Im QualityCenter bei Borland wurden aber auch ähnliche Dinge gemeldet, dass mit "CanFocus" irgendwas nicht ganz in Ordnung sein sollte/könnte/ist.

Hier ein reproduzierbarer Code:

Delphi-Quellcode:

Application.ShowMainForm := False;

// Form 1

procedure TForm1.FormShow(Sender: TObject);
begin
  // Unter gewissen Bedingungen wird entweder das eine Control, oder das andere Control focus'ed,
  // deswegen ein SetFocus im OnShow();

  if edit2.CanFocus and Active then edit2.SetFocus; // erhält nicht den Focus
  if edit2.CanFocus {and Active} then edit2.SetFocus; // jetzt erhält es den Focus, aber manchmal Exception
end;

// Da das ShowMainForm = False ist, führe ich den Initialisierung mit einem Timer anstelle des OnShow-Ereignisses aus
// Außerdem: Nur unter _gewissen_ Bedingungen soll das Form auch angezeigt werden. Deswegen schreibe ich den Code im Timer und nicht im OnShow / OnCreate (OnCreate: Andere Forms noch nicht initialisiert).

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := false;

  // Hier ist eigentlich zeitaufwändiger Code, weswegen ich es als einmaligen Timer mache...

  // Unter gewissen Voraussetzungen wird das Form dann gezeigt:
  Show;
end;
Getestet mit D6 / D2006.

Hat jemand eine Idee, was da falsch ist und wieso diese Exceptions nur bei gewissen Benutzern kommen?

Gruß
blackdrake

Hawkeye219 17. Dez 2008 09:34

Re: CanFocus and Active: Probleme
 
Hallo Daniel,

vielleicht kannst du die Formular-Eigenschaft Delphi-Referenz durchsuchenActiveControl statt des Aufrufs von SetFocus nutzen. Damit sollte das angegebene Control ebenfalls beim Anzeigen des Formulars den Eingabefokus erhalten.

Eine andere Möglichkeit wäre es, im Timer-Code per PostMessage eine benutzerdefinierte Nachricht in die Warteschlange des Formulars zu stecken. Beim Empfang dieser Nachricht kannst du dann den Eingabefokus setzen.

Es sind nur Ideen, ich habe es selbst nicht getestet. Wie du ja selbst schreibst, ist der Fehler nicht auf allen Rechnern zuverlässig reproduzierbar.

Gruß Hawkeye

blackdrake 20. Dez 2008 22:06

Re: CanFocus and Active: Probleme
 
Hallo.

Vielen Dank für deine Antwort.

Mit ActiveControl erscheint der Bug bei den betroffenen Benutzern nicht mehr. (Die Anzahl der aktiven Bugreports und deren Resonanz auf mein Debug-Build ist jedoch so gering, dass ich jetzt nicht von einem bewiesenen "SOLVED" Status reden kann)

Ich möchte aber gerne nachvollziehen, wieso es nicht bei manchen Benutzern funktioniert hat und ob es nicht vielleicht doch Stellen geben kann, bei denen ActiveControl unter den Bedingungen des Programmes abstürzt.

Meine weiteren Fragen sind deshalb:

1. Wieso verwendet man CanFocus AND Active?
2. Wieso wird CanFocus nicht false, wenn Active nicht gegeben ist?
3. Wieso funktioniert SetFocus() manchmal, auch wenn Active false ist? Wieso schlägt es manchmal fehl?
4. Was bewirkt Active?
5. Ist ActiveControl besser als SetFocus oder gibt es irgendwelche Unterschiede?

Ich habe außerdem festgestellt, dass ActiveControl ebenfalls einen Fehler verursacht, wenn ich z.B. ein deaktiviertes Element auswählen möchte (was natürlich logisch ist). Ich könnte aber anhand dieser Erkenntnis schließen: Wenn If-CanFocus-Then-SetFocus manchmal fehlschlägt, dann wird ActiveControl wohl auch vielleicht fehlschlagen.

Deswegen noch eine Frage:
6. Sollte man ActiveControl vorher mit CanFocus abprüfen? Wird es dann auch noch Probleme geben, wenn Active false wird?

Gruß
blackdrake

Hawkeye219 20. Dez 2008 23:57

Re: CanFocus and Active: Probleme
 
Hallo Daniel,

zur Beantwortung deiner Fragen ist sicher eine genaue Kenntnis der VCL-Interna notwendig, die ich leider nicht besitze. Natürlich kann ich mir die Quelltexte ansehen, aber wie soll man in kürzester Zeit eine komplexe Bibliothek verstehen, die zahlreiche Entwickler in den letzten 14 Jahren erstellt haben? Vielleicht ist das Embarcadero Diskussionsforum eine bessere Anlaufstelle für solche speziellen Fragen. Dort lesen (und schreiben) neben einigen TeamB-Mitgliedern auch Entwickler von CodeGear mit. Sie sollten eigentlich kein Problem haben, dir die notwendigen Informationen zu liefern.

Eine Vermutung dennoch: bei der Abarbeitung des OnShow-Handlers ist das Formular noch nicht sichtbar, du kannst das mit einem ShowMessage-Aufruf zu Beginn des Handlers prüfen. Ein sicheres Setzen des Fokus ist zu diesem Zeitpunkt offenbar nicht möglich. Der im vorigen Beitrag genannte Ansatz über PostMessage müsste funktionieren, da diese Nachricht erst bei einem sichtbaren Formular verarbeitet werden sollte.

Gruß Hawkeye


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