【VBA×WindowsAPI】GetWindowLongPtr関数の使い方

GetWindowLongPtr関数

GetWindowLongPtr関数は指定したウィンドウに関する情報を取得するための関数です。
WinAPIにはGetWindowLong関数という同じ機能を持つ関数が存在しますが、GetWindowLongPtr関数はこのGetWindowLong関数を64bit/32bitの両環境で使えるようにしたものです。

ウィンドウに関する情報として、指定のウィンドウのウィンドウスタイル拡張ウィンドウスタイル、関連付いたウィンドウのハンドルなどを取得することができます。

ウィンドウスタイルとはウィンドウの見た目や動作の基本的なスタイルのことで、例えばウィンドウの枠線やタイトルバー、最大化/最小化ボタンの有無などがこれにあたります。拡張ウィンドウスタイルとはさらに応用的なウィンドウスタイルのことで、ドラッグ&ドロップ操作の機能やウィンドウの右側スクロールバー(ブラウザのような)の有無などがこれにあたります。

ウィンドウは起動時に各アプリケーションで指定されたウィンドウスタイルを持って起動されます。VBAのUserFormのデフォルト時のウィンドウスタイルと拡張ウィンドウスタイルは下画像の通りです。たとえば「WS_CAPTION」はタイトルバーが有ることを表し、「WS_EX_LEFT」は左揃えのプロパティを持っていることを表します。(詳しくは上記ウィンドウスタイルのリンクを参照)

GetWindowLongPtr関数とは対の存在となるSetWindowLongPtr関数を使うことで、このウィンドウスタイル/拡張ウィンドウスタイルを追加したり除去したりすることができます。このとき、現状のウィンドウスタイルはそのままで新たに追加したいという場合に、現状のウィンドウスタイルを取得する必要があります。このときに利用されるのがGetWindowLongPtr関数です。

ウィンドウスタイル以外にもいくつか取得できる情報がありますが、VBAで利用する際はUserFormのウィンドウスタイル/拡張ウィンドウスタイルを操作して本来のUserFormではできないことを可能にすることに利用したりします。(UserFormの透明化、ウィンドウ最大化/最小化ボタンの追加など)

使用方法

GetWindowLongPtr関数を使用するにはあらかじめ関数の宣言しておく必要があります。
※宣言をしないと関数は使えずにエラーとなるので書き忘れに注意しましょう。

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

 icon-code  64bit  

Declare PtrSafe Function GetWindowLongPtr Lib “user32” Alias “GetWindowLongPtrA” _
(ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr

icon-code  32bit  

Declare Function GetWindowLongPtr Lib “user32” Alias “GetWindowLongPtrA” _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long

上記のどちらを書けばいいかわからない場合は以下のコードをコピペして、モジュールの最上部に書いておきましょう。この構文を書いておくことで自動的に使うことのできる方の構文が使用されます。
VBE上では使えない方の構文が赤色で表示される場合がありますが、実行に影響はありません。

 
各関数の宣言文は「Private/Public」を付けて各関数の有効範囲を指定することもできます。

Private Declare PtrSafe Function~ :モジュール内でのみ呼び出し有効
Public Declare PtrSafe Function~ :モジュール外で呼び出し有効

 

構文

GetWindowLongPtr関数の構文は下記のように書きます。

icon-code GetWindowLongPtr関数 

lRet = GetWindowLongPtr(hWnd, nIndex)

引数

 hWnd    (64bit:LongPtr型 / 32bit:Long型) 

情報を取得する対象のウィンドウへのハンドルを入力します。
ウィンドウハンドルを取得するための関数としてFindWindow関数FindWindowEx関数GetActiveWindow関数など様々なものがあります。環境によって引数の型が変わるので注意が必要です。
 

 nIndex    (Long型) 

取得したい情報のインデックスの定数値を入力します。
定数値はいくつか存在しますが、代表的なものを抜粋すると下表のような値があります。

意味
GWL_STYLE = -16 ウィンドウスタイルを取得する
GWL_EXSTYLE = -20 拡張ウィンドウスタイルを取得する
GWLP_HWNDPARENT = -8 親ウィンドウのハンドルがある場合はそのハンドルを取得する

上記以外の定数値はGetWindowLongPtr関数(パラメータ)ページを参照下さい
 

戻り値

 lRet    (64bit:LongPtr型 / 32bit:Long型) 

戻り値は引数で指定したインデックスの情報です。
関数が失敗した場合は「0」が返されます。
ウィンドウハンドルと同様に環境によって戻り値の型が変わるので注意が必要です。

サンプルコード

以下はGetWindowLongPtr関数FindWindow関数SetWindowLongPtr関数を使って、UserFormに最大化ボタンと最小化ボタンを付与するサンプルコードです。UserFormを1つ作成し下記コードをコピーペーストしてUserFormを表示させることで、フォームのInitializeイベントが走り表示されるUserFormに最大化ボタンと最小化ボタンを付与することができます。

 

 icon-share-square  VBA×WindowsAPIまとめページ

その他のWindowsAPI関数は下記ページにまとまっているので合わせて参照下さい。

 icon-share-square  参考

Microsoft公式:GetWindowLongW 関数 (winuser.h) – Win32 apps

2023年12月10日Excel, VBA, Windows API

Posted by Lic