Rich Edit で文字列を検索する

Rich Edit Control のテキストを EM_FINDTEXT で検索します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. ウインドウに貼り付けた RichEdit のテキストから、キーワードを検索します。
    マウスの右クリックで、先頭から一個ずつキーワードを見つけ出して赤色で表示します。
    RichEdit にテキストを表示する手順は Rich Edit にテキストを表示する を参照して下さい。
  2. cfm は見つけたキーワードを赤色で表示するための CHARFORMAT 構造体です。
    Find はキーワードを検索するための FINDTEXT 構造体です。
    Pos は検索したキーワードのインデックスです。
    g_buf は RichEdit に表示するテキストデータです。
    HWND        g_hREdit= NULL;
    HMODULE     hRtLib= NULL;
    CHARFORMAT  cfm;            //CHARFORMAT 構造体
    FINDTEXT    Find;           //FINDTEXT 構造体
    int         Pos;            //検索位置
    
    LPSTR      g_buf=
    {  "0123key4567key89\n"
       "abcKEYkeydefg\n"
       "hijklmn\n"
       "opqrstuvwxyz\n"
       "ABCDEFGHkeyIJKLMN\n"
       "keyk07 入力長\n"
       "ファイル名 Key\n"
       "KEYTEST DATA\n"
       "1    2   3   key 4   5   6   7\n"
       "8    9   10  KEY\n"
       "999999key\n"
    };
    
  3. WM_CREATE から LoadLibrary() で RICHED32.DLL をロードします。
    CreateWindowEx() で Rich Edit を生成してウインドウに貼り付けます。
    SetWindowText() でテキスト(g_buf)を表示します。
    CHARFORMAT 構造体の初期設定を行います。
    見つけたキーワードを赤色で表示するために CFM_COLOR を設定しています。
    FINDTEXT 構造体の初期設定を行います。
    cpMin が検索開始位置で、cpMax が検索終了位置です。
    lpstrText に設定している "key" が今回検索するキーワードです。
        switch (msg)
        {   case WM_CREATE:
                hRtLib = LoadLibrary("RICHED32.DLL");
                g_hREdit = CreateWindowEx(WS_EX_CLIENTEDGE,"RICHEDIT","",
                        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_HSCROLL |
                        WS_VSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL,
                        0,0,0,0,hWnd,(HMENU)IDC_RICHEDIT,g_hInst,NULL);
                SetWindowText(g_hREdit,g_buf);
                //CHARFORMAT 構造体の初期設定
                memset(&cfm, 0, sizeof(CHARFORMAT));
                cfm.cbSize = sizeof(CHARFORMAT);
                cfm.dwMask = CFM_COLOR;
                //FINDTEXT 構造体の初期設定
                Find.chrg.cpMin= 0;
                Find.chrg.cpMax= GetWindowTextLength(g_hREdit);
                Find.lpstrText= "key";
                return 0L;
    
  4. Rich Edit Window 上で右クリックされた情報は、親ウインドウに WM_CONTEXTMENU: として伝えられます。
    親ウインドウでは CONTEXTMENU: を捕まえて検索を開始します。
            case WM_CONTEXTMENU:    //右クリックの通知
                Search();           //次の KEY を検索
                return 0L;
    
  5. キーワードを検索する Search() 関数です。
    EM_FINDTEXT でキーワードを検索します。
    Pos には見つけたキーワードの位置が格納されます。
    大文字小文字を区別するときは FR_MATCHCASE を、しないときは FR_NOUPDOWN を指定します。
    見つけたキーワードを選択状態にして、EM_SETCHARFORMAT で赤色に変えます。
    次のキーワードを検索するために、cpMin に Pos+3 を設定します。
    void Search()
    {
        //Pos= (int)SendMessage(g_hREdit,EM_FINDTEXT,FR_MATCHCASE,(LPARAM)&Find);
        //大文字小文字を区別しないとき
        Pos= (int)SendMessage(g_hREdit,EM_FINDTEXT,FR_NOUPDOWN,(LPARAM)&Find);
        if (Pos==-1)
        {   MessageBox(NULL,"見つかりません","FINDTEXT",MB_OK);
            return;
        }
        SendMessage(g_hREdit,EM_SETSEL,Pos,Pos+3);
        cfm.crTextColor= RGB(255,0,0);
        if (SendMessage(g_hREdit,EM_SETCHARFORMAT,SCF_SELECTION|SCF_WORD,(LPARAM)&cfm)==0)
            MessageBox(NULL,"EM_SETCHARFORMAT 失敗です", "Error", MB_OK);
        Find.chrg.cpMin= Pos+3;
    }
    

【NOTE】

  1. WM_SIZE で Rich Edit のサイズをウインドウサイズに合わせる方法です。
        RECT    rc;
    
            case WM_SIZE:
                GetClientRect(hWnd,&rc);
                MoveWindow(g_hREdit,rc.left,rc.top,rc.right,rc.bottom,TRUE);
                break;
        
    lp で渡されたパラメータを利用して設定することも出来ます。
            case WM_SIZE:
                MoveWindow(g_hREdit,0,0,LOWORD(lp),HIWORD(lp),TRUE);
                break;
        
  2. Rich Edit でテキストを EM_EXSETSEL で選択する方法です。
        CHARRANGE   cr;     //Chracter Range
        cr.cpMin= Pos;
        cr.cpMax= Pos+3;
        SendMessage(g_hREdit,EM_EXSETSEL,0,(LPARAM)&cr);
        
    一般的な Edit Control で用いられる EM_SETSEL を使う方法です。
        SendMessage(g_hREdit,EM_SETSEL,Pos,Pos+3);
        
    全テキストを選択する場合です。
        SendMessage(g_hREdit,EM_SETSEL,0,GetWindowTextLength(g_hREdit));
        

超初心者のプログラム入門(Win32API C++)