2017-11-18 16 views
-1

編集コントロール(リッチエディットコントロールではない)でキャレットposを変更するイベントを処理する必要があります。キャレットポジションを変更するイベントをどのように処理できますか?

私は編集でテキストを変更するイベントを処理する方法を知っていますが、エディットコントロール内のキャレット位置を変更するイベントをどのように処理するかはわかりません。

誰かが私を助けてくれることを願っています。ありがとうございます。

+0

よく知られているように、通常の編集コントロールでは、キャレットposの変更、つまり選択の変更についての通知はありません。それに対処する1つの方法は、豊富な編集コントロールを使用し、['EN_SELCHANGE'](https://msdn.microsoft.com/en-us/library/windows/desktop/bb787987(v = vs.85))を処理することです。 aspx)。もう1つのアプローチは、通常のエディットコントロールを使用し続け、キャレットpos、つまりナビゲーションキーとマウスクリックを変更する可能性のあるすべてのイベントを処理することです。免責事項:「EN_SELCHANGE」がすべてのキャレット位置の変更をカバーしていることを100%保証しているわけではありません。私はセレクションがどこにキャレットがあるのか​​が分からないと思う。 –

+0

[XY問題](http://xyproblem.info)とよく似ている。あなたは本当に達成しようとしていますか? – IInspectable

+2

なぜdownvotes? **完全な無知から投票しないでください**。あなたが質問を理解していないときは、それを理解する能力が不足している可能性があるかどうかを検討してください。理解が不足していても、投票できる資格はありません。それはあなたが投票から逃れるべきである反対を意味します。 –

答えて

1

あなたが同じ位置に任意の位置から選択EM_SETSELメッセージ、送信することにより、エディットコントロール内のキャレットの位置を設定することができます。キャレットの位置を取得する

SendMessage(hWnd, EM_SETSEL, pos, pos); 

をする必要がありEM_GETSELメッセージを送信してください。開始点と終了点が同じ位置にある場合は、キャレットの正確な位置を知っていることに注意してください。違いがある場合は、テキストが選択されていることを意味し、最後のテキストを位置として取ることができます。

キャレット/選択の変更のみを追跡する特定のイベントはありません。あなたのイベントループでは、主要なプレスイベントとマウスイベントを捕らえ、ポジションを変更したかどうかを確認する必要があります。しかし、それを積極的に追跡するのではなく、必要なときにだけ、キャレットの位置を読み取ることは可能でしょうか?

+0

私はOPが逆のことを求めていると思います:キャレットの位置の変更について通知を受け取ります。 –

+0

@ Cheersandhth.- Alf Oops!ヒントのおかげで、私は逆の操作を完了するために編集しました。 – Christophe

1

これは、編集コントロール(SetWindowLongPtr)をサブクラス化し、潜在的にキャレットを移動させる可能性のあるメッセージについて親ウィンドウにメッセージを送信することによって、ステータスバーに行番号を表示するためにこれを行った後です。

#define CARET_MOVED_COMMAND_ID 50001 

WNDPROC OriginalEditProc = 0; 
HWND OriginalEditParent = 0; 

LRESULT WINAPI MyEditProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 
{ 
    // Handle message by original edit control procedure. 
    LRESULT result = CallWindowProc(OriginalEditProc, hwnd, msg, wparam, lparam); 

    switch (msg) 
    { 
    case WM_CHAR: 
    case WM_KEYDOWN: 
    case WM_KEYUP: 
    case WM_LBUTTONDOWN: 
    case WM_LBUTTONUP: 
    case WM_LBUTTONDBLCLK: 
    case WM_RBUTTONDOWN: 
    case WM_RBUTTONUP: 
    case WM_RBUTTONDBLCLK: 
    case WM_MBUTTONDOWN: 
    case WM_MBUTTONUP: 
    case WM_MBUTTONDBLCLK: 
    case EM_SETSEL: 
    // And maybe others... 
     // Notify parent of posible caret move. 
     // You can recreate EN_SELCHANGE behavior, I have been too lazy 
     // and was just sending command (like from menu). 
     SendMessage(OriginalEditParent, WM_COMMAND, MAKEWPARAM(CARET_MOVED_COMMAND_ID, 0), 0); 
     break; 
    } 
    return result; 
} 

// ---- In initialization code ---- 
// subclass 
OriginalEditParent = MyMainWindow; 
OriginalEditProc = (WNDPROC) SetWindowLongPtr(EditBoxHwnd, GWLP_WNDPROC, (LONG_PTR)MyEditProc); 

// ---- In parent window message handling ---- 
case WM_COMMAND: 
    switch (LOWORD(wparam)) 
    { 
    case CARET_MOVED_COMMAND_ID: 
     { 
      // You sould execute this code in EN_CHANGE handler, 
      // so it can handle cuting, pasting, undo etc. 
      int line = (int) SendMessage(EditBoxHwnd, EM_LINEFROMCHAR, -1, 0); 
      // Update status bar. Could be optimized by remembering 
      // displayed line number and updating only when it changes. 
      wchar_t buff[50]; 
      wsprintf(buff, L"%d", line); 
      SendMessage(StatusBarHwnd, SB_SETTEXT, MAKEWPARAM(1, SBT_NOBORDERS), (LPARAM) buff); 
     } 
     break; 
    } 
    break; 
+0

'SetWindowLongPtr'を[コントロールのサブクラス化](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183.aspx)と呼ぶことは10年以上にわたって間違った解決策でした。 – IInspectable

関連する問題