第七回・ボタンを押したらメモ帳が起動する

さて、またまた久しぶりの様な気がする第七回。
今回は『ボタンを押したらメモ帳が起動する』です。
つまり、他のプログラムを起動する方法ですね。

ただし、他のプログラムを起動すると言ってもランチャー
と言うよりはメニュープログラムを意識しています。
サークルの作品集CD-ROMなどでメニュープログラムがあると
便利ですよ。

では、本題に入る前に、他のプログラムを起動するAPIを紹介します。

WinExec・・・一番簡単、コマンドラインが利用できる
CreateProcess・・・コマンドラインが利用できる、プロセスのハンドルが取得できる
ShellExecute・・・関連付けが利用できる

この他にもいくつかあった気がしますが、よくわからないので省略します。
では、サンプルを見て下さい。

サンプルコード(新しいウィンドウで開きます)

前回と違う点は

最初の方の

//定数
#define Button1		100

という部分と

ウィンドウプロシージャの

case WM_CREATE:
	CreateWindow("BUTTON", "メモ帳を起動!", WS_CHILD | WS_VISIBLE |
		 BS_PUSHBUTTON, 10, 10,150, 25, hwnd, (HMENU)Button1, g_hInstance, NULL);
	return 0;
case WM_COMMAND:
	switch(LOWORD(wParam))
	{
	case Button1:
		ShellExecute(NULL,"open","notepad.exe",NULL,NULL,SW_SHOWNORMAL);
		break;
	}
	return 0;

この部分だけです。

//定数
#define Button1		100

#defineはわかりますね?この後に出てくる「Button1」という記号を全て「100」に
置き換えろという意味です。
なぜこんなことをするかというと、ただ単に100と書いてあると何の100なのか
わからなくなってしまうからです。
ちなみに今回の100はボタンのIDです。ボタンを増やしたいときは

#define Button2		101
#define Button3		102


等のように増やしていきます。そして増やした分だけボタンを作り、場合分けをして
ボタンごとの処理をします。

ボタンが増えた場合

case WM_CREATE:
	CreateWindow("BUTTON", "メモ帳を起動!", WS_CHILD | WS_VISIBLE |
		 BS_PUSHBUTTON, 10, 10,150, 25, hwnd, (HMENU)Button1, g_hInstance, NULL);
	return 0;


WM_CREATEメッセージはウィンドウが作られるときに一度だけ送られるメッセージです。
なので起動時に一度だけやりたい処理はここでします。
今回はCreateWindowでボタンを作成しています。

気が付きましたか?ボタンも通常のウィンドウと同じように作成します。
実はボタンに限らずWindowsのパーツはほとんどがウィンドウです。

CreateWindowの各パラメータについての説明はヘルプなどを参照して下さい。

第9引数の

(HMENU)Button1

というのがボタンのIDですが、この第9引数は本来ウィンドウのメニューの
ハンドルを入れる引数なので(HMENU)と型キャストをかけています。
キャストを忘れると「型が違うぞ〜!」と怒られるわけですね。

WM_COMMANDメッセージはボタンが押された時やメニューから項目が選択された
時に送られるメッセージです。
このメッセージが送られるとき、同時にwParamの下位ワードでIDが送られるので

switch(LOWORD(wParam))

として各IDごとに処理を振り分けます。(LOWORDは下位ワードを取得するマクロ)
これでどのボタンが押されたか見分けるわけですね。

	case Button1:
		ShellExecute(NULL,"open","notepad.exe",NULL,NULL,SW_SHOWNORMAL);
		break;

やっとここでShellExecuteが出てきました。

第一引数は親ウィンドウのハンドル
第二引数は操作(他にprintやexploreが指定できる)
第三引数は実行するファイル名(関連付けされていれば実行ファイル以外でも可)
第四引数は実行時に渡すパラメータ(第三引数が実行ファイルの場合のみ)
第五引数は実行するディレクトリ
第六引数は表示状態

これでメモ帳を起動しています。

ちなみに他のAPIを使った場合。

●WinExecを使った場合

	case Button1:
		WinExec("notepad.exe",SW_SHOWNORMAL);
		break;

これが一番簡単でしたね。でもWin32で使用するのは推奨されていません。

●CreateProcessを使った場合

	case Button1:
		STARTUPINFO si;
		PROCESS_INFORMATION pi;

		ZeroMemory((LPVOID)&si,sizeof(STARTUPINFO));
		si.cb = sizeof(STARTUPINFO);
		si.dwFlags = STARTF_USESHOWWINDOW;
		si.wShowWindow = SW_SHOWNORMAL;

		CreateProcess(NULL,"notepad.exe",NULL,NULL,FALSE,
			CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS ,NULL,NULL,&si,&pi);
		break;


面倒ですね(^^;)プロセスのハンドルはpi.hProcessに保存されます。

今回はここまでです。お疲れさまでした。

戻る