連載:VB 6ユーザーのための
これならマスターできるVB 2005超入門

第12回 VB 2005でWin32 APIを利用する

羽山 博
2007/10/26
Page1 Page2 Page3 Page4

■マウスをキャプチャするまでのコードを書く

 では、イベント・ハンドラを見ていこう。[サイズ変更]ボタンをクリックしたら、マウスをキャプチャし、フォームでマウス・イベントを受け取れるようにする。ここではまだWin32 APIを使う必要はない。

 コードのほとんどは、テキストボックスに入力された値が数値であるか、画面のサイズからはみ出していないかをチェックするためのもので、マウスをキャプチャするために必要なコードは、 の「Me.Capture = True」だけである。

Private Sub StartResize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnResize.Click

  Dim iLeft, iTop, iMaxWidth, iMaxHeight As Integer

  iLeft = SystemInformation.VirtualScreen.Left
  iTop = SystemInformation.VirtualScreen.Top
  iMaxWidth = SystemInformation.VirtualScreen.Width
  iMaxHeight = SystemInformation.VirtualScreen.Height

  ' テキストボックスの内容を数値に変換する
  If Not Integer.TryParse(txtWidth.Text, iWidth) OrElse _
      (iWidth < iLeft Or iWidth > iMaxWidth) Then
    MessageBox.Show("正しい幅を入力してください")
    txtWidth.Focus()
    Exit Sub
  End If

  If Not Integer.TryParse(txtHeight.Text, iHeight) OrElse _
      (iHeight < iTop Or iHeight > iMaxHeight) Then
    MessageBox.Show("正しい高さを入力してください")
    txtHeight.Focus()
    Exit Sub
  End If

  ' マウスをキャプチャする
  Me.Capture = True
End Sub
正しい数値が入力されているかどうかを調べ、マウスをキャプチャする
  SystemInformationクラスのVirtualScreenプロパティを利用すれば、仮想スクリーンの範囲(Rectangle構造体の値)が得られる。ここでは仮想スクリーンの左端の位置を取得している。 でも同様にして、上端の位置、幅、高さを求めている。
  幅を入力するためのテキストボックスに正しく数値が入力されているかどうかをTryParseメソッドで調べ、さらに、左端の位置よりも小さな値、あるいは幅よりも大きな値が指定されていないかを調べる。
  正しい値が入力されていなければ、エラー・メッセージを表示する。
  テキストボックスに入力フォーカスを移す。高さについても同様の処理を行う。
  CaptureプロパティをTrueに設定し、マウスをキャプチャする。これでフォームの外でマウス・ボタンが押されても、フォームのMouseDownイベント・ハンドラで処理できるようになる。

 このコードで注意すべき点は1つだけ。VB 6までは入力フォーカスを移動するのにSetFocusというメソッドを使っていたが、VB 2005ではFocusメソッドを使うといったあたりだろう。なお、マルチ・モニタを利用している場合、プライマリ・モニタの左上が仮想スクリーンの原点となる。

■ウィンドウのサイズを変更するコードを書く

 次はフォームのMouseDownイベント・ハンドラを見てみよう。最も重要な処理はウィンドウのサイズを変更するということ。もちろん、自分のウィンドウではなく、マウスの位置にあるウィンドウのサイズを変更しなければならない。

 その考え方はすでに説明したとおりで、マウスの位置からウィンドウ・ハンドルを取得し、その親ウィンドウを順に探していき、デスクトップを直接の親に持つウィンドウか親のないウィンドウまでたどりついたら、それをプログラムのフレーム・ウィンドウと見なし、そのサイズを変更すればよい。

 では、コードを見てみよう。

Private Sub ResizeWindow(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown

  Dim hWndTarget As Integer

  ' マウスの位置からウィンドウ・ハンドルを取得する
  hWndTarget = WindowFromPoint( _
                    Cursor.Position.X, Cursor.Position.Y)

  ' フレーム・ウィンドウのハンドルを取得する
  hWndTarget = GetFrameWindow(hWndTarget)

  ' フレーム・ウィンドウのサイズを変える
  SetWindowPos(hWndTarget, 0, 0, 0, iWidth, iHeight, SWP_NOMOVE)

  ' マウスのキャプチャを解放する
  Me.Capture = False
End Sub
ウィンドウのサイズを変更する
  WindowFromPoint APIを利用して、マウスの位置にあるウィンドウのハンドルを得る。
  GetFrameWindow関数を呼び出し、フレーム・ウィンドウのハンドルを得る。この関数は、Win32 APIではなく、別に記述したFunctionプロシージャである。詳細は後述。
  SetWindowPos APIを利用して、ウィンドウのサイズを変える。
  フォームのCaptureプロパティをFalseに設定し、マウスのキャプチャを解放する。

 まず、マウスの位置を知る方法だが、これには2通りの方法がある。1つは、イベント・ハンドラに渡されてくるeという引数のXプロパティとYプロパティを使う方法。しかし、これらの値は、フォームの左上を原点とする値なので、このプログラムでは使えない(座標系の変換が必要)。

 もう1つは、CursorクラスのPositionプロパティ(POINT構造体)を使う方法。こちらは画面の左上を原点とする値なので好都合だ。 では、WindowFromPoint APIの引数にそれらの値を指定し、マウスの位置にあるウィンドウのハンドルを取得している。

 親ウィンドウを順に探していく処理については、Functionプロシージャにまとめてある。従って、ここではその詳細な処理が分からなくても、 でプログラムのフレーム・ウィンドウのハンドルが取得できると考えればよい。

  では、SetWindowPos APIを使ってウィンドウのサイズを変えている。このAPIはウィンドウの位置やサイズ、重なり方の順序を変えることもできるのだが、今回のサンプル・プログラムではサイズを変更するだけでよいので、順序や位置については0を指定し、最後の引数に「SWP_NOMOVE」を指定して、位置を変えないことを指示している。

 SWP_NOMOVEの実際の値は2である(コードの最初の方に、フォーム・レベルの定数として宣言してある)。なお、Win32API.txtには、このような定数の値も定義されている。


 INDEX
  VB 6ユーザーのためのこれならマスターできるVB 2005超入門
  第12回 VB 2005でWin32 APIを利用する
    1.サンプル・プログラム18 − ウィンドウのサイズを変更するプログラム
    2.プログラムの考え方とWin32 APIの宣言
  3.マウスのャプチャとウィンドウのリサイズ
    4.フレーム・ウィンドウのハンドル取得
 
インデックス・ページヘ  「これならマスターできるVB 2005超入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH