HSP ver2.6からは、loadlib.dllの命令が標準命令として統合され、Win32 APIを使用したプログラムを公開する際にloadlib.dllをともに配布する必要がなくなって、HSPにおけるAPI関数の使い勝手がさらによくなりましたよね。
しかし、HSP ver2.6では、それ以外もいろいろな拡張がなされています。その1つに、#define 命令のマクロ機能の強化があります。以前のバージョンでは、#define 命令は単純に定数の置き換えを行なう機能しかありませんでしたが、新しいHSPでは、引数付きの展開を行なうことができるようになったのです。これにより、 #deffunc 命令でモジュール命令を定義するのと同じように、新しい命令を#define 命令で定義することもできるようになりました。この新しい命令では、複雑な展開の仕方を指定することもできるので、非常に便利なものとなっています。
現在では、HSP ver2.6用に公開されているモジュールなどには、新しいマクロ機能を使用したものが数多く存在します。そのうち、Win32 API関数の呼び出しのための機能を提供しているHSP ver2.61用マクロに、blueleafさんによって公開されている WA_MACRO があります。
WA_MACROは、これまでllmodモジュールによって実現できた機能を提供しており、さらに、Windowsの主要なシステムDLLが提供するAPI関数をマクロにより網羅しています。WA_MACROの優れている点は、llmodモジュールを使用する場合のような面倒な手続きが必要なく、API関数名と引数を指定するだけで関数の呼び出しができてしまうというところにあります。
では、API関数呼び出しがどれほど簡単になるかを見てみることにしましょう。例として、MessageBox 関数によるメッセージボックスの表示を行なってみるとします。まず、llmodモジュールを使用する場合には、次のようになりますね。
#include "llmod.as" mref bmscr, 67 ; ウィンドウのBMSCR構造体を変数 bmscr に割り当てる text1 = "LLMODを使ってます" text2 = "API呼び出しテスト" ; MessageBox 関数の呼び出し pm.0 = bmscr.13 ; ウィンドウハンドル getptr pm.1, text1 ; 表示文字列へのポインタ getptr pm.2, text2 ; キャプション文字列へのポインタ pm.3 = 0x30 ; MB_OK | MB_ICONEXCLAMATION dllproc "MessageBoxA", pm, 4, D_USER end
一方、WA_MACRO を用いた場合には、次のように書くことができます。
#include "wam/user32.as"
; MessageBox 関数の呼び出し
MessageBox PRMHWND, SPTR("WA_MACROを使ってます"), SPTR("API呼び出しテスト"), 0x30
end
関数呼び出し部分が、たったの1行になってしまいました。llmodモジュールを使用した場合と比べると格段に簡単になってしまうことが分かりますね。
では、WA_MACROを使用する方法を説明していくことにしましょう。最新のWA_MACROバージョン1.04はHSP 2.61が必須です。
WA_MACROはblueleafさんのホームページにて公開されていますので、そこからダウンロードしましょう。現在の正式版の最新バージョンは1.04となっています。
WA_MACROのバージョン1.04をダウンロードしたら、ダウンロードしたアーカイブに含まれているwamフォルダを、HSPのcommonフォルダにコピーします(wamフォルダ内のファイルを個別にコピーするのではなく、wamフォルダそのものをcommonフォルダの中に入れてしまいましょう)。また、アーカイブ内にデバッグ実行時用のDLLが含まれているので、これをHSPがインストールされているフォルダにコピーします。他にも、helpフォルダの中にはマクロのヘルプが、omakeフォルダの中にはWin32 APIを使う上での便利なツールが含まれています。これらも、HSPがインストールされているフォルダの適当な場所にコピーしておきましょう。
WA_MACROでは、任意のDLLに含まれる任意の関数を呼び出したり、その関数を新しくマクロ定義したりすることができますが、とりあえずは、すでに提供されているシステムDLL関数用のマクロを使用していくことにしましょう。
WA_MACROでは、以下のファイルをインクルードすることで、それぞれのDLLが持っている関数を呼び出すことができるようになります。それぞれのファイル名の前に「wam/」をつける必要があることに注意してください。
winapi.as をインクルードすると、上のすべてのファイルで定義されるマクロをまとめて定義することできるようになっています。
さらに、以下のファイルも使うことができます。
もう一度言いますが、これらのファイル名の前には「wam/」を付けて指定しなければいけません。例えば、「wam/kernel32.as」や「wam/winapi.as」などのように指定します。
では、実際にWM_MACROを使ってみることにしましょう。まずは、先ほどの MessageBox 関数の場合を例にとって説明していきます。
まず、マクロファイルのインクルードをする必要があります。MessageBox 関数はuser32.dll に含まれる関数であるので、「user32.as」をインクルードする必要があります(「winapi.as」でもいいですが)。「wam/user32.as」(または「wam/winapi.as」)と指定しなければいけません。
#include "wam/user32.as"
あとは、関数名を引数付きで記述すればOKです。
MessageBox PRMHWND, SPTR("WA_MACROを使ってます"), SPTR("API呼び出しテスト"), 0x30
「MessageBox」と書けば、MessageBox 関数が呼び出されるようになっているわけです。非常に簡単ですね。文字列が関係するこの関数にはANSI文字列版の MessageBoxA とUnicode版の MessageBoxW がありますが、上のスクリプトのように最後の「A」を付けない形で指定すると MessageBoxA の方が呼び出されるようになっています。もちろん、
MessageBoxA PRMHWND, SPTR("WA_MACROを使ってます"), SPTR("API呼び出しテスト"), 0x30
のように明示的に「A」を付けた形で指定することも可能です。
さらに、それぞれのパラメータについて見ていくと、まず最初が「PRMHWND」となっていますね。これは関数呼び出し時のパラメータ用に定義されているマクロの1つで、描画中のウィンドウのウィンドウハンドルを渡すことができます。他にも、描画中のウィンドウとは別のウィンドウ、例えば、ウィンドウID2のウィンドウのハンドルを渡したい場合には、「PRMHWNDN(2)」と指定することができます。
次に、第2・3パラメータには、表示される文字列へのポインタ(アドレス)を渡さなければいけませんね。文字列へのポインタを渡すには、「SPTR」マクロを使って文字列を直接指定し、「SPTR("文字列")」のように記述します。ただし、SPTR マクロで使用できる文字列は255バイト分まで(バージョン1.04では4095バイト分まで)という制限があるので、注意が必要です。
SPTRとは別に、変数へのポインタを渡すマクロ「PTR」もあります。そこで、サイズの大きい文字列を渡したい場合には、いったん文字列を変数に格納した後で、その変数をPTRマクロで渡すようにすればいいでしょう。上のスクリプトは、次のように書くこともできます。
text1 = "WA_MACROを使ってます" text2 = "API呼び出しテスト" MessageBox PRMHWND, PTR(text1), PTR(text2), 0x30
関数呼び出し時のパラメータ用に、上で示した「SPTR」などの他にもいくつかのマクロが定義されています。以下に、それらをまとめておきます。
マクロ | 意味 |
---|---|
PTR(v1) | 変数 v1 へのポインタ |
SPTR(s1) | 文字列 s1 へのポインタ(最大4Kバイト) |
WSPTR(s1) | 文字列 s1 のUnicode文字列へのポインタ(最大4Kバイト;2047文字) |
PRMHINST | アプリケーションのインスタンスハンドル |
PRMHWND | 描画中ウィンドウのハンドル |
PRMHWNDN(n1) | ウィンドウID n1 のウィンドウのハンドル |
PRMHDC | 描画中ウィンドウの画面バッファのデバイスコンテキストのハンドル |
PRMHDCN(n1) | ウィンドウID n1 のウィンドウの画面バッファのデバイスコンテキストのハンドル |
PRMHOBJ(n1) | 描画中ウィンドウ上にあるHSPオブジェクトID n1 のウィンドウハンドル |
HSPではマクロ名を含めて大文字・小文字の区別はされませんから、小文字で「ptr(v)」などとすることが可能です。
以上のマクロは、関数呼び出し時のパラメータ指定に対してしようすることができます。逆に、別の目的(変数への代入など)には使用することができません。例えば、
p = PTR(v) ; これは間違い hwnd = PRMHWND ; これは間違い
などとすることはできないのです。
戻り値はマクロ名「DLLRET」で定義されています。これはllmodモジュールにおける戻り値用の変数 dllret と互換性を持たせるためにこのような形になっています(WA_MACROはllmodモジュールと同時に使用することができるようになっています)。この戻り値マクロはグローバル定義されており、モジュール領域の中からでもアットマーク「@」をつけることなく「DLLRET」(または「dllret」)だけの形で参照できるようになっています。
例えば、 CreateEllipticRgn 関数を使用して、円形のリージョンオブジェクトを作成する場合には以下のようにします(あらかじめgdi32.asをインクルードしておく必要があります)。
; 円形のリージョンオブジェクトを作成する CreateEllipticRgn 0, 0, 300, 300 hRgn = dllret ; リージョンのハンドル
戻り値の取得に関しては、llmodモジュールと同じですね。ただ、 dllproc 命令の場合にはシステム変数 stat にも戻り値が格納されていましたが、WA_MACROの場合には stat への格納はされないので注意しましょう。
上述のパラメータ用マクロで取得できる値(例えば「PTR(v)」など)を変数での代入のために使用することはできませんでした。これを行なうために、別のマクロが定義されています。
マクロ | 意味 |
---|---|
GetAddr v1, v2 | 変数 v1 へのポインタを v1 に格納 |
GetHinst v1 | アプリケーションのインスタンスハンドルを v1 に格納 |
GetHwnd v1 | 描画中ウィンドウのハンドルを v1 に格納 |
GetHwndN v1, n2 | ウィンドウID n2 のウィンドウのハンドルを v1 に格納 |
GetHdc v1 | 描画中ウィンドウの画面バッファのデバイスコンテキストのハンドルを v1 に格納 |
GetHdcN v1, n2 | ウィンドウID n2 の画面バッファのデバイスコンテキストのハンドルを v1 に格納 |
GetHobj v1, n2 | 描画中ウィンドウ上にあるHSPオブジェクトID n2 のウィンドウハンドルを v1 に格納 |
GetHobjN v1, n2, n3 | ウィンドウID n3 上にあるHSPオブジェクトID n2 のウィンドウハンドルを v1 に格納 |
例えば、GetAddr は getptr 命令とまったく同じ働きがあることが分かりますよね。つまり、関数のパラメータ以外に変数のアドレスを取得する必要がある場合には、これを使用すればいいのです。
これら以外にも、様々なマクロが定義されています。まず、以下の関数型マクロが定義されています。
マクロ | 意味 |
---|---|
LOWORD(n1 ) | n1 の下位16ビット値(符号なし) |
HIWORD(n1 ) | n1 の上位16ビット値(符号なし) |
LOSWORD(n1 ) | n1 の下位16ビット値(符号付き) |
HISWORD(n1 ) | n1 の上位16ビット値(符号付き) |
LOBYTE(n1 ) | 16ビット値 n1 の下位8ビット値(符号なし) |
HIBYTE(n1 ) | 16ビット値 n1 の上位8ビット値(符号なし) |
LOSBYTE(n1 ) | 16ビット値 n1 の下位8ビット値(符号付き) |
HISBYTE(n1 ) | 16ビット値 n1 の上位8ビット値(符号付き) |
MAKELONG(n1, n2 ) | 下位16bitが n1,上位16bitが n2 の値 |
RGB(nRed, nGreen, nBlue ) | 指定した色のRGB値 |
GetRValue(nColor) | RGB値 nColor から赤の値を取得 |
GetGValue(nColor) | RGB値 nColor から緑の値を取得 |
GetBValue(nColor) | RGB値 nColor から青の値を取得 |
例として、GetSysColor 関数を使ってシステムカラー(ここでは、3Dオブジェクトの表面色)を取得するスクリプトは以下のようになります。
#include "wam/user32.as" GetSysColor 15 ; COLOR_3DFACE r = GetRValue(dllret) ; 赤の値 g = GetGValue(dllret) ; 緑の値 b = GetBValue(dllret) ; 青の値 mes "赤:"+r+" 緑:"+g+" 青:"+b stop
また、Win32 APIではよく使われる以下の定数マクロが定義されています。
マクロ | 値 | 意味 |
---|---|---|
NULL | 0 | ヌルポインタまたはヌルハンドル |
FALSE | 0 | 真偽値のうち偽を示す値 |
TRUE | 1 | 真偽値のうち真を示す値(通常はTRUEかどうかで判断するのではなく、FALSEであるかないかで判断すべき) |
MAX_PATH | 260 | ファイルパス・ファイル名を格納する文字列変数の確保するべきサイズ |
これらのマクロは、他の人が公開しているモジュールの中でも同じように定義されている場合があり、そのようなモジュールとWA_MACROを同時に使用すると、マクロ多重定義によるエラーが発生することがあるので注意してください。
WA_MACROではシステムDLLが提供する関数をマクロ定義していますが、いくつかの関数ではHSPの命令と名前の衝突を起こしてしまっているので、次のような措置がとられています。
これらの関数を使用する場合には注意しましょう。