Text auf inaktiver Form mit dem ersten Klick selektieren

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Text auf inaktiver Form mit dem ersten Klick selektieren

    Guten Morgen,

    ich versuche gerade folgendes zu realisieren:

    Es sind 2 Forms vorhanden auf der einen Form befindet sich eine Rich
    Text Box, auf der anderen Form ein paar Buttons, wenn man auf diese
    Buttons klickt verändert sich der Text in der Rich Text Box. Nun ist die
    Form mit den Buttons im Vordergrund und die Form mit der Rich Text Box
    im Hintergrund und inaktiv. Versuche ich nun in die Rich Text Box zu
    klicken und einen Teil des Textes zu selektieren funktioniert dies
    nicht. Ich muss zuerst einmal in die Textbox klicken um die Form(?) und
    die Textbox wieder auf aktiv zu setzen und erst dann kann ich den Text
    markieren. Dieses 2 Mal klicken ist auf Dauer ganz schön nervig.



    Ich habe schon einiges versucht, am offensichtlichsten erschien mir ins
    MouseDown Event der TextBox einzusteigen und dort sofort den Focus an
    die Textbox zu übergeben, dies funktioniert jedoch nicht. Die Textbox
    hat zwar dann den Fokus aber da die Maustaste ja schon gedrückt wurde
    erkennt sie trotzdem nicht, dass ich jetzt eigentlich den Text markieren
    möchte.

    Die einzige Variante, welche mich bis jetzt zu meinem Ziel geführt hat
    war im MouseMove Event der Textbox den Fokus zu setzen, dies ist jedoch
    auf Dauer auch nervig, da jedesmal wenn ich mit der Maus über die
    Textbox fahre, diese den Fokus bekommt und sofort in den Vordergrund
    springt.



    Ich weiß nicht ob es hierfür eine einfache Lösung gibt oder ob ich
    einfach nur zu kompliziert denke, aber irgendwie muss es ja möglich
    sein, da Anwendungen wie OpenOffice oder Notepad++ ja auch dazu im
    Stande sind, dass ich mit nur einem Klick sofort den Text markieren
    kann.



    Ich wäre sehr dankbar falls jemand einen Lösungsvorschlag für mich hätte!
    Willkommen im Forum :thumbup:
    Du musst die 2. Form als nicht modalen Dialog aufrufen.

    VB.NET-Quellcode

    1. Dim dlg As New Form1
    2. '...
    3. dlg.ShowDialog() ' modal
    4. dlg.Show() ' nicht modal, Form kann hinter die Mainform geklickt werden
    5. dlg.Show(Me) ' nicht modal, Form kann nicht hinter die Mainform geklickt werden
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke für die schnelle Antwort, dies löst das Problem jedoch leider nicht.

    Die Form mit ShowDialog aufzurufen ist ja in meinem Fall sowieso unsinn, da ich die 2.Form ja immer nebenher laufen lassen will, damit man den sich verändernden Text ständig betrachten kann.
    Also bleibt nur Show und Show(Me) über, da bei Show(Me) die Mainform immer im Hintergrund ist, fällt diese Option auch weg. Also bleibt nur noch Show über, genau so wie ich meine Form auch aufrufe.

    Der Aufruf und das ändern des Textes klappt ja auch alles super. Es ist eben nur dieses 2 Mal klicken, welches mich stört. Ich habe die Form mit den Buttons z.B. auf der linken Seite des Bildschirms und die Form mit der Textbox auf der rechten Seite. Jetzt habe ich gerade auf den weiter Button gedrückt und lese mir den neuen Text in der rechten Form durch (Da ich auf den Button gelickt habe ist somit die linke Form, mit den Buttons noch die aktive).
    Nun erkenne ich in der rechten Form im Text (befindet sich in einer RichTextBox) eine wichtige Stelle und will diese mit der Maus selektieren um sie dann zu kopieren oder irgendetwas anderes damit anzustellen.
    Also mit der Maus in die Textbox gefahren, geklickt und Maus nach rechts bewegt, doch siehe da, man kann den Text nicht markieren.
    Ich muss praktisch erst einmal in die Textbox klicken, damit diese den Fokus bekommt und erst dann kann ich mit einem 2. Klick und mit gedrückter Maustaste den Text markieren.
    Ich hab jetzt Deinen Post 2x gelesen und bin wohl immer noch nicht ganz schlau.
    Versuch bitte mal, Dein Problem in 3 Sätzen zu formulieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Okay, wenn du mal den Editor öffnest und einfach ein paar Zeichen eingibst bzw. irgendeine Textdatei öffnest und jetzt ein Explorer Fenster bzw. irgendein anderes Fenster in den Vordergrund holst (nicht Maximiert, sondern nur so, dass ein Teil des Editors verdeckt ist).

    Versuchst du nun den Teil des Textes im Editor zu markieren den du noch sehen kannst (obwohl der Editor ja im Hintergrund ist und zum Teil vom Explorer verdeckt wird) kannst du sofort den Text markieren.

    Dies geht bei meiner Anwendung nicht, ich muss erst einmal in die Form klicken welche sich im Hintergrund befindet (dann springt diese in den Vordergrund und bekommt den Fokus) und dann noch ein zweites mal um den Text zu markieren.
    Mal sehen, ob ich Dich richtig verstanden habe:
    Um bei einem Programm, das keinen Fokus hat, eine Aktion auszulösen, musst Du 2x draufklicken, um dies zu tun.
    OK.
    Dieses Problem kenne ich, da reicht schon ein Button_Klick, der nicht funktioniert.
    Offensichtlich ist dies bei .NET-Programmen so.
    bei C++ und Co-Programmen nicht.
    Sorry. :S
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Um bei einem Programm, das keinen Fokus hat, eine Aktion auszulösen, musst Du 2x draufklicken, um dies zu tun.
    OK.

    Das sagt er. Aber das stimmt nicht ;)
    Button.Click -> Geht
    TextBox.Select -> Geht
    RichTextbox.Select ... -> Geht nicht ;)

    Ist also eine Eigenart des RTB Control. Muss man schauen, ob man ihm das abgewöhnen kann, oder man verwendet halt keine RTB (sondern zb Multiline Textbox)
    Mit anderen Controls habe ich dies leider nocht nicht ausprobiert mir ist es nur explizit bei der RichTextBox aufgefallen, aber es muss doch irgendein Workaround hierfür geben, damit die RichTextBox schon beim ersten Mal klicken erkennt, dass ich nun einen Text markieren will, wie gesagt ich habe schon einiges im MouseDown Event probiert, aber bin dadurch leider noch zu keiner Lösung gekommen
    Ins Fokus Event komm ich komischerweiße niemals rein!

    Wenn ich eine Funktion baue welche das .GotFocus Event der Form behandelt und mir dort einen Brakepoint setze kann ich machen was ich will, er kommt niemals in die Funktion rein, egal ob ich wild zwischen den Forms hin und her klicke, es passiert nichts. Selbst wenn ich im Form_Load Event implizit einbaue Me.Focus() kommt er nicht in das Event hinein. Dies betrifft beide Events sowohl .GotFocus, als auch .LostFocus und andere Events zum Fokus gibt es ja nicht
    Probier mal das Activated-Event der Form:

    VB.NET-Quellcode

    1. Private Sub Form1_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Activated
    2. End Sub

    Aber mach da keine MessageBox rein. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Okay vielen Dank das hat mich schonmal ein gutes Stück weiter gebracht.
    Es reicht jedoch nicht der RichTextBox in diesem Event dann den Fokus zu setzen.
    Die einzige Möglichkeit die Momentan zum gewünschten Ergebnis führt ist das simulieren eines MouseUp und anschließen wieder eines MouseDowns, damit wäre ich immernoch bei den 2 Klicks, wobei 1 Klick jedoch programmiertechnisch umgesetzt wäre, das ganze ist zwar nicht wirklich schön gelöst, aber scheint mir momentan die einzige Möglichkeit zu sein
    Poste mal bitte Deinen Code, ich würde da gern mal drüber sehen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Okay also, folgendes Szenario:

    2 Forms:
    - 1. Form frmChgTxt, auf dieser befinden sich 2 Buttons ein Button um die Form mit der RichTextBox anzuzeigen und ein Button um den Text in der RichTextBox zu ändern
    - 2. Form frmShowTxt, auf dieser befindet sich nur die RichTextBox

    VB.NET-Quellcode

    1. Public Class frmChgTxt
    2. Private shwTxt As New frmShowTxt
    3. Private Sub cmdShwTxt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShwTxt.Click
    4. shwTxt.Show()
    5. End Sub
    6. Private Sub cmdChgTxt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdChgTxt.Click
    7. shwTxt.rtbText.Text = shwTxt.rtbText.Text + "aaaa aaaa aaaa aaaa aaaa aaaa aaaa"
    8. End Sub
    9. End Class


    VB.NET-Quellcode

    1. Public Class frmShowTxt
    2. Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
    3. Public Const MOUSEEVENTF_LEFTDOWN = &H2
    4. Public Const MOUSEEVENTF_LEFTUP = &H4
    5. Private Sub frmShowTxt_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    6. rtbText.Text = "aaaa aaaa aaaa aaaa aaaa aaaa"
    7. End Sub
    8. Private Sub frmShowTxt_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Activated
    9. mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    10. mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    11. End Sub
    12. End Class


    Der ganze Code ist hier natürlich stark vereinfacht
    Wo soll denn das hinklicken?

    VB.NET-Quellcode

    1. mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    2. mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe für X und Y einfach willkürliche Werte gewählt, da ich das Form Activate Event ja nicht mit
    ByVal e As System.Windows.Forms.MouseEventArgs

    aufrufen kann und somit auch nicht auf die Koordinaten e.X und e.Y zugreifen kann.

    Das Intresannte an der ganzen Sache ist egal was ich angebe, selbst wenn ich

    VB.NET-Quellcode

    1. mouse_event(MOUSEEVENTF_LEFTUP, 1500, 2000, 0, 0)
    2. mouse_event(MOUSEEVENTF_LEFTDOWN, 1500, 2000, 0, 0)


    eingebe wird der Klick genau an der Stelle ausgeführt, an welcher ich den Mausklick mit der Maus ausführe.
    Wenn ich z.B. auf die Titelleiste der Form klicke wird nicht wie vielleicht vermutet mein Mausklick ausgeführt
    und dann noch ein Mausklick auf die Koordinaten die ich oben angegeben habe. Sondern er führt einen zweiten
    Klick auf die Stelle aus, an welche ich bereits geklickt habe.
    MSDN:
    Windows NT/2000/XP: This function has been superseded. Use SendInput instead.
    ...
    dx
    [in] Specifies the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is specified as the mouse's actual x-coordinate; relative data is specified as the number of mickeys moved. A mickey is the amount that a mouse has to move for it to report that it has moved.
    dy
    [in] Specifies the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is specified as the mouse's actual y-coordinate; relative data is specified as the number of mickeys moved.

    Klingt ein wenig merkwürdig.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja mir war das ganze auch etwas suspekt, aber:

    Ich kann das ganze sehr einfach nachvollziehen, ich führe einen Klick auf die Titelleiste der Form aus und siehe da die Form wird auf einmal maximiert, so als ob ich einen Doppelklick ausführe (was ich ja eigentlich auch tue, da der eine Klick ja vom Programm simuliert wird). Also wird der simulierte Klick definitiv auf die selbe Stelle ausgeführt, auf welcher der reelle Klick schon ausgeführt wurde.