● メモ帳でも作ってみるか ●

いろいろやってきたメモ帳の遠隔操作はもう終わり。このページはおまけだよ。

さて、もうメモ帳遠隔操作のネタはなくなりました。従って、もう止めてもいいのですがもうちょっと遊ばしてください。ちょっとメモ帳作成に関する可能性でも示唆させていただこうと思います。遠隔操作だけではもったいないので、いっそのことメモ帳を作っちゃいましょう。さらに調子に乗って、テキストボックスでなくエディットボックスを使用しましょう。Visual Basic でエディットボックスなんて馬鹿げていますが、まぁ、何事も経験です。

エディットボックスは何かといいますと、簡単に言えばテキストボックスです。ただ、テキストボックスとは違い、プロパティ・メソッドはないので、必要に応じて自力で書かねばなりません。また、デフォルトではエディットボックスは32KBまでしか編集できません。紹介はこんなところでいいでしょう。

さて、メモ帳を作るといいましても、そのコードをすべてここで紹介するわけにはいかないので必要と思われる事だけを書くことにします。まずは、エディットボックスの作成です。「は?作る」と思われるかもしれませんが、そのとおり作るのです。作るには、 CreateWindowEx というAPI関数を利用します。関数が成功すると作成したウインドウのハンドルを返してくれます。「エディットボックスってウインドウなの?」と思う方がいるかもしれません。思い出してください。メモ帳は親ウインドウに子ウインドウとしてエディットボックスが張り付いている、という構成でした。エディットボックスはそれ自体ハンドルを持っているので立派なウインドウなのです。さて、 CreateWindowEx の宣言や引数は以下の通りです。

Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByVal lpParam As Long) As Long

dwExStyle    … 拡張ウインドウスタイル
lpClassName  … 作成するコントロールのクラス名
lpWindowName … タイトルバーに表示する文字列
dwStyle    … ウインドウスタイル
X        … ウインドウのX座標
Y        … ウインドウのY座標
nWidth     … ウインドウの幅
nHeight    … ウインドウの高さ
hWndParent … 親ウインドウのハンドル
hMenu    … メニューのハンドル
hInstance  … インスタンスのハンドル
lpParam   … ウィンドウへ送る作成データ

さて、メモ帳には右端で折り返すという機能があります。この右端で折り返すなどの機能は CreateWindowEx API関数の dwStyle で設定します。例えば、右端で折り返すようなエディットボックスを作成するには次のようにします。

  hEditbox = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", vbNullString, _
         WS_OVERLAPPED Or WS_VSCROLL Or WS_CHILD Or WS_VISIBLE Or _
         ES_MULTILINE Or ES_LEFT Or ES_WANTRETURN Or ES_NOHIDESEL, _
         0&, 0&, Me.ScaleWidth, Me.ScaleHeight, Me.hwnd, 0&, App.hInstance, 0&)

  'マージン設定
  Call SendMessage(hEditbox, EM_SETMARGINS, EC_LEFTMARGIN Or EC_RIGHTMARGIN, ByVal 0&)

また、右端で折り返さないようにするには以下のようにします。

  hTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", vbNullString, _
         WS_OVERLAPPED Or ES_WANTRETURN Or WS_CHILD Or WS_VISIBLE Or _
         ES_NOHIDESEL Or ES_MULTILINE Or ES_LEFT Or WS_VSCROLL Or _
         WS_HSCROLL Or ES_AUTOHSCROLL Or ES_AUTOVSCROLL, _
         0&, 0&, Me.ScaleWidth, Me.ScaleHeight, Me.hwnd, 0&, App.hInstance, 0&)

各定数の値はこちらを見てください。ウインドウスタイルなどはここでは説明いたしません。それぞれ各自で調べて好みに合ったエディットボックスを作ってくださいね。ウインドウを作成したら、いつかは削除しなければいけません。VBの場合 Form_QueryUnloadイベント や Form_Unloadイベント で削除処理をすればよいわけです。当然、作成したウインドウハンドルは外部変数として保持しておく必要があります。削除する方法は、以下のAPI関数の引数に削除したいウインドウのハンドルを渡せばいいだけです。上の場合であれば、 hEditbox ですね。

 
  Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long

メモ帳のように、右端で折り返すか折り返さないかを設定できるようにするには、現在のエディットボックスのハンドルを解放し、再び作り直してあげればいいのです。実際、メモ帳もそうやっているはずです。Spy++ でエディットボックスのハンドルを見てみると、設定変更前と後とでは違っているのです。

その他ついでにいろいろ書いておきます。API、定数の値、意味は各自で調べてください。

固定幅フォントをエディットボックスに設定するなら、

  'フォントを設定する
  Call SendMessage(hEditbox, WM_SETFONT, GetStockObject(OEM_FIXED_FONT), ByVal 1&)

編集可能サイズを変更するなら、

  '編集可能サイズ(単位:バイト)を設定する、Win95では64KBまでだったと思います
  Call SendMessage(hEditbox, EM_LIMITTEXT, 設定するサイズ, ByVal 0&)

親ウインドウのサイズに合わせるなら、

Private Sub Form_Resize()

  'テキストボックスのサイズを調整
  Call MoveWindow(hEditbox, 0, 0, Me.ScaleWidth, Me.ScaleHeight, True)

End Sub

エディットボックスに背景色・文字色を設定するには、基本的に親フォームの BackColorプロパティ、ForeColorプロパティに依存するようなので両者を設定すればいいと思います。それがいやなら、サブクラス化して WM_CTLCOLOREDIT メッセージを拾う必要があります。下の処理は、背景色を黒、文字色を白に設定する処理です。hBrush はブラシのハンドルを格納する外部変数です。WM_CTLCOLOREDIT を拾ったら、ブラシを作成し、背景色・文字色を設定し、その後でブラシのハンドルを返すという処理をします。例によって、hBrushはいらなくなったら、DeleteObject API関数で削除する必要があります。Form_QueryUnloadイベント や Form_Unloadイベント でどうぞ。OldWindowhWnd はデフォルトのウインドウプロシージャで、サブクラス化の際、拾っておく必要があります。hWnd には親ウインドウのハンドルが送られるものとします。

Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

  Select Case uMsg
    Case WM_CTLCOLOREDIT

      If lParam = hEditbox Then
        If hBrush = 0 Then hBrush = CreateSolidBrush(vbBlack)

        'wParam にはエディットボックスのデバイスコンテキスト
        'のハンドルが送られてくる。
        Call SetTextColor(wParam, vbWhite)
        Call SetBkColor(wParam, vbBlack)

        WindowProc = hBrush
        Exit Function
      End If
    Case Else
      'それ以外の処理
  End Select

  WindowProc = CallWindowProc(OldWindowhWnd, hWnd, uMsg, wParam, lParam)

End Function

以上を持って「メモ帳を遠隔操作して遊ぼう」のトピックを終わりです。何かお役に立てたでしょうか。これから先は、今まで述べてきた各関数を駆使してよりよいものを作ってください。


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