● 文字列を検索する ●

ここまでやったらとことんいきましょう。

文字列検索をやりたいと思います。文字列が見つかったらその文字列を反転させ、見つからないなら Beep音を鳴らすという仕様にしてみたいと思います。ここで復習をします。文字列を選択状態にする方法は以下の通りでしたね。

Call SendMessage(hTextbox, EM_SETSEL, 選択開始位置, ByVal 選択終点位置)

さて、文字列を検索するにはちょっと工夫が必要です。なにせ、文字コードの土俵が違いますからね。API側は ANSI、VB側は UNICODE となっていることは、今更、言うまでもないでしょう。VBには Instr関数 があります。作る側としてはこの関数を利用したいところです。(というか、APIで文字列検索する方法が分からないだけです。C言語で言う strstr 関数みたいなAPI関数ってあるのでしょうか?)

まず、メモ帳から文字列を取得する必要がありますね、この方法は既に紹介済みです。VBの文字列変数に取得さえできれば Instr関数 を使えるので大丈夫ですね。次に、Instr関数 を使用して文字列検索を試みます。文字列が見つかれば、見つかった位置、見つからなければ0を取得します。0を取得したら、 Beep音 を鳴らして終了処理をします。0でない値を取得すればどうしたらいいのでしょう。例えば、"一二三123あいう"から"い"を検索して返る値はです。当然のことながら、文字列を選択状態にするには SendMessage関数 を使わないといけないのでではなく11を取得しなければなりません。さて、どうするかというと、Left$関数 で "一二三123あ" までを取得します。そうしたら"一二三123あ"のバイト数を取得すればいいのです。こうすれば選択開始位置11を取得することができます。選択終点位置は、先の11に"い"のバイト数を足した値、すなわち13ということになります。以上のことをふまえて、関数を書いてみます。

Private Const EM_SCROLLCARET = &HB7  'キャレット位置にスクロールする

'---------------------------------------------------------------
' 関数名: SearchText
' 機能 : メモ帳の文字列を検索する
' 引数 : (in) hEditbox … メモ帳のエディットボックスのハンドル
'     (in) srcText … 検索文字列
'     (in) StartPos … 検索開始位置
' 返り値 :次回検索開始位置、文字列が見つからなかった:0
'---------------------------------------------------------------
Public Function SearchText(ByVal hEditbox As Long, ByVal srcText As String, ByVal StartPos As Long) As Long

  Dim gTextBuff As String
  Dim SearchPos As Long
  Dim SelStartPos As Long '選択開始位置
  Dim SelEndPos As Long  '選択終了位置

  'メモ帳の文字列を取得
  gTextBuff = GetEditboxText(hEditbox)

  If StartPos < 1 Then StartPos = 1

  '文字列検索
  SearchPos = InStr(StartPos, gTextBuff, srcText)

  '文字列発見
  If SearchPos Then
    SelStartPos = GetStrLenB(Left$(gTextBuff, SearchPos - 1)) '選択開始位置を取得
    SelEndPos = SelStartPos + GetStrLenB(srcText)     '選択終了位置を取得

    Call SendMessage(hEditbox, EM_SETSEL, SelStartPos, ByVal SelEndPos) '範囲選択
    Call SendMessage(hEditbox, EM_SCROLLCARET, 0&, ByVal 0&) 'スクロール

    SearchText = SearchPos + Len(srcText)
  Else
    Beep
  End If

End Function

'----------------------------------------------------------------
' 関数名 : GetStrLenB
' 機能 : 文字列のバイト数を取得する
' 引数 : (in) srcString … 調査対象文字列
' 戻り値 : 文字列のバイト数
'----------------------------------------------------------------
Public Function GetStrLenB(ByVal srcString As String) As Long

  GetStrLenB = LenB(StrConv(srcString, vbFromUnicode))

End Function

1つ見慣れない関数がありますね。

  Call SendMessage(hEditbox, EM_SCROLLCARET, 0&, ByVal 0&)

これは、キャレットがある位置にエディットボックスをスクロールする関数です。これがあるのとないのでは大違いです。どう違うのかと疑問にもう方がいれば、この部分をコメントアウトしてその動作を試してみてください。文字列のバイト数を取得する関数については、こちらで説明しているので参照してください。

下のコードで動作確認してください。文字列"あいう"を検索するコードです。連続して押すことで次の"あいう"を検索できるようになっています。この場合は"あいう"ですが、この部分を改造してより良い関数を作成してください。

Private Sub cmdTextSearch_Click()

  Static StartPos As Long

  StartPos = SearchText(hEditbox, "あいう", StartPos)

End Sub


[ インデックスページへ  |  前のページへ  |  次のページへ ]