Autor Beitrag
Sneedlewoods
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Do 11.04.13 02:02 
Hallo,

1. ich habe eine Form1 erstellt
2. ich habe KeyPreview auf true gestellt
3. ich setze einen Button auf die Form

nun ist das Problem:
1. dass der Button immer den Focus hat
2. CanSelect der Form schreibgeschützt ist und auf false steht
3. CanFocus/CanSelect vom Button schreibgeschützt ist und true ist

Ich möchte gerne, dass der Button gar nicht erst den Fokus erhält, oder dass ich in der Lage bin, der Form den Focus zu geben. Denn sonst müsste ich wohl alle Button-aktivierenden Tasten beim Button abfangen? Der Button soll gar nicht erst über die Tastatur aktiviert werden, was ich wohl noch hinkriegen würde. Lieber wäre mir jedoch die Kontrolle über den Focus.

Ich habe nun schon etwas länger gesucht, und wundere mich, dass es dafür nicht eine einfache Lösung gibt.

Grüße Sneedle
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 11.04.13 10:42 
Button ableiten, CanFocus oder CanSelect (je nachdem was du genau vor hast) überschreiben und false zurückgeben lassen.

Für einen sinnvollen Ratschlag sollten wir aber erstmal wissen warum du das willst was du da willst.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 11.04.13 11:03 
Als Quick&Dirty-Lösung würde mir einfallen, den Button durch ein Panel zu ersetzen. Sieht dann zwar evtl. etwas anders aus und entspricht nicht dem normalen Windows-Verhalten, aber ich denke mal, dass du das sowieso umgehen willst.

Ich denk da so an einen Klick-Wettbewerb, den man nicht durch drücken der Enter-Taste umgehen soll. Liege ich da in etwa richtig? ;-)

_________________
We are, we were and will not be.
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Do 11.04.13 13:23 
Danke für die Tips.

@Ralf das mit dem Button ableiten hab ich auch überlegt und versucht. Mein Problem dabei ist, dass er CanFocus nicht erkennt:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class myButton : Button
{
    public override bool CanFocus ...  //CanFocus wird nicht erkannt, falsche Syntax?

    public myButton()
    {
       this.CanFocus = false;  //CanFocus erkannt aber schreibgeschützt
    }
}


Ansonsten muss man eben nicht wissen, warum ich das will. Das Problem ist da und sucht nach Lösungen, egal warum ich das will.

@Gausi
Ein anderes Control zu nehmen habe ich auch schon überlegt. Würde ich im Notfall vielleicht machen, aber schön find ich das nicht. Ich verstehe nicht, wieso es überhaupt so schwierig sein muss -.-
Nein das ist kein Klick-Wettbewerb ;) Aber das Problem ist das Gleiche. Ich fange Tastatureingaben auf Form1-Ebene ab. Wenn jedoch der Button den Focus hat, wird er aktiviert sobald man Leertaste oder Enter oder sowas drückt, was schlicht und einfach nicht immer sinnvoll ist.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 11.04.13 14:39 
CanFocus und CanSelect sind nicht virtual :( Tja da war mein Vorschlag dann nicht wirklich hilfreich.

Vielleicht hilft es wenn du im Constructor des abgeleiteten Buttons den Style passend setzt.

ausblenden C#-Quelltext
1:
this.SetStyle(ControlStyles.Selectable, false);					
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Fr 12.04.13 01:21 
Hallo also beim Button funktioniert das so nicht. Eventuell müsste ich das Panel ableiten und SetStyles ändern, aber dass würde bedeuten dass ich alle Labels, Buttons etc. selber in das Panel setzen muss, oder kann ich den Designer irgendwo dafür einspannen? Theoretisch müsste das ja gehen, ist das gleiche Objekt.

Mir gefällt allerdings gerade die Idee besser, die Tastatureingaben für den Button zu sperren. Dann muss ich die ganzen Elemente nicht erneut auf die Form setzen. Aber wie ich es mir dachte funktioniert leider auch nicht -.-

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Button.KeyPress += new KeyPressEventHandler(this.ButtonNoKey);
Button.KeyUp += new KeyEventHandler(this.ButtonNoKey);

private void ButtonNoKey(object sender, KeyPressEventArgs e)
{
    e.Handled=true;
}
private void ButtonNoKey(object sender, KeyEventArgs e)
{
    e.Handled=true;
}


Das hat leider nicht zum Erfolg geführt. Geht das irgendwie anders?
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Fr 12.04.13 01:31 
OMG, auf meiner endlosen Suche nach einer Lösung, habe ich in einem anderen Forum einen beiläufigen Satz gefunden, der den Focus eines normalen Buttons verhindert!

ausblenden C#-Quelltext
1:
TabStop = false;					


Ich probier mir hier nen Wolf :D Leute es geht meistens einfach! :p
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 12.04.13 11:00 
Das ist das Problem mit den Fragen stellen aber nicht die Details mitgeben wollen ;)

Du hast gefragt wie man das focusieren verhindert zumindest ist das was hier angekommen ist. Deine Lösung ist jetzt aber den Button aus der Tabulatorreihenfolge zu nehmen. Wenn das reicht ok aber den Button per Keyboard focusieren und ausführen geht so natürlich immer noch. Man kann ja zum Beispiel per Cursortasten zum Button navigieren.
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Sa 13.04.13 12:37 
Wir können ja jetzt noch lange darüber diskutieren, was aber zu nichts führen wird.
1. Letztendlich habe ich das Problem oben beschrieben, dass der Button immer den Focus hat. Dieses Problem wurde nun umgangen.
2. Die Cursor-Tasten führen nicht zu einer Aktivierung/Fokussierung!
3. In meinem 2. Post @Gausi sollte der unspektakuläre Hintergrund ersichtlich sein.
4. Mir ist bewusst dass es immer die Vertreter gibt, möglichst viel wissen zu müssen, weil sie dann eventuell auf bestimmte Ideen kommen. Diese Lösung kann man durchaus auch ohne viel Hintergrundwissen finden. (Zusätzlich siehe Punkt 3)
5. Ich hatte auch gesagt, die Tastatur für den Button komplett abzuschalten. Folglich brauche ich kein TabStop.

So hoffe, dass wir die Diskussion nun beenden können.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 13.04.13 13:05 
OK dann keine Diskussion.

Dann nur eine Antwort zu dokumentarischen Zwecken für andere Leser.
TabStop verhindert nur das focussieren eines Controls über die Tabfolge es verhindert nicht das focussieren über andere Wege. In diesem speziellen Fall hier wo noch andere Dinge passieren mag das helfen im allgemeinen Fall wird das setzen von TabStop allein nicht helfen.
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Sa 13.04.13 14:06 
user profile iconSneedlewoods hat folgendes geschrieben Zum zitierten Posting springen:

2. ich habe KeyPreview auf true gestellt

hi, geht es dir darum, dass du die "tasten" nicht mehr angefangen kriegst, weil der Focus auf dem button ist?
wenn ja dann fang die "Tasten" doch mit
ausblenden Delphi-Quelltext
1:
2:
3:
//procedure in einem timer
GetAsyncKeystate( Taste ))
//Taste könnte ord('A') sein falls du herausfinden willst, ob A gedrückt wurde etc..

Hier eine Liste der Taste:
www.delphipraxis.net...ruck-simulieren.html

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Sa 13.04.13 21:00 
Hi Ihope,

doch Tasten bekomme ich immernoch abgefangen. KeyPreview bewirkt ja eben, dass die Tasten zuerst zu den Form-Events geleitet wird und danach erst zu den Controls. Allerdings wird der Button eben immer ausgelöst wenn ich Return, Leertaste, etc. drücke, was nicht erwünscht ist, weil er den Focus hat, was ebenfalls nicht erwünscht ist.

Aber wie schon erwähnt, funktioniert es in diesem Falle mit TabStop=false. Ich habe nicht viel rumprobiert, aber bisher konnte keine Taste den Focus auf den Button legen.

Also alles i.O. ;)
Sneedlewoods Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Sa 13.04.13 21:21 
Also Ralf hatte Recht. Sobald ich mit der Maus den Button anklicke, hat er den Focus wieder. Mit den Tasten habe ich nachwievor keine Probleme.
Also bleibt die Suche nach einer Sicheren Methode offen.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 14.04.13 12:17 
Hallo,

hast du denn die von Ralf Jansen vorgeschlagene Möglichkeit
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public class NonFocusButton : Button
{
    public NonFocusButton()
    {
        SetStyle(ControlStyles.Selectable, false);
    }
}

mal ausprobiert?

Anstatt abzuleiten, kannst du auch per Reflection diese Methode auf das Control (Button) anwenden:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
void SetControlNonSelectable(Control control)
{
    Type type = control.GetType();
    BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
    MethodInfo method = type.GetMethod( "SetStyle", flags );
    if(method != null)
    {
        object[] param = { ControlStyles.Selectable, false };
        method.Invoke(control, param);
    }
}
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 14.04.13 13:44 
Um es zu lösen:
- Tabstop des Buttons auf FALSE setzen
UND die OnClick Procedure sollte so aussehen (am Beispiel von Button1)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Visible := False;
Button1.Visible := True;
end;

allgemein also:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.ClickButton(Sender: TObject);
begin
(Sender as TButton).Visible := False;
(Sender as TButton).Visible := True;
end;


Edit: Es ist zwar in Delphi geschrieben, aber ich denke du verstehst damit was gemeint ist
-> Ein unsichtbares Object kann kein Focus haben ! somit verschwindet dieser bei Visisble := false;
damit der button aber weiterhin angezeigt wird wieder Visible := True;
... manche Compiler erkenen die "Sinnlosigkeit" und compilieren das deshalb gar nicht mit.. deshalb (falls das der Fall sein sollte) einfach mal ein delay(10) dazwischensetzen

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 14.04.13 14:14 
Im NonFocusButton Code von TH69 sicherheitshalber noch im Konstruktor den Basisklassen Konstruktor aufrufen.
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 14.04.13 14:21 
@Ralf Jansen:
Danke dass du TH69-Variante noch verbesserst :D Aber ich denke meine "Art" ist leichter umzusetzen/zu verstehen oder?

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 14.04.13 15:12 
@IhopeonlyReader: Ich vermute mal das das hier, in C#/Winforms mit vermutlich nur diesem Buttom auf der Form, nicht funktioniert.
Verstehe auch nicht wie das in Delphi helfen sollte? Wenn der Button den Focus bekommt wird kein Click ausgeführt. Warum sollte das rumschrauben an der Visibility in Click dann irgendwas ändern. Wenn du dafür sorgen willst das das der Button nach dem Click den Focus verliert, warum auch immer, sollte das einfacher gehen.
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: So 14.04.13 15:21 
weil er nur durch die Maus den Focus bekommen kann..

aber du hast recht, man kann natürlcih auch mit der maus den Focus setzten OHNE das onClick ergeignis auszuführen.
deshalb verbessert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.IrgendeinButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (Button=mbLeft) then (Sender as TButton).OnClick(Sender); //Diese Zeile ist nur Notwendig, falls der Button eine OnClick-Event besitzt
Button1.Visible := False;
Button1.Visible := True;
end;


Edit: In Delphi funktioniert dieser Code um einem Button den "Focus" wegzunehmen, in C# nicht wie ich gerade festgestellt habe...

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!


Zuletzt bearbeitet von IhopeonlyReader am So 14.04.13 15:45, insgesamt 1-mal bearbeitet
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 14.04.13 15:43 
Hallo Ralf,

der Default-Basisklassenkonstruktor wird in .NET automatisch beim Ableiten aufgerufen.
Nur wenn man einen Basisklassenkonstruktor mit Parametern aufrufen möchte/muß, dann muß man diesen explizit aufrufen.