[トップ][一覧][最近の更新]

編集履歴:差分

記録開始以来のモーダルダイアログを実装の変更箇所

  • + 追加された行
  • - 削除された行

編集履歴ページに戻る

- DialogBoxIndirectParamを使ってモーダルダイアログを実装してみる。
- 
- [[$$toc]]
- - →[[HSP3・サンプルスクリプト]]に戻る
- 
- ----
- 
- HSP 3.1β2で動作確認~%
- 
- ダイアログを実装するには、ダイアログテンプレートというリソースが必要なんですね。~%
- 実は、HSPからでもC言語で使うRESファイル(リソースコンパイラでコンパイルした物)は、使えるのです。~%
- (多少加工しますが。)~%
- 
- なるべく簡単に、できるだけ応用が利くようにするために、色々用意するものがあります。~%
- 
- まず、コールバックを使うので ちょくとさんの'''hscallbk.dll'''を用意します。~%
- 
- hscallbk10.zip 5.4KB ~%
- http://yokohama.cool.ne.jp/chokuto/download/ ~%
- 
- 解凍後、hscallbkの説明書にしたがって各ファイルをそれぞれコピーします。
- 
- 次に、リソースコンパイラを何とか入手しましょう。(*note-1)~%
- '''RC.EXE''' と '''RCDLL.DLL'''~%
- 以下のもの(無償)をインストールしてあれば、ついています。~%
- Microsoft Platform SDK~%
- Visual C++ 2005 Express Edition~%
- MASM32(ダウンロードサイズが小さいくおすすめ。ファイルを取り出した後ばっさり削除しても問題なし。)~%
- 
- また、'''RC.EXE''' と '''RCDLL.DLL'''だけ入手したい場合グーグルで、検索するといくらでも入手できます。~%
- 
- では、早速やって見ましょう。
- まず、適当にフォルダをひとつ作ります。仮に'''test'''と名前を付けます。~%
- そこへ先ほど入手した'''RC.EXE''' と '''RCDLL.DLL'''をコピーしておきます。
- 
- 次に、C言語でおなじみのリソースを書いてみましょう。
- ダイアログだけを作りたいので下記のようにしてみます。(*note-2)
- {{{
- ////////////////////////////////////////
- //使う定数を書いておく。
- #define WS_POPUP        0x80000000// $80000000ではエラーになる
- #define DS_MODALFRAME   0x00000080//  
- #define WS_CAPTION      0x00C00000
- #define WS_SYSMENU      0x00080000
- #define IDOK            0x00000001
- #define WS_GROUP        0x00020000
- #define IDCANCEL        0x00000002
- #define ES_AUTOHSCROLL  0x00000080
- 
- #define IDD_ABOUTBOX    100 //
- #define IDI_HSP         128 //HSPアイコンのID
- #define IDC_MYICON        2 //
- #define IDC_STATIC       -1 //
- 
- ////////////////////////////////////////
- //
- // よくあるダイアログのテンプレート
- //
- IDD_ABOUTBOX DIALOG   22, 17, 230, 75
- STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
- CAPTION "バージョン情報"
- FONT 9, "MS UI Gothic"
- BEGIN
-     ICON            IDI_HSP,IDC_MYICON,14,9,16,16
-     LTEXT           "test Version 1.0",IDC_STATIC,49,10,119,8
-     LTEXT           "Copyright (C) 2006",IDC_STATIC,49,20,119,8
-     DEFPUSHBUTTON   "OK",IDOK,195,6,30,11,WS_GROUP
- END
- 
- }}}
- これをコピーし'''test.rc'''として、先ほどのフォルダへ保存してください。
- 
- 次に、リソースコンパイラで '''test.rc''' をコンパイルしつつ、HSP用に加工します。~%
- 下記のソースをコピーし、同じフォルダへ保存して実行してください。
- {{{
- 
- mes "開始"
- 
- exec "rc.exe test.rc",2
- ;exec "cmd.exe /k rc.exe test.rc"
- wait 50
- exist "test.RES" : size=strsize
- 
- if size=-1{dialog "失敗":end}
- 
- wait 10
- 
- sdim digtmpl,size-64
- bload "test.RES",digtmpl,size-64,64
- 
- wait 10
- 
- bsave "_digtmpl.dat",digtmpl,size-64
- 
- wait 10
- 
- mes "終了"
- }}}
- '''_digtmpl.dat''' というファイルが出来ていれば、成功です。~%
- '''_digtmpl.dat'''は'''packfile'''ファイルに入れられるのでいいかなぁ〜と。ちょくとさん方式でコード化してもいいですね。
- 
- 後は、これを呼び出すだけです。~%
- {{{
- #epack "_digtmpl.dat"
- 
- #define WM_INITDIALOG	 $00000110
- #define WM_CLOSE	 $00000010
- #define WM_COMMAND	 $00000111
- 
- onexit gosub *exit
- 
- #include "hscallbk.as"
- 
- #uselib ""
- #func DlgProc "" int,int,int,int
- setcallbk pDlgProc,DlgProc,*OnDlgProc
- 
- #uselib "user32.dll"
- #func DialogBoxIndirectParamA "DialogBoxIndirectParamA" int,var,int,var,int
- #func EndDialog "EndDialog" int,int
- 
- //--------------------------------
- 
- exist "_digtmpl.dat" : size=strsize
- 
- if size=-1{dialog "失敗":end}
- 
- sdim digtmpl,size
- bload "_digtmpl.dat",digtmpl,size
- 
- screen 0,640,480 : Hid=hwnd
- 
- pos 0,0 : button gosub "test", *go
- 
- stop
- 
- *go
- //テスト用にオーナーウィンドウを指定してません。
- 	DialogBoxIndirectParamA hinstance,digtmpl,0,pDlgProc,0
- //本当は、↓がメイン
- ;	DialogBoxIndirectParamA hinstance,digtmpl,hwnd,pDlgProc,0
- 
- return
- 
- *OnDlgProc ; 引数 hwnd,dwMsg,wPram,lPram
- 	dhwnd=callbkarg(0)
- 	dwMsg=callbkarg(1)
- 	wPram=callbkarg(2)
- 
- 	if dwMsg=WM_INITDIALOG{ return 1 }
- 
- 	if dwMsg=WM_COMMAND{
- 
- 		if (wPram&$ffff)=1{
- 			EndDialog dhwnd,1
- 		return 1
- 		}
- 	}
- 	
- 	if dwMsg=WM_CLOSE{
- 		EndDialog dhwnd,1
- 	return 1
- 	}
- 
- return 0
- 
- *exit
- end
- }}}
- ダイアログが表示されたら成功です。~%
- リソースファイルをいろんなダイアログテンプレートに書き換えて
- コンパイルするだけで呼び出せるので、~%
- ほかにも応用出来るかも。(試してませんが(笑))
- 
- あと、HSPの変数に直接書くやり方もありますが、非常に面倒なので割合させていただきます。
- 
- 2006/04/24 07:48:59 JST~%
- 早く実装されるといいですね。~%
- お約束の埋め込み。
- 
- {{{
- 
- onexit gosub *exit
- 
- #uselib "user32.dll"
- #func DialogBoxIndirectParamA "DialogBoxIndirectParamA" int,var,int,var,int
- #func EndDialog "EndDialog" int,int
- 
- ;xdimが必要かも。
- dim fncode,14
- fncode.0 = $8bec8b55, $102d0c45, $74000001, $0e754823, $107d8366, $660b7401
- fncode.6 = $02107d83, $c0330474, $b70f11eb, $ff501045, $15ff0875, $00000000
- fncode.12= $5d40c033, $000010c2
- 
- ;po=varptr(EndDialog) : fncode.11=varptr(po)
- po=varptr(EndDialog) : lpoke fncode,44,varptr(po)
- 
- ;テンプレートのリソースデータ
- dim dcode,63
- dcode.0=$00c800c0,$00000000,$00160004,$00e60011,$0000004b,$30d00000
- dcode.6=$30b830fc,$30f330e7,$583160c5,$00090000,$0053004d,$00550020
- dcode.12=$00200049,$006f0047,$00680074,$00630069,$00000000,$50000003
- dcode.18=$00000000,$0009000e,$00100010,$ffff0002,$ffff0082,$00000080
- dcode.24=$50020000,$00000000,$000a0031,$00080077,$ffffffff,$00740082
- dcode.30=$00730065,$00200074,$00650056,$00730072,$006f0069,$0020006e
- dcode.36=$002e0031,$00000030,$00000000,$50020000,$00000000,$00140031
- dcode.42=$00080077,$ffffffff,$00430082,$0070006f,$00720079,$00670069
- dcode.48=$00740068,$00280020,$00290043,$00320020,$00300030,$00000036
- dcode.54=$00000000,$50030001,$00000000,$000600c3,$000b001e,$ffff0001
- dcode.60=$004f0080,$0000004b,$00000000
- 
- screen 0,640,480
- 
- pos 0,0 : button gosub "test", *go
- 
- stop
- 
- *go
- 	gsel 0
- 	DialogBoxIndirectParamA hinstance,dcode,hwnd,fncode,0
- return
- *exit
- end
- 
- }}}
- そのまんまのコード
- {{{
- 
- #include <windows.h>
- 
- //BOOL (WINAPI *pfnEndDialog)(HWND,INT_PTR);
- 
- INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- 	UNREFERENCED_PARAMETER(lParam);
- 	switch (message)
- 	{
- 	case WM_INITDIALOG:
- 		return (INT_PTR)TRUE;
- 
- 	case WM_COMMAND:
- 		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- 		{
- 			EndDialog(hDlg, LOWORD(wParam));
- 			//pfnEndDialog(hDlg, LOWORD(wParam));
- 			return (INT_PTR)TRUE;
- 		}
- 		break;
- 	}
- 	return (INT_PTR)FALSE;
- }
- 
- }}}