Position der Einfügemarke (Caret) in einem Editfeld



  • Hallo,

    ich frage in einem StringGrid während des Editierens einer Zelle (InplaceEditor = edNormal) die Caretposition ab, um bestimmte Zeichen finden zu können.

    Die Abfrage erfolgt jeweils im OnSetEditText- und OnKeyDown-Ereignis.

    void __fastcall Tprofiltabelle::u1_gridKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
      if(!static_cast<TAdvStringGrid*>(Sender)->EditMode)
        return;
    
      String Value = "";
    
      if(Key == VK_CLEAR || Key == VK_BACK || Key == VK_DELETE)
      {
        static_cast<TWinControl*>(Sender)->Parent->Tag = 1;
        TabSheet6->Tag = 1;
        calc_rules->Tag = 1;
      }
    
      // Handle des InPlaceEditors holen
      HWND hWnd = static_cast<TAdvStringGrid*>(Sender)->NormalEdit->Handle;
      if(hWnd)
      {
        Value = static_cast<TAdvStringGrid*>(Sender)->NormalEdit->Text;
    
        // Caretposition abfragen (wenn nichts markiert ist, dann ist
        // dwstart == dwend
        SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwstart, (LPARAM)&dwend);
    
        // Ausgabe in der Statusbar zur Kontrolle
        MainForm->tbxsb1->Panels->Items[3]->Caption = "dwstart:  "+(String)dwstart+
                        "   dwend:  "+(String)dwend+"   Textlänge:  "+IntToStr(Value.Length());
    
        if(dwstart-1 > 0)
        {
          if(!Value.IsEmpty())
          {
            if(Value[dwstart-1] == WK_VARDELIMITER_LEFT && Value[dwend+1] == WK_VARDELIMITER_RIGHT)
              ShowVarBox(Sender);
          }
        }
      }
    }
    //---------------------------------------------------------------------------
    

    Dabei habe ich folgendes Verhalten festgestellt, welches ich mir nicht erklären kann:

    Bei folgender Tastenfolge und einer Textlänge von 26:
    VK_END --> VK_LEFT --> VK_LEFT --> VK_RIGHT ändern sich die Werte wie folgt
    (dwstart und dwend jeweils gleich) : 26 26 25 24

    Bei einer Tastenfolge von:
    VK_HOME --> VK_RIGHT --> VK_RIGHT --> VK_RIGHT --> VK_LEFT bekomme ich folgende Werte : 0 0 1 2 3 2

    Hat jemand von Euch evtl. eine Erklärung für dieses seltsame Verhalten.
    (Ich arbeite mit BCB6 und WinXP)

    Falls das Thema ins WinAPI-Forum gehört, bitte verschieben.

    Gruß Udo



  • Schuss ins Blaue:
    Das KeyDown-Event ist ja u.A. dazu da, bestimmte Tasten zu blockieren (Key 0 setzten), ohne das der Key schon Auswirkung hatte.
    Heißt also dein Carret ist noch nicht an der neuen Position, sondern erst nach dem Event (Deine Ausgabe zeigt ja auch ein um ein Event verzögertes Bild).
    OnKeyPress oder OnKeyUp wären wohl angebracht. Welches jetzt das richtige ist, weiß ich nicht.

    mfg
    xXx



  • Hallo,

    im OnKeyPress kann man wohl die Sondertasten nicht abfragen und im OnKeyUp hatte ich (glaub ich mich zu erinnern) das gleiche seltsame Verhalten.

    Udo



  • Hallo,

    ich habe jetzt mal mit dem OnKeyUp-Event probiert:

    void __fastcall Tprofiltabelle::u1_gridKeyUp(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
      if(!static_cast<TAdvStringGrid*>(Sender)->EditMode)
        return;
    
      String Value = "";
      Shift = NULL;
    
      if(Key == VK_CLEAR || Key == VK_BACK || Key == VK_DELETE)
      {
        static_cast<TWinControl*>(Sender)->Parent->Tag = 1;
        TabSheet6->Tag = 1;
        calc_rules->Tag = 1;
      }
    
      HWND hWnd = static_cast<TAdvStringGrid*>(Sender)->NormalEdit->Handle;
      if(hWnd)
      {
        Value = static_cast<TAdvStringGrid*>(Sender)->NormalEdit->Text;
    
        SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwstart, (LPARAM)&dwend);
    
        MainForm->tbxsb1->Panels->Items[3]->Caption = "dwstart:  "+(String)dwstart+
                        "   dwend:  "+(String)dwend+"   Textlänge:  "+IntToStr(Value.Length());
    /*
        if(dwstart-1 > 0)
        {
          if(!Value.IsEmpty())
          {
            if(Value[dwstart-1] == WK_VARDELIMITER_LEFT && Value[dwend+1] == WK_VARDELIMITER_RIGHT)
              ShowVarBox(Sender);
          }
        }
    */
      }
      Key = 0;
    }
    //---------------------------------------------------------------------------
    

    Die Ausgabe in der Statusbar erfolgt bei den Tasten 'Ende' und 'Pos1'.
    Bei betätigen der Pfeiltasten rechts oder links kommt die Ausgabe nur, wenn ich jeweils nach der Pfeiltaste die Umschalttaste drücke.
    Die ausgegebene Caretposition scheint dann allerdings richtig zu sein.

    Was mache ich denn jetzt noch falsch (muß ich TShiftState extra abfragen???)

    Gruß Udo



  • Hallo,

    Keiner eine Ahnung, warum das Betätigen der Pfeiltasten rechts und links kein OnKeyUp-Ereignis auslöst???

    OnKeyPress wird durch diese Tasten auch nicht ausgelöst.

    Gruß Udo



  • Udo11 schrieb:

    Keiner eine Ahnung, warum das Betätigen der Pfeiltasten rechts und links kein OnKeyUp-Ereignis auslöst???

    Vermutlich wird CM_CHILDKEY (Taste im untergeordneten Fenster) gesendet.

    Warum machst du 3 Fragezeichen ??? 😃





  • Hallo,

    @Jansen
    Danke für den Link, das könnte die Lösung sein.
    Ich werde das mal versuchen und mich wieder melden.

    Udo



  • Hallo,

    Ich brauche nochmal Eure Hilfe. Ich muß die Pfeiltasten im InPlaceEdit des AdvStringGrid abfragen. Jetzt ist mir nicht klar, wie bzw. wo (in welchem Header und .cpp).

    In dem Link steht, das der WM_GETDLGCODE Handler auf Control-Ebene geschrieben werden muß.

    Note: Don't create a WM_GETDLGCODE handler for your form. You must write the WM_GETDLGCODE handler at the control level.

    Gruß Udo



  • @Jansen

    Ich habe die Vorgehensweise aus Deinem Link nicht ganz verstanden.
    Wenn ich folgendes in die .cpp meiner Form einfüge:

    void __fastcall TBaseGrid::WMGetDlgCode(TMessage &Message)
    {
      if(Options.Contains(goEditing))
        Message.Result |= DLGC_WANTARROWS;
    }
    //---------------------------------------------------------------------------
    

    kommen folgende Compilerfehlermeldungen:

    [C++ Error] BaseGrid.hpp(175): E2247 Zugriff auf '_fastcall TCustomGrid::WMGetDlgCode(TWMNoParams &)' nicht möglich
    [C++ Error] BaseGrid.hpp(175): E2034 Konvertierung von 'TMessage' nach 'TWMNoParams' nicht möglich
    [C++ Error] BaseGrid.hpp(175): E2342 Keine Übereinstimmung des Typs beim Parameter 'Msg' ('TWMNoParams &' erwartet, 'TMessage' erhalten)

    Ich glaube, ich habe da grundsätzlich etwas nicht verstanden.
    Kannst Du mir eventuell noch bischen auf die Sprünge helfen?

    Gruß Udo


Log in to reply