hsgetmsg.dllのメッセージ取得機能を使った最初に紹介する拡張機能は、HSPウィンドウにドラッグ・アンド・ドロップされたファイルの取得であります。
ドラッグ・アンド・ドロップされたファイル名を取得する機能を使うには、基本的には以下のような操作を行ないます。
まずは、取得メッセージの設定からです。ファイルがウィンドウにドラッグ・アンド・ドロップされると、そのウィンドウには メッセージが送られます。
hDropパラメータ(wParamの値)は、ドロップファイル名を管理している内部データ構造体を操作するためのハンドルになります。このハンドルが何なのかはあとで説明します。
次に、ウィンドウがファイルがドロップされるファイルを受け取るのを許可する設定をします。ウィンドウにドロップ出来るようにするには、DragAcceptFiles関数を使います。
VOID DragAcceptFiles(
HWND hWnd, // ウィンドウハンドル
BOOL fAccept // 受け入れるかどうかのフラグ
);
この関数で、fAcceptパラメータに1を指定することで、ドラッグ・アンド・ドロップされるファイルの受け入れを許可します。
あとはメッセージが送られてくるのを待ちます。ドラッグアンドドロップされると、ウィンドウにメッセージが送られてきます。このメッセージの付加情報wParamパラメータはドロップされたファイルの名前を管理している内部データ構造体を操作するためのハンドルを示します。ファイル名を取得するにはこのハンドルが必要になります。
まずはドロップされたファイルの数を取得する必要があります。ファイル数を取得するにはDragQueryFile関数を使います。
UINT DragQueryFileA(
HDROP hDrop, // 内部データ構造体のハンドル
UINT iFile, // ファイルインデックス
PTSTR pszFile, // ファイル名を格納するバッファのアドレス
UINT cch // pszFile バッファのサイズ
);
ファイル数を取得する場合はこの関数のhDropパラメータに先ほどの内部構造体のハンドルを指定し、iFileパラメータに-1を指定します。こうすることで、関数の戻り値としてファイル数が返ります。
次にファイル名を取得します。ファイル名の取得は1つずつ行ないます。使用するAPI関数は、ファイル数取得のときと同様にDragQueryFile関数です。今度は、iFileパラメータにファイルのインデックスを、pszFileパラメータには、ファイル名を格納するための文字列変数のアドレスを指定しておきます。この文字列変数は出来れば260バイト以上のサイズを確保したものを指定しましょう。そして、cchパラメータにはそのサイズ(260)を指定します。ファイルのインデックスは0を基準としたものになります。したがって、1つ目のファイルを取得するならインデックスを0に、2つ目なら1に、……というようにして、これをドロップされたファイルの数だけ繰り返します。
必要なデータがすべて取得し終わったら、DragFinish関数を呼び出します。
VOID DragFinish(
HDROP hDrop // 内部データ構造体のハンドル
);
ファイルがドロップされると、システムは自動的にメモリを確保してドロップされたファイルの情報を保持しています。DragFinish関数は、このメモリ領域を解放するためのものです。
さて、実際にスクリプトを書いてみます。ウィンドウにファイルがドラッグ・アンド・ドロップされたらそのファイル名を表示するプログラムを作ります。
#include "llmod.as"
#include "hsgetmsg.as"
#define WM_DROPFILES 0x0233
; ウィンドウのサブクラス化
set_subclass : hwnd = stat ; ウィンドウハンドル(ID=0)
set_message WM_DROPFILES ; 取得メッセージを設定
; ドロップファイルの受け入れを設定
pm = hwnd, 1
dllproc "DragAcceptFiles", pm, 2, D_SHELL
if stat == 0 {
dialog "受け入れの設定に失敗しました。", 1, "エラー"
end
}
mes "このウィンドウにファイルをドロップして下さい。"
; メッセージパラメータ用変数
dup msg, msgval.1
dup wprm, msgval.2
dup lprm, msgval.3
*mainloop
get_message msgval
if msgval == hwnd {
; メッセージを受け取ったとき
if msg == WM_DROPFILES : gosub *OnDropFiles
} else {
wait 10
}
goto *mainloop
*OnDropFiles
; ファイルがドロップされたときの処理
hDrop = wprm ; データ構造体のハンドル
; ファイルの数の取得
pm = hDrop, -1, 0, 0 ; 第2パラメータを -1 に
dllproc "DragQueryFileA", pm, 4, D_SHELL
filenum = stat ; ドロップされたファイル数
sdim filename, 260 ; ファイル名を格納するバッファ
getptr p_filename, filename ; バッファのアドレス
repeat filenum ; ドロップされたファイルの数だけ実行
; ファイル名の取得
pm = hDrop, cnt, p_filename, 260
dllproc "DragQueryFileA", pm, 4, D_SHELL
mes filename ; ファイル名を表示
loop
; ドロップファイル用のメモリを解放
pm = hDrop
dllproc "DragFinish", pm, 1, D_SHELL
return