プラグインの作成

HSP用プラグインは要するにDLLのなので作成方法そのものは通常のDLLとほとんど変わりません。

通常のDLLと違う点は、エクスポートテーブルへの登録がPROCディレクティブにEXPORTを指定するだけで良い点です。通常のDLLの様に定義ファイル(.DEF)を作成する必要がありません。これはHSPがGetProcAddressに渡すプラグインの関数名をSTDCALLの名前付け規約そのままで使用しているためです。

DLLのエントリポイント(実行開始地点)はDllMain(名前は変更可能)で、プロセスへのアタッチやデタッチ時に呼び出されます。つまり、ここで初期化処理や終了処理を行います。
DllMainの説明(MSDN Online)

プラグインの関数にはいくつかのタイプがあり、その内容はHSPからのDLL呼び出し方法リファレンスマニュアルに書かれています。関数に渡される引数は4つと固定されていて、その内容は選択したタイプによって決まります。HSPスクリプト側から渡せるパラメータは、タイプ$202以外は2〜4個で、その数と種類はタイプによって固定されています。タイプ$202ではスクリプト側から渡せるパラメータの数や種類に制限はありませんが、Ver2.6から新設されたタイプなので、それ以前のHSPではサポートされていません。

返値は通常0にしますが、システム変数statに値を返したい場合は負の数を返します。エラーを表示したい場合は1〜255の値を返すと、それに応じたエラーメッセージが表示されて終了します。他にも関数終了後にawait・waitを実行させることも出来ます。

サンプルとして、日付をタイトルとしたMessageBoxを表示する命令を、タイプ6と$202で作成します。


ファイル名:TestHpi.asm

;*********************************************************************
;タイトルに日付を持つMessageBoxを表示
;TestProc p1,p2
;TestProc2 p1,p2
;p1:メッセ−ジ
;p2:MessageBoxのタイプ
;*********************************************************************
        .386
        .model flat,stdcall
        option casemap:none

        include windows.inc
        include hspdll.inc

        include kernel32.inc
        include user32.inc
        includelib kernel32.lib
        includelib user32.lib
;*********************************************************************
.data
        fmt db "%04d年%02d月%02d日",0
.code
;*********************************************************************
DllMain PROC ,hInstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID
        mov eax,TRUE
        ret
DllMain ENDP
;*********************************************************************
TestProc PROC EXPORT,pBms:ptr BMSCR, pMsg:ptr CHAR ,uType ,tmp      ;type 6
        LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR

        invoke GetLocalTime,ADDR stime
        movzx eax,stime.wYear
        movzx ecx,stime.wMonth
        movzx edx,stime.wDay
        invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx
        mov ecx,pBms
        invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType
        neg eax
        ret
TestProc ENDP
;*********************************************************************
TestProc2 PROC EXPORT USES ebx ,pExinfo:ptr HSPEXINFO, tmp1,tmp2,tmp3   ;type$202
        LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR ,pMsg ,uType

        invoke GetLocalTime,ADDR stime
        movzx eax,stime.wYear
        movzx ecx,stime.wMonth
        movzx edx,stime.wDay
        invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx
        mov ebx,pExinfo
        ASSUME ebx:ptr HSPEXINFO
        invoke [ebx].HspFunc_prm_gets
        mov pMsg,eax
        invoke [ebx].HspFunc_prm_getdi,MB_OK
        mov uType,eax
        mov ecx,[ebx].er
        mov eax,[ecx]
        .if eax
                ret
        .endif
        mov eax,[ebx].actscr
        invoke [ebx].HspFunc_getbmscr,DWORD ptr [eax]
        mov ecx,eax     ;eaxはスタック変数のアドレス取得に使われる
        invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType
        neg eax
        ret
TestProc2 ENDP
;*********************************************************************

END DllMain

TestHpi.DLL作成用バッチファイル

@ECHO OFF
Ml /c /coff TestHpi.asm
if errorlevel 1 goto error
Link /SUBSYSTEM:WINDOWS /DLL  TestHpi.obj
if errorlevel 1 goto error
goto fin
:error
echo ===============================エラー======================================
:fin
echo ===============================終了=======================================

このプラグインを動作させるHSPスクリプト

#uselib "TestHpi.dll"
#func TestProc  TestProc        6
#func TestProc2 TestProc2       $202
#define MB_ICONERROR    $00000010
#define MB_ICONQUESTION $00000020

testproc "test1",MB_ICONERROR
testproc2 "test2",MB_ICONQUESTION

タイプ$202では必要な情報は全てHSPEXINFO構造体を通じて入手します。つまり何度もHSPEXINFO構造体にアクセスする必要があり、よけいな手間を省くためには、そのアドレスをebxなどの値が保存されるレジスタに格納しておき、ASSUMEディレクティブで型を指定しておきます。


戻る