Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Aktuellen Focus verlieren oder löschen (https://www.delphipraxis.net/197935-aktuellen-focus-verlieren-oder-loeschen.html)

knaeuel 19. Sep 2018 13:56

Aktuellen Focus verlieren oder löschen
 
Folgendes Problem:

Ich hab eine App-Bildschirmmaske mit einem TabControl mit 3 Seiten.
Das Blättern funktioniert unter anderem durch Wischen.

Auf jeder Seite gibt es Steuerelemente, die durch Schieben eingestellt werden können (Switches und Trackbars). Wenn nun ein Trackbar ein Stückchen verschoben wird, will die App neben dem gewünschten Verstellen der Komponente auch umblättern, weil es das Schieben für ein Wischen hält.

Also fange ich das ab. Wenn der Focus beim Auslösen einer Geste auf einem der Switch/Trackbar-Steuerelemente liegt, dann setze ich "Handled" auf "true" und schon blättert es nicht mehr um. Jetzt ruht der Focus allerdings auf einem Switch/Trackbar, was zur Folge hat, dass das Blättern nicht mehr funktioniert, weil es IMMER abgefangen wird.

Also will ich den Focus EINFACH NUR LÖSCHEN oder ersatzweise auf ein anderes Element legen.
Und genau das ist das Problem. Ich habe kein anderes Steuerelement auf dem Bildschirm, dass den Focus erhalten kann.

Vorraussetzungen dafür sind nämlich:
- Steuerelement hat die Eigenschaft "CanFocus"
- Steuerelement ist auf der aktuell sichtbaren Maske
- Steuerelement ist sichtbar

Ich kann also keinen unsichtbaren Dummy-Button oder ein Element von einem anderen Formular oder einer anderen Tab-Seite benutzen. :S

Delphi-Quellcode:
procedure TFormOptions.TabControl1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
  //wir wollen die "blättern"-geste vermeiden, wenn der Focus auf dem Trackbar/TSwitch liegt,
  //damit beim Einstellen des Trackbars/TSwitchs nicht immer der Bildschirm gewechselt wird
  if Assigned(Focused) then
  begin
    //bei Trackbar-Verschiebung nicht durch die Tabs blättern
    if Focused.GetObject is TTrackbar then
      Handled:=true;

    //bei Switch-Bewegung nicht durch die Tabs blättern
    if Focused.GetObject is TSwitch then
      Handled:=true;

    if Handled then
    begin
      //zum Schluss Focus wegschicken, damit die Gesten nun wieder funktionieren

      //ClearFocus oder ReleaseFocus oder ForgetFocus wäre schön, gibts aber nicht

      //nur-lesen-eigenschaft: TTrackbar(Focused.GetObject).IsFocused:=false;

//funzt nicht, weil visible=false
//      if TabControl1.ActiveTab=TabItem1 then
//        SetFocused(ButtonFocusDummyPage1);
//      if TabControl1.ActiveTab=TabItem2 then
//        SetFocused(ButtonFocusDummyPage2);
//      if TabControl1.ActiveTab=TabItem3 then
//        SetFocused(ButtonFocusDummyPage3);
    end;
  end;
  if not Handled then
  begin
    case EventInfo.GestureID of
    sgiLeft: ExecuteAction(NextTabActionPGOptions);
    sgiRight: ExecuteAction(PreviousTabActionPGOptions);
    end;
  end;
end;
Gibt es einen Trick, den Focus, der auf TSwitch oder TTrackbar liegt, loszuwerden?

Danke!

EWeiss 19. Sep 2018 14:01

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

//ClearFocus oder ReleaseFocus oder ForgetFocus wäre schön, gibts aber nicht
Nö aber SetFocus(0)

gruss

DeddyH 19. Sep 2018 14:05

AW: Aktuellen Focus verlieren oder löschen
 
Ja, unter Windows.

EWeiss 19. Sep 2018 14:08

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von DeddyH (Beitrag 1413635)
Ja, unter Windows.

Ach so wusste nicht das es nicht um Windows geht.

sorry dann weis ich auch nicht.

PS:
Und SetFocused(0); ?

gruss

knaeuel 19. Sep 2018 14:29

AW: Aktuellen Focus verlieren oder löschen
 
cool, danke für die schnellen Antworten!

so wie es aussieht, ist

Delphi-Quellcode:
SetFocused(nil);
die Lösung!

Herzlichen Dank für die Tipps!

in Gänze sieht das also so aus:

Delphi-Quellcode:
procedure TFormOptions.TabControl1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
  //wir wollen die "blättern"-geste vermeiden, wenn der Focus auf dem Trackbar/TSwitch liegt,
  //damit beim Einstellen des Trackbars/TSwitchs nicht immer der Bildschirm gewechselt wird
  if Assigned(Focused) then
  begin
    //bei Trackbar-Verschiebung nicht durch die Tabs blättern
    if Focused.GetObject is TTrackbar then
      Handled:=true;

    //bei Switch-Bewegung nicht durch die Tabs blättern
    if Focused.GetObject is TSwitch then
      Handled:=true;

    if Handled then
    begin
      //zum Schluss Focus wegschicken, damit die Gesten nun wieder funktionieren
      SetFocused(nil);
    end;
  end;
  if not Handled then
  begin
    case EventInfo.GestureID of
    sgiLeft: ExecuteAction(NextTabActionPGOptions);
    sgiRight: ExecuteAction(PreviousTabActionPGOptions);
    end;
  end;
end;

EWeiss 19. Sep 2018 14:34

AW: Aktuellen Focus verlieren oder löschen
 
Ich habe mir schon gedacht das es auch so etwas in was auch immer du programmierst Windows, Android.. bla bla geben muss.
War mir nur nicht sicher was bei SetFocused verwendet wird.
Aber gut wenn es geht ;)

Lag ich doch nicht SOooo falsch.

gruss

Redeemer 19. Sep 2018 16:33

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von DeddyH (Beitrag 1413635)
Ja, unter Windows.

Das bezweifle ich. Bei VCL habe ich in einer TControl-Unterstützerklasse das hier:
Delphi-Quellcode:
procedure Blur();
begin
  if Enabled then
  begin
    Self.Enabled := False;
    Self.Enabled := True;
  end;
end;
Geht das besser (in VLC)?

EWeiss 19. Sep 2018 16:38

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von Redeemer (Beitrag 1413672)
Zitat:

Zitat von DeddyH (Beitrag 1413635)
Ja, unter Windows.

Das bezweifle ich. Bei VCL habe ich in einer TControl-Unterstützerklasse das hier:
Delphi-Quellcode:
procedure Blur();
begin
  if Enabled then
  begin
    Self.Enabled := False;
    Self.Enabled := True;
  end;
end;
Geht das besser (in VLC)?

Um was geht es dir hier?

Er wollte mir sagen das es SetFocus unter Windows gibt aber nicht unter Android.
Wo gibt es nun mit deiner Antwort einen Bezug zu Android? Und der Frage vom TE
Man muss verstehen was man liest.. aber keine bange mir geht es mitunter auch nicht anders.

Ich habe vorher auch nicht gewusst das es NICHT um Windows geht.

gruss

TurboMagic 28. Sep 2018 19:05

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von EWeiss (Beitrag 1413633)
Zitat:

//ClearFocus oder ReleaseFocus oder ForgetFocus wäre schön, gibts aber nicht
Nö aber SetFocus(0)

gruss

Ich hab' heute auch so etwas gebraucht und das hier gefunden:

FMX.Controls.TControl.ResetFocus

EWeiss 28. Sep 2018 19:40

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von TurboMagic (Beitrag 1414473)
Zitat:

Zitat von EWeiss (Beitrag 1413633)
Zitat:

//ClearFocus oder ReleaseFocus oder ForgetFocus wäre schön, gibts aber nicht
Nö aber SetFocus(0)

gruss

Ich hab' heute auch so etwas gebraucht und das hier gefunden:

FMX.Controls.TControl.ResetFocus

Dir ist aber klar das dieses Thema erledigt war oder?
Delphi-Quellcode:
SetFocused(nil);


gruss

TurboMagic 29. Sep 2018 07:46

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von EWeiss (Beitrag 1414476)
Zitat:

Zitat von TurboMagic (Beitrag 1414473)
Zitat:

Zitat von EWeiss (Beitrag 1413633)
Zitat:

//ClearFocus oder ReleaseFocus oder ForgetFocus wäre schön, gibts aber nicht
Nö aber SetFocus(0)

gruss

Ich hab' heute auch so etwas gebraucht und das hier gefunden:

FMX.Controls.TControl.ResetFocus

Dir ist aber klar das dieses Thema erledigt war oder?
Delphi-Quellcode:
SetFocused(nil);


gruss

Ja, die Lösung sah' ich im Thread, aber warum nicht aufzeigen, dass es auch andere Lösungsansätze gibt?
SetFocus(nil) klingt etwas weniger übersichtlich als ResetFocus.

EWeiss 29. Sep 2018 08:51

AW: Aktuellen Focus verlieren oder löschen
 
SetFocused(nil); <> SetFocus(nil)

SetFocused ist global. Es spielt keine rolle welches Control den Focus hat!
während FMX.Controls.TControl.ResetFocus nur für ein spezifisches Control gilt. (Reine Vermutung bin kein FMX'ler)

gruss

himitsu 29. Sep 2018 08:58

AW: Aktuellen Focus verlieren oder löschen
 
Den Fokus komplett abzugeben ist keine gute Idee, denn wenn die Anwendung ihn nicht mehr hat, dann bekommt ihn ein anderes Fenster (falls es andere Fenster gibt) und dein Programm verschwindet im Hintergrund.

Du kannst aber den Fokus dem Fenster geben, oder dem ersten Control auf Diesem. (entsprechend der TabStops)
Liegt der Fokus beim Umblättern im PageControl, dann wird beim Umblättern das erste Control auf dem neuen Tab fokusiert.
Lag der Fokus außerhalb, dann bleibt er dort, also einfach vor dem umblättern den Fokus raussetzen, wenn er im Tab liegt. (Parent/Parent/Parent/... des aktiven Controls ist ein TabSheet des PageControls)

TWinControl.Delphi-Referenz durchsuchenSelectFirst/Delphi-Referenz durchsuchenSelectNext/Delphi-Referenz durchsuchenCanFocus

EWeiss 29. Sep 2018 09:02

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Den Fokus komplett abzugeben ist keine gute Idee, denn wenn die Anwendung ihn nicht mehr hat, dann bekommt ihn ein anderes Fenster (falls es andere Fenster gibt) und dein Programm verschwindet im Hintergrund.
Schau doch einfach mal um was es hier geht.. NICHT um Windows!
Welches Fenster bekommt dann den Focus unter Android\FMX ?

gruss

himitsu 29. Sep 2018 19:56

AW: Aktuellen Focus verlieren oder löschen
 
Selbst Android kennt einen Desktop-Modus, wo mehrere Fenster/Programme gleichzeitig nicht im Vollbild aktiv sein können.

Aber OK ... gute Frage war im normalen Vollbild-OneApp-Modus dann passiert.

knaeuel 1. Okt 2018 08:45

AW: Aktuellen Focus verlieren oder löschen
 
@himitsu: interessanter gedanke auf jeden fall. bisher bleibt die app beim löschen des focus auf andoird und ios im vordergrund. sollte sich das aber mal ändern, habe ich das hier jetzt im hinterkopf. danke!

EWeiss 1. Okt 2018 09:15

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von knaeuel (Beitrag 1414580)
@himitsu: interessanter gedanke auf jeden fall!

Mehr aber auch nicht ein Gedanke.
Zitat:

bisher bleibt die app beim löschen des focus auf andoird und ios im Vordergrund
Wird sich auch nie ändern.
Zitat:

sollte sich das aber mal ändern
Wird es nicht!

Zitat:

Den Fokus komplett abzugeben ist keine gute Idee, denn wenn die Anwendung ihn nicht mehr hat, dann bekommt ihn ein anderes Fenster (falls es andere Fenster gibt) und dein Programm verschwindet im Hintergrund.
Quatsch..

Mit Verlaub.. Die Annahme von @himitsu ist schlichtweg falsch.

Denn das setzen des Focus ist nur gültig für den eigenen Prozess und kann nicht an übergeordnete Fenster die mit dem eigenen Prozess nichts zu tu haben übergeben werden.

Teste es ganz einfach.
Schicke eine Message an ein fremdes Fenster mit SetFocus(AnderesFensterHandleControl) und du wirst sehen es tut sich NICHTS.
Zudem hat es keinerlei Einfluss auf irgendeine ZOrder in welcher form auch immer.

Um den Focus auf einen anderen Prozess (Fenster (Zorder)) zu setzen gibt es als Beispiel diese Funktion
SetForegroundWindow.. dann benötigst du kein SetFocus mehr da in diesem Fall deine Anwendung keinen Focus mehr hat.

Und nochmal das setzen des SetFocus(0) oder wie unter Android SetFocused(nil) hat keinen Einfluss auf irgendeinen Parent. Weder in der ZOrder noch aktiviert es ein anderes Fenster außerhalb der eigenen Anwendung und setzt ihn dort.
Nicht alles was @himitsu schreibt ist zwangsläufig auch richtig!

gruss

KodeZwerg 1. Okt 2018 09:58

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von EWeiss (Beitrag 1414588)
Um den Focus auf einen anderen Prozess (Fenster (Zorder)) zu setzen gibt es als Beispiel diese Funktion
SetForegroundWindow.. in dem Fall benötigst du kein SetFocus mehr da in diesem Fall deine Anwendung keinen Focus mehr hat.

Und nochmal das setzen des SetFocus(0) hat keinen Einfluss auf irgendeinen Parent. Weder in der ZOrder noch aktiviert es ein anderes Fenster und setzt ihn dort.

Wenn man im Vorfeld mit AttachThreadInput ne Verbindung aufbaut kann man auch mit SetFocus(fremdThread) hin und her hopsen. (als weiteres Beispiel)
So sind jedenfalls meine Erfahrungen damit, ansonsten gebe auch ich dem letzten part von EWeiss Recht.

EWeiss 1. Okt 2018 10:02

AW: Aktuellen Focus verlieren oder löschen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1414590)
Zitat:

Zitat von EWeiss (Beitrag 1414588)
Um den Focus auf einen anderen Prozess (Fenster (Zorder)) zu setzen gibt es als Beispiel diese Funktion
SetForegroundWindow.. in dem Fall benötigst du kein SetFocus mehr da in diesem Fall deine Anwendung keinen Focus mehr hat.

Und nochmal das setzen des SetFocus(0) hat keinen Einfluss auf irgendeinen Parent. Weder in der ZOrder noch aktiviert es ein anderes Fenster und setzt ihn dort.

Wenn man im Vorfeld mit AttachThreadInput ne Verbindung aufbaut kann man auch mit SetFocus(fremdThread) hin und her hopsen. (als weiteres Beispiel)
So sind jedenfalls meine Erfahrungen damit, ansonsten gebe auch ich dem letzten part von EWeiss Recht.

Es geht hier um SetFocus der eigenen Anwendung.
Nicht um Input.. Set Keyboard Focus als Beispiel. Das ist ebenfalls mit Verlaub etwas ganz anderes.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz