(AutoHotkey)(POINT構造体 の 値を取得してみる 編)

 元々 AutoHotkeyには MouseGetPosがあるので マウスカーソルの位置を取得する術はあるわけですが
「あくまで シンプルな例を提示する」のが 今回の目的なので あえて API関数のGetCursorPosを使う事にします

 API関数のGetCursorPos は 呼び出すと POINT構造体に 値をセットする仕様なわけですが
AutoHotkeyには 構造体を定義する方法がありませんので
他の言語で 一般的に行われているような 構造体へのアクセスの仕方は 今のバージョン(v1.0.47.05)では 出来ません
早く実装されればいいんですけどねぇ 笑)、 みんなで せかしまくるんだ!! 笑)

 というワケなので 構造体のような 代替品を 用意してあげる必要があるわけなんですが
今回は 構造体のようなものを作るために AutoHotkey の VarSetCapacity関数を利用します
この関数は 固定長サイズの変数を作ったりするものです
具体的に説明すると 仕様は VarSetCapacity(<変数名>, <確保を希望するバイト数>, <変数を埋め尽くす値(0〜255)>)
戻り値は 実際に確保できた領域のサイズになります

 では 実際に POINT構造体のようなものを 作ってみるわけですが
まず POINT構造体 の構造を知る必要がありますね
いろんな所で 調べてみると POINT構造体の定義は 以下の感じですよね
[]typedef struct tagPOINT {[]
	[]LONG x;[]
	[]LONG y;[]
[]} POINT;[]
つまり POINT構造体とは 32ビット(4バイト)の x と y という 二つのメンバを持った 連続した 8バイトの変数という事になります
よって 8バイトのサイズの 変数を用意してあげれば なんとかなるわけです
さっきの VarSetCapacity関数を使って 表現してみると
	[]VarSetCapacity(bufPOINT, 8, 0x00)[]
これで 8バイト分の 0x00 で埋め尽くされた bufPOINT という 変数が用意された事になります

 今度は GetCursorPosの定義を見てみると
[]BOOL GetCursorPos([]
	[]LPPOINT lpPoint []
[]);[]
POINT構造体の アドレス を GetCursorPos に 渡してあげれば良さそうですね
戻り値 は BOOL型ですし 成功時 0以外 失敗時は 0 という 典型的なパターンでしょうね
ということで ここでの問題は 「どうやって アドレスを渡すのか?」ということですが
実は 変数のアドレスを渡すときは 変数名の前に & をつけてやるだけでOKです
	[]DllCall("user32.dll\GetCursorPos", "UInt", &bufPOINT)[]
これで ちゃんと bufPOINT に 座標が書き込まれたはずです

 とはいえ ちゃんと 書きこまれたにしても その値を利用できなければ 意味がありませんよね
そこで AutoHotkey で用意されている NumGet と NumPut という 関数を 利用する事にします
今回は 値を取得するわけなので NumGet関数を使います、 NumPut関数 については また後日にでも書きます

 NumGet関数は 変数 と オフセット値 と データ型 を 指示する事によって
指定した変数のアドレス+オフセット値 から始まるデータを 指示したデータ型で 読み取ります
ん〜ちょっと混乱しそうですね 笑)、 まぁ 使い方を見れば なんとなく分かるでしょう
	[]BufX := NumGet(bufPOINT, 0, "Int")[]
	[]BufY := NumGet(bufPOINT, 4, "Int")[]
	[]MsgBox, x:%bufX% y:%bufY%[]
まず bufPOINTのアドレス と xメンバ のアドレスは 同じなので オフセット値 は 0 です、 Int型で読み取らせます
つづいて yメンバ のアドレスは bufPOINTのアドレスよりも 4バイト後(xメンバのサイズ分)なので 4 になります

	[]; POINT構造体もどきを作成[]
	[]; MsgBoxで 実際に確保できたサイズを表示させます[]
	[]; 8バイトくらいなら 別に何の問題も無く 成功するでしょう[]
	[]MsgBox,% VarSetCapacity(bufPOINT, 8, 0x00)[]

	[]; API関数に POINT構造体もどきの 変数の アドレスを渡します[]
	[]DllCall("user32.dll\GetCursorPos", "UInt", &bufPOINT)[]

	[]; x メンバの値を bufX に 代入[]
	[]bufX := NumGet(bufPOINT, 0, "Int")[]
	[]; y メンバの値を bufY に 代入[]
	[]bufY := NumGet(bufPOINT, 4, "Int")[]

	[]; MsgBox で マウスカーソルの 座標を表示[]
	[]MsgBox, x:%bufX% y:%bufY%[]