PHPでWinAsmを使ってWindowsプログラムをデザイン

(1/1)
これまで、WinBinderbamcompile を使ってWindowsアプリを作ったが、アプリケーションウィンドウをソースコードに書くのは手間がかかる。
そこで今回は、ウィンドウをGUIツールを使ってデザインできる無償ツール WinAsm Studio を使い、パスワードを生成するEXEプログラムを作ってみることにする。

サンプル・プログラム

PHPでWindowsアプリを開発する

WinAsmの準備

winasm.org から WinAsm Studioをダウンロードし、ここでは、"C:\php4\WinAsm\" に解凍する。

日本語が使えるように、UI languages からJapanese UIをダウンロードする。解凍して得られた "Japanese.dll" は "C:\php4\WinAsm\UI\" へコピーする。

リソース

makepassword.zip を解凍すると、下記のようになる。
makepassword.zip
│  makepassword.bcp
│  makepassword.exe
└─makepassword
     │  makepassword.phpw
     │  makepassword.rc
     │  application.ico
     │  php_mbstring.dll
     │  php_winbinder.dll
     ├─include
     │     wb_generic.inc.php
     │     wb_resources.inc.php
     │     wb_windows.inc.php
     │     winbinder.php
     └─icon
         makepassword.ico
makepassword.rc がウィンドウのデザインを記したリソースである。その中身はテキストファイルである。
拡張子 .rc を WinAsm に関連づけておくといいだろう。

0001: ;This Resource Script was generated by WinAsm Studio.
0002: 
0003: #define IDC_NUM_LABEL 1010
0004: #define IDC_NUM_EDIT 1011
0005: #define IDC_OPT1_CHECK 1016
0006: #define IDC_OPT2_CHECK 1017
0007: #define IDC_OPT3_CHECK 1018
0008: #define IDC_OPT4_CHECK 1019
0009: #define IDC_OPT1_LABEL 1012
0010: #define IDC_OPT2_LABEL 1013
0011: #define IDC_OPT3_LABEL 1014
0012: #define IDC_OPT4_LABEL 1015
0013: #define IDC_EXEC_BUTTON 1020
0014: #define IDC_PASSWORD_EDIT 1021
0015: #define IDC_GROUPBOX1 1022
0016: #define IDD_MAIN 1001
0017: 
0018: IDD_MAIN DIALOGEX 0,0,180,130
0019: CAPTION "パスワード生成機"
0020: FONT 10,"MS Pゴシック"
0021: STYLE 0x10cc0000
0022: EXSTYLE 0x00000000
0023: BEGIN
0024:     CONTROL "",IDC_GROUPBOX1,"Button",0x50000007,6,3,166,62,0x00000000
0025:     CONTROL "桁数",IDC_NUM_LABEL,"Static",0x50000000,16,15,21,10,0x00000000
0026:     CONTROL "8",IDC_NUM_EDIT,"Edit",0x50012002,37,12,38,13,0x00000200
0027:     CONTROL "英大文字",IDC_OPT1_LABEL,"Static",0x50000000,34,31,40,10,0x00000000
0028:     CONTROL "英小文字",IDC_OPT2_LABEL,"Static",0x50000000,126,31,40,10,0x00000000
0029:     CONTROL "数字",IDC_OPT3_LABEL,"Static",0x50000000,34,46,40,10,0x00000000
0030:     CONTROL "記号",IDC_OPT4_LABEL,"Static",0x50000000,126,46,40,10,0x00000000
0031:     CONTROL "IDC_CHECKBOX1016",IDC_OPT1_CHECK,"Button",0x50010002,17,31,9,10,0x00000000
0032:     CONTROL "IDC_CHECKBOX1017",IDC_OPT2_CHECK,"Button",0x50010003,106,31,9,10,0x00000000
0033:     CONTROL "IDC_CHECKBOX1018",IDC_OPT3_CHECK,"Button",0x50010003,17,46,9,10,0x00000000
0034:     CONTROL "IDC_CHECKBOX1019",IDC_OPT4_CHECK,"Button",0x50010003,106,46,9,10,0x00000000
0035:     CONTROL "生成",IDC_EXEC_BUTTON,"Button",0x50010000,6,74,41,13,0x00000000
0036:     CONTROL "",IDC_PASSWORD_EDIT,"Edit",0x50000000,57,74,112,13,0x00000200
0037: END
0038: 

WinAsm で makepassword.rc を開くと、下のような画面になる。
Excelマクロ開発やVisualStudioのような感じで編集ができる。
WinAsm

解説:ウィンドウの作成

0274: // メインプログラム ==================================================
0275: //コントロール配置
0276: eval(parse_rc(file_get_contents('makepassword.rc'), '$window', NULLPopupWindowAPPNAMEWBC_CENTERWBC_CENTER, 260, 240, 0, 0));
0277: 
0278: //フォント設定
0279: $font = wb_create_font(FONT_NAME, 10);
0280: wb_set_font($window$font);
0281: wb_set_font(wb_get_control($windowIDC_NUM_LABEL), $font);
0282: wb_set_font(wb_get_control($windowIDC_NUM_EDIT),  $font);
0283: wb_set_font(wb_get_control($windowIDC_OPT1_LABEL), $font);
0284: wb_set_font(wb_get_control($windowIDC_OPT2_LABEL), $font);
0285: wb_set_font(wb_get_control($windowIDC_OPT3_LABEL), $font);
0286: wb_set_font(wb_get_control($windowIDC_OPT4_LABEL), $font);
0287: wb_set_font(wb_get_control($windowIDC_PASSWORD_EDIT), $font);
0288: wb_set_font(wb_get_control($windowIDC_EXEC_BUTTON), $font);
0289: wb_set_font(wb_get_control($windowIDC_COPY_BUTTON), $font);
0290: 
0291: //チェックボックスのデフォルト値
0292: wb_set_value(wb_get_control($windowIDC_OPT1_CHECK), TRUE);
0293: wb_set_value(wb_get_control($windowIDC_OPT2_CHECK), FALSE);
0294: wb_set_value(wb_get_control($windowIDC_OPT3_CHECK), TRUE);
0295: wb_set_value(wb_get_control($windowIDC_OPT4_CHECK), FALSE);
0296: 
0297: //メニューバーの生成
0298: $mainmenu = wb_create_control($windowMenuarray(
0299:     internal2sjis('ファイル(&F)'),
0300:         array(IDCLOSE,    internal2sjis('終了(&X)\tCtrl+Q'), "", "", "Ctrl+Q"),
0301:     internal2sjis('ヘルプ(&H)'),
0302:         array(IDC_HELPinternal2sjis('このプログラムについて(&H)'), "", "", "")
0303: )); 
0304: 
0305: //イベントハンドラの設定
0306: wb_set_handler($window, 'process_main');
0307: 
0308: //アプリケーション・アイコン設定
0309: wb_set_image($windowICONFILE);
0310: 
0311: //起動時フォーカス
0312: wb_set_focus(wb_get_control($windowIDC_EXEC_BUTTON));
0313: 
0314: //アプリケーションループ
0315: wb_main_loop();

パスワードを生成するユーザー関数 make_password は「PHPでパスワードを生成」で作ったものをそのまま流用している。

ここでは、リソースに対するロジックを説明する。
まず、関数  file_get_contents  を使ってリソース "makepassword.rc" を読み込む。読み込んだ文字列をWinBinder関数 parse_rc に入れてやると、「PHPでWindowsアプリケーションウィンドウに表示する」で書いたアプリケーションウィンドウを作成するPHPソースに変換される。そこで、関数  eval  を使って評価してやれば、PHPソースが実行できた格好になる。

次に、WinBinder関数 wb_get_control と関数 wb_set_value を使い、いくつかのコントロールの初期値を設定してやる。これらはリソースに初期値として設定したやっても構わない。

メニューバーの設定は、WinBinder関数 wb_create_control を使う。

解説:イベントハンドラ

0229: /**
0230:  * イベントハンドラ:メインウィンドウ
0231:  * @param int $windowウィンドウID
0232:  * @param int $id     イベントID
0233: */
0234: function process_main($window$id) { 
0235:     switch($id) {
0236:         //パスワード生成
0237:         case IDC_EXEC_BUTTON:
0238:             put_password($window);
0239:             break
0240:         //パスワード・コピー
0241:         case IDC_COPY_BUTTON:
0242:             $psw = wb_get_text(wb_get_control($windowIDC_PASSWORD_EDIT));
0243:             SetClipboardData(1, $psw);
0244:             break
0245:         //ヘルプ機能
0246:         case IDC_HELP:
0247:             create_help($window, 'process_help');
0248:             break;  
0249:         //プログラム終了
0250:         case IDCLOSE:
0251:             wb_destroy_window($window);      //ウィンドウを破棄 
0252:             break;  
0253:     }
0254: }

「生成」ボタンや「コピー」ボタンを押下したときの動作と、メニューバーの「ヘルプ」動作、「閉じる」ボタンを押下したときの動作は、イベントハンドラ process_main に記述する。
第2引数に、イベントを発生したコントロールIDを渡すので、それに応じて処理を分岐させてやればよい。

0189: /**
0190:  * ヘルプ・ダイアログを作成
0191:  * @param  int       $parent 親ウィンドウID
0192:  * @param  string   $handlerイベントハンドラ
0193:  * @return string    なし
0194: */
0195: function create_help($parent$handler) {
0196:     global $Password_min$Password_max;
0197: 
0198:     if (!defined('IDH_HELP_LABEL'))   define('IDH_HELP_LABEL',   3011);
0199:     if (!defined('IDH_LINK_BUTTON'))   define('IDH_LINK_BUTTON',  3021);
0200:     if (!defined('IDH_CLOSE_BUTTON'))   define('IDH_CLOSE_BUTTON', 3022);
0201: 
0202:     $name = APPNAME;
0203:     $ver  = APPVERSION;
0204:     $year = date('Y');
0205: $help =<<< EOT
0206: {$name}  バージョン {$ver}
0207: Copyright by (c)studio pahoo, {$year}
0208: 
0209: {$Password_min} 文字以上、{$Password_max} 文字以下のパスワードを生成します。
0210: 
0211: EOT;
0212: 
0213:     $window = wb_create_window($parentModalDialoginternal2sjis('このプログラムについて'), WBC_CENTERWBC_CENTER, 300, 200, WBC_VISIBLE, 0);
0214: 
0215:     //コントロール配置
0216:     wb_set_handler($window$handler);
0217:     wb_create_control($windowLabelinternal2sjis($help), 10, 15, 250, 140, IDH_HELP_LABELWBC_MULTILINE);
0218:     wb_create_control($windowPushButtoninternal2sjis('参考サイト'), 40, 110, 80, 20, IDH_LINK_BUTTONWBC_VISIBLE | WBC_ENABLED);
0219:     wb_create_control($windowPushButtoninternal2sjis('閉じる'), 140, 110, 80, 20, IDH_CLOSE_BUTTONWBC_VISIBLE | WBC_ENABLED);
0220: 
0221:     //フォント設定
0222:     $font = wb_create_font(FONT_NAME, 10);
0223:     wb_set_font($window$font);
0224:     wb_set_font(wb_get_control($windowIDH_HELP_LABEL), $font);
0225:     wb_set_font(wb_get_control($windowIDH_LINK_BUTTON), $font);
0226:     wb_set_font(wb_get_control($windowIDH_CLOSE_BUTTON), $font);
0227: }

ヘルプもダイアログで表示するのだが、WinAsmで複数のダイアログを生成する良い方法が見当たらなかったので、こちらはPHPソースとして create_help に記述した。

0256: /**
0257:  * イベントハンドラ:このプログラムについて
0258:  * @param int $windowウィンドウID
0259:  * @param int $id     イベントID
0260: */
0261: function process_help($window$id) { 
0262:     switch($id) {
0263:         case IDH_LINK_BUTTON:
0264:             wb_exec(REFERENCE);
0265:             wb_destroy_window($window);      //ウィンドウを破棄 
0266:             break;  
0267:         case IDH_CLOSE_BUTTON:
0268:         case IDCLOSE:
0269:             wb_destroy_window($window);      //ウィンドウを破棄 
0270:             break;  
0271:     }
0272: }

ヘルプにもイベントハンドラ process_help を付けている。
「参考サイト」ボタンを押下すると、WinBinder関数 wb_exec を使って標準ブラウザが起動するようにしてある。

「コピー」ボタンを押下したときに、パスワードをクリップボードにコピーするが、この処理は「PHPでクリップボードにテキスト貼り付け(Windowsアプリ版)」で紹介したプログラムを利用している。

コンパイル

コンパイルは「PHPでbamcompileを使ってEXEプログラムを生成」で紹介したのと同じ手順で、bamcompile.exe を使ってプロジェクトファイル "makepassword.bcp" をコンパイルする。
コマンドラインから "bamcompile makepassord.bcp" を実行する。コンパイルが完了すると、"makepassord.exe" が生成されている。
"makepassord.exe" は、DLL不要で、単独で動作するEXEプログラムである。

参考サイト

(この項おわり)
header