Anklicken einer Editbox = kompletten Text selektieren



  • Hi,

    ich würde gerne eine Editbox so einrichten, dass wenn der User sie anklickt zunächst der gesamte Text markiert wird. Erst beim zweiten Klick soll der Cursor (Caret) an die entsprechende Stelle positioniert werden. Ich habe es mit Behandlung von SETFOCUS probiert, allerdings funktioniert das nur, wenn ich die Editbox über den Tabulator anwähle. Klicke ich mit der Maus hinein, wird unmittelbar der Cursor an die entsprechende Stelle gesetzt.

    Eine Idee, die ich hatte, war, auf LBUTTONDOWN zu reagieren, wenn die Linke Maustaste innerhalb des Controls gedrückt wird und mir zusätzlich über ein Flag (bzw. einen Count), das (der) bei KILLFOCUS zurückgesetzt wird, zu merken, ob es "der erste Klick" in das Feld war. Aber zuvor wollte ich mal nachfragen, ob man das nicht weniger kompliziert haben kann.

    Danke schon mal!


  • Mod

    Das geht einfacher.
    Bau einen LButtonDown Handler. Wenn der Handler angesprungen wird, dann prüfst Du ob das aktuelle Control den Focus hat und setzt ein Flag. Dan führst Du den default aus, was dann den Focus setzt. Anschließend SetSel aufrufen wen es den Focus frisch bekommen hat.

    Pseudocode:

    void CMyEdit::OnLButtonDown(...)
    {
        bool bHasFocus = GetFocus()==this;
        Default();
        if (!bHasFocus)
            SetSel(0,GetWindowTextLength());
    }
    


  • Nachdem ich angefangen hatte meine oben beschriebene Idee umzusetzen, habe ich festgestellt, dass es für CEdit kein WM_LBUTTONDOWN gibt 😞 und habe mir deshalb (wie du es mit CMyEdit ja auch vorschlägst) eine eigene Editbox-Klasse von CEdit abgeleitet.

    Der Rest deines Vorschlag ist clever (hat funktioniert)! Vielen Dank für den Tip!

    Anschließend wusste ich dann zwar zunächst nicht, wie ich für meine eigene Editbox-Klasse DDX verwende, da ich das Control mittels Create() (und nicht im Dialog-Editor) erzeugt hatte.
    Schließlich habe ich aber SubclassDlgItem() gefunden und damit erreicht, was ich wollte 🙂



  • Wieso hast du das per Create gemacht?
    Wenn du weiterhin mit dem Dialog-Editor arbeiten möchtest, musst du nur eine Controlvariable für das Edit anlegen lassen und dann den Typ in deine eigene Klasse ändern.
    Das funktioniert für jedes selbstgebastelte Control. 🙂



  • So habe ich es am Ende auch gemacht, allerdings dachte ich, ich müsste zusätzlich CMyEdit::SubclassDlgItem() aufrufen, damit es funktioniert...
    Oder ist das überflüssig? Muss ich vielleicht später noch einmal ausprobieren...



  • Ich glaube, das ist überflüssig.
    Ich habe diese Zeile nichtmal in meinem Projekt (wo ich sowas oft mache) nicht finden können.
    😉


  • Mod

    Das einfachste ist den Classwizard ein normales CEdit Control anbinden zu lassen.
    Anschließend ändert man in der Header-Datei nur den Klassennamen von CEdit auf CMyEdit...



  • Ok, habe SubclassDlgItem() wieder herausgenommen, alles funktioniert wie gehabt, es scheint also tatsächlich überflüssig zu sein. Danke noch mal für die Infos!

    P.S.:
    Ich hatte das aus "Kruglinski, Shepherd, Wingo: Inside Visual C++ 6.0".
    Dort heißt es (kurz gefasst), man müsse folgendermaßen vorgehen:
    1. Control im Dialog-Editor hinzufügen.
    2. Eigene Klasse von gewünschtem Control ableiten.
    3. Membervariable vom Typ der eigenen Klasse zur Dialogklasse hinzufügen.
    4. Wenn mit einer Dialogfeldklasse gearbeitet wird: einfügen von

    m_myControl.SubclassDlgItem(IDC_MYCONTROL, this);
    

    in OnInitDialog().
    5. Wenn mit einer Formularansichtsklasse gearbeitet wird: einfügen von

    if(m_myControl.m_hWnd == NULL)
        m_myControl.SubclassDlgItem(IDC_MYCONTROL, this),
    

    in OnInitUpdate().

    Außerdem wird auf die "MFC Technical Note #14" verwiesen. Wirklich klar geworden ist mir der Sinn und Zweck von SubclassDlgItem() beim Lesen allerdings nicht...


  • Mod

    Ein Fenster das durch Windows erzeugt wurde hat mit Deiner Klasse und den dort festegelegten Handlern nichts zu tun. Zudem wird das Control ja durch den Ressource-Editor und die Diaog Routinen angelegt und erzeugt.

    SubclassDlgItem verbindet nun dieses Control mit der Fenster-Prozedur (Klassen-Objekt), das Du angelegt hast. Nur so wird Deine Klasse mit _diesem_ Fenster auch verwendet!


Anmelden zum Antworten