VBAで指定したウィンドウを操作(閉じる/最大化/最小化)する【SendMessage関数(API)】

VBAでマクロを作っている時に「指定したウィンドウを操作したいな」という場面に出くわすことはないでしょうか?ここでいう操作とはたとえば、指定したエクスプローラーのウィンドウを開くだけではなく最大化して表示したり指定したウィンドウをまとめて閉じたりというような操作です。

という訳で今回はWindows APIを利用して指定したウィンドウを操作する方法を解説していきます。
ここではウィンドウの操作としてウィンドウを「閉じる」「最大化にする」「最小化にする」の3つの操作を紹介していきます。今回学ぶことのできる内容は以下のとおりです。

 Windows APIについて
SendMessage関数の使い方
FindWindow関数の使い方
 上記の関数でウィンドウを操作(閉じる/最大化/最小化)する方法

 

SendMessage関数とは

VBAで指定のウィンドウを操作するにはWindows APIのSendMessage関数を使います。ただ、SendMessage関数を使用するには操作対象となるウィンドウ”そのもの”を取得する必要があります。

ウィンドウを取得する方法はいくつかありますが、ここではその代表格のFindWindow関数を使ってウィンドウを取得します。(FindWindow関数もWindows APIの関数)

・SendMessage関数 :指定したウィンドウにメッセージを送信する
・FindWindow関数 
:指定したクラス名/ウィンドウ名を持つウィンドウのハンドルを返す

ウィンドウのハンドルとは各ウィンドウをそれぞれ個別に識別するための値です。
このハンドルを引数としてSendMessage関数を使うことで任意のウィンドウに対して指定の操作を行うことが可能になります。

ちなみにウィンドウハンドル取得するWindows APIの関数はFindWindow関数以外にもいくつか用意されています。(参考:VBAでウィンドウ名(キャプション)をまとめて取得する方法)

SendMessage関数はその名前からもわかる通り、コンピュータに対して”メッセージ”を送信することのできる関数です。ただ、このメッセージはいわゆる文字列のメッセージではなく”信号”です。イメージとしては「ウィンドウの閉じるボタンが押されたよ」というような信号を送信すれば、コンピュータがその処理(ウィンドウを閉じること)を実行してくれるといった具合です。

本ページではウィンドウを「閉じる」「最大化する」「最小化する」の操作をするためのメッセージしか出てきませんが、用意されているメッセージとしては非常に多くの数があり操作できる内容も膨大です。本ページ以外のメッセージについては「ウィンドウメッセージリスト」ページを参照下さい。
   

  Windows APIとは 

これらの関数はWindows APIで用意されているものでVBAとは別のものです。Windows APIとは簡単にいえばWindowsに用意されている機能がまとまっているセットのようなものです。

Windows APIには上記の関数以外にも様々な関数があり、VBA上でそれらを呼び出すことで、Windowsに用意されている様々な機能を使用することができます。(たとえばマウスを操作したり、指定した秒数だけ処理を止めることができます)

ちなみに名前からわかると思いますが、Windows APIではWindowsの機能を呼び出しているだけので基本的にはWindows以外のOSでは使用することはできません

 

ウィンドウ名取得用の各関数の使い方

各関数を使うにははじめに「Windows APIの関数を使うよ」と宣言する必要があります。
※宣言をしないと各関数は使えずエラーになるので書き忘れに注意しましょう。

使用しているWindowsが32bitか64bitかによって宣言時に書く内容が変わってきます。
以下のどちらかをコードの一番初め(Option Explicitの次の行あたり)に書いておくことで、そのモジュール内で各関数を使うことができるようになります。

 icon-code 64bit 

 ‘【SendMessage関数】
Declare PtrSafe Function SendMessage Lib “user32” Alias “SendMessageA” (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
‘【FindWindow関数】
Declare PtrSafe Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

 icon-code 32bit 

 ‘【SendMessage関数】
Declare Function SendMessage Lib “user32” Alias “SendMessageA” (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
‘【FindWindow関数】
Declare Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

※操作環境のbitと構文があっていないとエラーになるので注意しましょう。
 
上記のどちらを書けばいいかわからない場合は以下のコードをコピペして、モジュールの最上部(Option Explicitの次あたり)に書いておきましょう。

また、これら2つの関数は「ウィンドウハンドル(hwnd)」というものを引数で使用します。この「hwnd」は64bitと32bitで型が変わってしまうため、上記ではそれぞれに合わせた変数を宣言しています。(64bit:LongPtr型、32bit:Long型)
 

SendMessage関数の構文

SendMessage関数は1つまたは複数のウィンドウへ、指定されたメッセージを送信することのできる関数です。SendMessage関数を使うには以下のような構文を書きます。

icon-code SendMessage関数 

res = SendMessage(Msg, wParam, lParam)

第一引数「Msg」は送信するメッセージを入力します。
第二引数「wParam」は「Msg」の追加情報となるパラメータを設定します。
第三引数「lParam」は「wParam」のさらなる追加情報となるパラメータを設定します。
この「lParam」は「wParam」の種類によって存在するものと、存在しないものがあります。
存在しないパラメータの場合、「lParam」には「0」を入力します。

ウィンドウを操作するには「Msg」に下記の定数を入力します。

定数 内容
WM_SYSCOMMAND &H112& システムメニュー(コントロールメニュー)のメッセージ

 
ウィンドウの最小化、最大化、閉じるの操作は「wParam」に下記の定数を入力します。
下記の3つの定数は「lParam」が存在しないため、第三引数には「0」を渡します。

定数 内容
SC_MINIMIZE &HF020& ウィンドウを最小化する
SC_MAXIMIZE &HF030& ウィンドウを最大化する
SC_CLOSE &HF060& ウィンドウを閉じる

ここではウィンドウの操作に絞ったメッセージだけを抜粋していますが、このSendMessage関数はその他にも多くのメッセージとパラメータが存在しており、様々案操作をすることができます。その他メッセージについては下記ページを参照下さい。

 

FindWindow関数の構文

指定したウィンドウのハンドルを取得するためのFindWindow関数の構文は以下のように書きます。

icon-code FindWindow関数 

hwnd = FindWindow(lpClassName, lpWindowName)

第一引数「lpClassName」にはクラス名
第二引数「lpWindowName」にはウィンドウ名をそれぞれ入力します。
これにより入力したクラス名/ウィンドウ名をもつウィンドウのハンドルを取得することができます。
lpClassName / lpWindowName はどちらかを指定すればハンドルの取得が可能です。
指定しない場合側の引数には空の文字列(vbNullString)を入力します。

 

ウィンドウ操作サンプルコード

これまでの内容をまとめてVBAマクロとして使用する場合は以下のように書きます。
以下のコードを実行すると、現在開いている「コマンドプロンプト」ウィンドウを取得して閉じることができます。

 

まとめ

今回はWindows APIを使ってウィンドウ名を取得する方法についてでした。
指定したウィンドウを最前面に表示することができる関数もあるので、そういった関数と今回の内容を組み合わせることでExcelやAccessのようなアプリケーションの領域外の操作をすることも可能になります。

Windows APIは今回のもの以外にも多くのものがあるため、知識として頭に入れておくだけでもマクロで作成できる幅が増えます。興味がある方はぜひ他のWindows APIの関数も調べてみてください。 

icon-book VBAでその他のWindows APIを呼び出そう

Excel, VBA, Windows API

Posted by Lic