SetFocus löst kein Invalidate aus

Rund um die LCL und andere Komponenten
Antworten
siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

SetFocus löst kein Invalidate aus

Beitrag von siro »

Hallo zusammen,

beim Experimentieren mit meinen Komponenten viel mir grade folgendes auf:

SetFocus löst kein Invalidate aus

Alle Kontrollelemente, zumindest TCustomControl, haben die Procedure SetFocus.
Oft wird ein focussiertes Element jedoch anders gezeichnet als wenn es nicht den Focus hat.

Mein Problem war:
Ich wollte, dass meine Komponente sofort den Focus erhält wenn ich mit der Maus drüber fahre.
So habe ich bei OnMouseMove SetFocus aufgerufen.
Aber ich habe das Ergebnis nicht gesehen, da offenbar kein Invalidate meiner Komponente ausgeführt wurde,
meine Komponente jedoch anders aussieht wenn sie den Focus hat, das steht zumindest so in der Procedure paint.

Um meine Funktionalität nun zu erreichen, habe ich selbst Hand anlegen müssen
und die Procedure OnEnter und OnExit überschrieben, die lediglich
zusätzlich ein Invalidate ausführt.

Die Frage stellt sich jetzt: Ob das so gewollt ist ?

Dazu habe ich ein kleines Beispiel angefügt.
Damit man nix installieren muss, habe ich ein Miniprogramm mit einer Testkomponente erstellt und angehangen zum Testen der Funktionalität.

Wenn ich mit der Maus in das weisse Rechteck oben links fahre, erhält die Komponente den Focus
Das ist aber nicht zu sehen.
Durch Click mit der Maus auf das Feld wird nun lediglich ein Invalidate ausgeführt
und dann sieht man, dass dieses Feld grün wird.

Drücke ich auf den unteren Button, verliert meine Komponente automatisch den Focus und der wird an die Taste übergeben,
aber auch hier gibt es kein Invalidate für meine Komponte, das Feld bleibt grün, obwohl es jetzt wieder auf weiss umspringen sollte.

Abhilfe schafft nur das überschreiben der Procedure OnEnter und OnExit.
Dazu einfach die beiden Invalidate in den Proceduren DoEnter und DoExit wieder aktivieren.

Es scheint also zwingend erfordlich, diese beiden Proceduren "immer" ??? zu überschreiben ??

Für Informationen bedanke ich mich schonmal im voraus bei euch.

Siro
project1.zip
(127.39 KiB) 42-mal heruntergeladen
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: SetFocus löst kein Invalidate aus

Beitrag von wennerer »

Hallo Siro,
ich habe es eben unter Linux Mint getestet. Bei mir wird offensichtlich ein Invalidate ausgelöst und das Rechteck wird gleich grün. Eventuell verhält es sich unter Windows anders?
Aber was spricht denn dagegen in der MouseMove nach SetFocus einfach ein Invalidate einzufügen?

Viele Grüße
Bernd

Nachtrag: Habe es eben in Win10 getestet, da wird kein Invalidate ausgelöst!

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SetFocus löst kein Invalidate aus

Beitrag von siro »

Hallo Bernd,
danke, dass Du es mal getestet hast.

Dann scheint es einen Unterschied beim Verhalten zwischen Windows und Linux zu geben.
Ich benutze Windows, vergass ich zu erwähnen.

Windows 10 64 Bit

Lazarus #:2.0.8
Datum: 2021-11-04
FPC-Version: 3.04
SVN-Revision:62944
x86_64-win64-win32/win64

Im Prinzip hast Du recht, ich kann natürlich nach SetFocus auch gleich Invalidate aufrufen,
aber meine Komponente bekommt es dann immernoch nicht mit wenn eine andere Komponente den Focus erhält.
Ich hätte also nur eine Teillösung des Problems. Daher habe ich die zweite Procedure OnExit
auch mit invalidate versehen, damit meine Komponente wieder den nicht fokussierten Zustand anzeigt.

Vielleicht ist das ja auch ein Bug (ich trau mich sowas eigentlich nicht zu spekulieren)
Mal gucken was die Anderen dazu sagen...

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SetFocus löst kein Invalidate aus

Beitrag von siro »

Gleiches Verhalten auf anderem Rechner:

Lazarus #:2.0.12
Datum: 2021-02-21
FPC-Version: 3.2.0
SVN-Revision:64642
x86_64-win64-win32/win64
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: SetFocus löst kein Invalidate aus

Beitrag von six1 »

Vielleicht ist das ja auch ein Bug (ich trau mich sowas eigentlich nicht zu spekulieren)
Mal gucken was die Anderen dazu sagen...
Du glaubst nicht, was es da alles gibt :-)
Ich setze von Devart die SecureBridge Komponenten ein, um einen SSH Tunnel aufzubauen und eine Port darüber zu tunneln.
Bis Version 8.x der Komponente lief unter WIN und Linux (gleiche Sourcen!) alles 1a.
Ab Version 9.x läuft unter WIN immer noch alles.
Unter linux, wenn ich die Porttunnelung disable, bleibt die Software in einem ewig langen Timeout.
Klicke ich während des Timeout in die IDE an beliebige Stelle in den Quellcode, läuft das Programm weiter.
Devart hat schon Probleme das PROBLEM zu erfassen :lol: :lol: :lol:
Gruß, Michael

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetFocus löst kein Invalidate aus

Beitrag von fliegermichl »

Das muss irgendeine andere Ursache haben.
Ich habe im FormCreate tc.TabStop := True gesetzt und einfach einen weiteren Button ins Formular geklickt.
Wenn ich jetzt mit der Tab Taste durch die fokussierten Controls springe,
kann ich das bei den Buttons sehen, bei TestControl jedoch nicht.

irgendeine ComponentStyle / ControlStyle o.ä. muss da noch gesetzt werden.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SetFocus löst kein Invalidate aus

Beitrag von siro »

Guten Morgen,

Auch Danke an Fliegermichi, ich hab das auch grad nochmal probiert mit TabStop und das ändert nichts am Verhalten,
Jetzt habe ich grade mal in meinen alten Delphi3 Komponenten geschaut und siehe da, dieses Problem gab es damals 2007 schon in Delphi 3....

Hier ein Kommentar den ich 2007 schon in die Komponente schrieb.:

Code: Alles auswählen

{ Siro 03.03.2007 } 
{ WMKillFocus ruft bei den Standardkomponenten kein Invalidate auf.
{ Ebensowenig wie CMFocusChanged. Meiner Meinung nach hat Borland dies vergessen. }
{ Bei TSpinButton z.B. wurde es richtig implementiert, ebenso bei den DataBase dbControls }

procedure TUniTaste.WMKillFocus(var Message: TWMSetFocus);
begin
  Repaint;         { sofort neuzeichnen }                                
  ........
  
procedure TUniTaste.WMSetFocus(var Message: TWMSetFocus);
begin
  Repaint;    { sofort neuzeichnen }
  .....
Ich hab da also schon damals gegengesteuert, konnte mich garnicht mehr erinnern, ist doch erst 14 Jahre her :lol:

Dann ist dieses Problem evtl. wieder der Kompatibilität geschuldet ?
Wobei ich heute eher davon ausgehe, dass es ein Problem in der Windows API ist, daher scheint es in Linux auch nicht aufzutreten wie Bernd feststellen konnte.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetFocus löst kein Invalidate aus

Beitrag von fliegermichl »

Ich habe jetzt mal in die Quellcodes des Package CustomDrawn geschaut.
Da wird auch DoEnter und DoExit überschrieben und vor dem Aufruf von inherited invalidate aufgerufen.

Auch TCheckBoxThemed aus der Palette LazControls macht es so.

Meiner Meinung nach gehört das schon in TWinControl.DoEnter|Exit rein. Da Delphi es aber genauso macht, ist es wohl der Kompatibilität geschuldet.

EDIT: Hab es eben in Delphi nachgespielt, exakt gleiches Verhalten.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: SetFocus löst kein Invalidate aus

Beitrag von siro »

Okay, danke fliegermichi, dass Du auch mal in den Quellcode reingeschaut hast.
Dann hat es sich also bestätigt und ich würde sagen, das Thema kann geschlossen werden.
Ich stimme zu, das gehört "eigentlich" in TWinControl rein...aber dann ist es ja nicht mehr kompatibel... :roll:
Dann geniesst das Wochenende.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten