● 選択されている文字列を取得する ●

ちょっと効率が悪い処理。

選択文字列を取得するには、まず選択されている位置を取得しなければなりません。それは、 SendMessage 関数に EM_GETSEL メッセージを送ることによって返される値より選択範囲を取得できます。戻り値の下位ワードから選択開始位置、上位ワードから選択終了位置を取得するわけです。上位ワード・下位ワードとは簡単に言うと、32ビットを上位・下位16ビットずつに分けた値のことを言います。よって、

  上位ワード は 戻り値 ÷ &H10000(=2の16乗) の商
  下位ワード は 戻り値 ÷ &H10000(=2の16乗) の余り

より取得できます。それでは早速、関数を書いてみましょう。

'---------------------------------------------------------------
' 関数名: GetHiWord
' 機能 : 上位ワードの値を返す
' 引数 : (in) srcValue … 32ビット値
' 返り値 : 上位ワード値
'---------------------------------------------------------------
Private Function GetHiWord(ByVal srcValue As Long) As Integer

  GetHiWord = srcValue \ &H10000

End Function

'---------------------------------------------------------------
' 関数名: GetLoWord
' 機能 : 下位ワードの値を返す
' 引数 : (in) srcValue … 32ビット値
' 返り値 : 下位ワード値
'---------------------------------------------------------------
Private Function GetLoWord(ByVal srcValue As Long) As Integer

  GetLoWord = srcValue Mod &H10000

End Function

本来なら、srcValue が &H8000000 以上であればエラー処理を施すといったことをしなければならないのですが、ここでは行いません。では、関数を書いてみます。

Private Const EM_GETSEL = &HB0  '選択されている位置を取得する

'----------------------------------------------------------------
' 関数名 : GetSelText
' 機能 : 選択されている文字列を取得する
' 引数 : (in) hEditbox … メモ帳のエディットボックスのハンドル
' 戻り値 : 選択されている文字列
'----------------------------------------------------------------
Private Function GetSelText(ByVal hEditbox As Long) As String

  Dim ret As Long
  Dim PrmLoWord As Integer '選択領域開始位置
  Dim PrmHiWord As Integer '選択領域最後尾位置
  Dim EditBoxText As String

  ret = SendMessage(hEditbox, EM_GETSEL, 0&, ByVal 0&)

  PrmLoWord = GetLoWord(ret) + 1
  PrmHiWord = GetHiWord(ret) + 1

  'エディットボックスの文字列を取得する(ANSI文字として)
  EditBoxText = StrConv(GetEditboxText(hEditbox), vbFromUnicode)

  GetSelText = StrConv(MidB$(EditBoxText, PrmLoWord, PrmHiWord - PrmLoWord), vbUnicode)

End Function

ちょっと効率悪い処理かもしれませんがしょうがないですね。まず、選択範囲の位置を取得します。PrmLoWord や PrmHiWord に1を足しているのは、後で使用する MidB$ 関数の第2引数の初期値が1だからです。(PrmLoWord = 0のときエラーが発生してしまいます。)そうしたら、エディットボックス文字を取得し、これを ANSI 形式にします。何故って、PrmLoWord、PrmHiWord には ANSI形式 の文字列を対象とした、文字列選択範囲の位置が格納されているからです。UNICODE と ANSI とでは土俵が違うのです。さて、ANSI 形式に戻したところで、MidB$ 関数より文字列を切り出します。Mid$ ではありませんよ。切り出したら、再び UNICODE に戻します。

ANSI → UNICODE → ANSI → UNICODE とコロコロ文字形式を変えなければならないのが Visual Basic の辛いところですね。


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