←HSPハック トップへ

プロパティシートを使う

プロパティシートを使います

最終更新:2017/11/18

初版:2017/11/17




プロパティシートとは...


プロパティシートとは、項目の設定などで使われるダイアログの一種です。
よく見るのは、ファイルのプロパティダイアログだと思います。

表示させる方法は簡単で、CreatePropertySheetPage 関数で、タブのページを作成し、 PropertySheet 関数で、作成したタブが入ったプロパティシートを表示させるだけです。

※ちょくと氏のhscallbk.dllが必要です。

表示までの流れ


  1. PROPSHEETPAGE構造体にプロパティシートのページ情報を格納
  2. CreatePropertySheetPage 関数にPROPSHEETPAGE構造体へのアドレスを指定してページを作成。
  3. PROPSHEETHEADER構造体にプロパティシートの情報を格納
  4. PropertySheet 関数にPROPSHEETHEADER構造体へのアドレスを指定してプロパティシートを表示させる。

ページのためのダイアログの準備


前回と同じ方法で、HSPのランタイムファイルをコピーして、リソースエディターで編集できる状態にしておきます。
リソースエディタで任意のIDを持つダイアログを作成し、その中にコントロールを配置すれば完了です。
ResEdit

ページを作る


PROPSHEETPAGE構造体に必要な情報をセットしていきます。
typedef struct {
  DWORD           dwSize;
  DWORD           dwFlags;
  HINSTANCE       hInstance;
  union {
    LPCSTR         pszTemplate;
    LPCDLGTEMPLATE pResource;
  };
  union {
    HICON  hIcon;
    LPCSTR pszIcon;
  };
  LPCSTR          pszTitle;
  DLGPROC         pfnDlgProc;
  LPARAM          lParam;
  LPFNPSPCALLBACK pfnCallback;
  UINT            *pcRefParent;
#if (_WIN32_IE >= 0x0500)
  LPCTSTR         pszHeaderTitle;
  LPCTSTR         pszHeaderSubTitle;
#endif 
#if (_WIN32_WINNT >= 0x0501)
  HANDLE          hActCtx;
#endif 
} PROPSHEETPAGE, *LPPROPSHEETPAGE;
	
dwSizeメンバには構造体のサイズ=52を代入します。
dwFlagsメンバにはページのオプションを指定します。
意味
PSP_DEFAULT(0x00000000)デフォルト。
PSP_DLGINDIRECT(0x00000001)pResourceメンバが示すメモリ内のダイアログボックステンプレートからページを作成します。
PSP_HASHELP(0x00000020)ヘルプボタンを有効にします。
PSP_HIDEHEADER(0x00000800)ウェルカムページと設定完了ページだけに指定します。
PSP_USECALLBACK(0x00000080)ページが作成または破棄されたときに、pfnCallbackメンバに指定された関数を呼び出します。
PSP_USEHICON(0x00000002)hIconをページのタブアイコンとして使用します。
PSP_USEICONID(0x00000004)pszIconをページのタブアイコンとして使用するアイコンリソースの名前として使います。
PSP_USETITLE(0x00000008)pszTitleメンバをダイアログボックステンプレートに格納されているタイトルではなく、プロパティシートダイアログボックスのタイトルとして使用します。

hInstanceメンバにはダイアログボックスリソースがあるモジュールのハンドルを指定します。HSPではhinstanceを指定するといいでしょう。
pszTemplateメンバにはダイアログボックスリソースのIDを指定します。

hIconメンバにはページのアイコンハンドルを指定します。(dwFlagsにPSP_USEICONを指定する必要あり)
pszTitleメンバにはページのタイトルを指定します。(dwFlagsにPSP_USETITLEを指定する必要あり)

pfnDlgProcメンバにはダイアログプロシージャーへのポインタを指定します。
これを使ってウィンドウメッセージを処理します。プロシージャー内でEndDialogを呼び出さないでください。

lParamに、アプリケーション固有の値を指定します。

PROPSHEETPAGE構造体の準備が終わったら、CreatePropertySheetPage 関数にPROPSHEETPAGE構造体へのアドレスを指定してページを作成します。
呼び出し作成に成功した場合、ページのハンドルが返ってきますので、それを配列変数に代入します。

これを作るページの数だけ繰り返します。

プロパティシートダイアログを作る


PROPSHEETHEADER構造体に必要な情報をセットしていきます。
typedef struct {
  DWORD                dwSize;
  DWORD                dwFlags;
  HWND                 hwndParent;
  HINSTANCE            hInstance;
  union {
    HICON   hIcon;
    LPCTSTR pszIcon;
  };
  LPCTSTR              pszCaption;
  UINT                 nPages;
  union {
    UINT    nStartPage;
    LPCTSTR pStartPage;
  };
  union {
    LPCPROPSHEETPAGE ppsp;
    HPROPSHEETPAGE   *phpage;
  };
  PFNPROPSHEETCALLBACK pfnCallback;
#if (_WIN32_IE >= 0x0400)
  union {
    HBITMAP hbmWatermark;
    LPCTSTR pszbmWatermark;
  };
  HPALETTE             hplWatermark;
  union {
    HBITMAP hbmHeader;
    LPCSTR  pszbmHeader;
  };
#endif 
} PROPSHEETHEADER, *LPPROPSHEETHEADER;
	
dwSizeメンバには構造体のサイズ=52を代入します。
dwFlagsメンバにはページのオプションを指定します。
意味
PSH_DEFAULT(0x00000000)デフォルト。通常のプロパティシートが作成されます。
PSH_AEROWIZARD(0x00004000)Version 6.00か、Windows Vista対応。
新しいAeroスタイルを使用するウィザードのプロパティシートを作成します。PSH_WIZARDフラグも指定する必要があります。シングルスレッドアパートメント(STA)モデルを使用する必要があります。
PSH_HASHELP(0x00000200)プロパティシートのページにヘルプボタンを表示できるようにします。(PSH_AEROWIZARD指定時無効)
PSH_NOAPPLYNOW(0x0x00000080)[適用]ボタンを削除します。(PSH_AEROWIZARD指定時無効)
PSH_NOCONTEXTHELP(0x02000000)Version 5.80以降対応。
コンテキストヘルプボタンを削除します。(PSH_AEROWIZARD指定時無効)
PSH_PROPSHEETPAGE(0x0x00000008)ppspメンバを使用し、phpageメンバを無視します。
PSH_PROPTITLE(0x0x00000001)プロパティシートのタイトルバーに加工されたタイトルが表示されます。pszCaptionで指定された文字列の後に「のプロパティ」が挿入されます。
PSH_RESIZABLE(0x04000000)ユーザーがプロパティシートのサイズを変更できるようにします。PSH_AEROWIZARDと一緒に使います。
PSH_RTLREADING(0x00000800)プロパティシートのタイトル文字列の読む向きを右から左に変更します。
PSH_WIZARD(0x00000020)ウィザードのプロパティシートを作成します。PSH_AEROWIZARDを指定するときにも使います。
PSH_WIZARD97(0x00002000)Version 5.80以降対応。Wizard97ウィザードのプロパティシートを作成します。(PSH_AEROWIZARD指定時無効)
PSH_WIZARDCONTEXTHELP(0x00001000)コンテキストヘルプボタンを追加します。(PSH_AEROWIZARD指定時無効)
PSH_WIZARDHASFINISH(0x00000010)ウィザードに[完了]ボタンが常に表示されます。ウィザード形式のプロパティシート(PSH_WIZARD、PSH_WIZARD97、PSH_AEROWIZARD)である必要があります。

hwndParentメンバには親ウィンドウハンドルを指定します。HSPではhwndを指定するといいでしょう。
hInstanceメンバにはダイアログボックスリソースがあるモジュールのハンドルを指定します。HSPではhinstanceを指定するといいでしょう。
pszCaptionメンバにはダイアログボックスのタイトル文字列を指定します。

nStartPageメンバには0から始まる初期表示ページIDを指定します。
phpageメンバには、上で作成したページのハンドルが代入されている配列変数へのアドレスを指定します。

PROPSHEETHEADER構造体の準備が終わったら、PropertySheet 関数にPROPSHEETHEADER構造体へのアドレスを指定してプロパティシートを表示させます。
モーダルダイアログボックスにおいて、呼び出し作成に成功した場合は、ユーザーがOKを押すと1が、キャンセルを押すと0が返り、 失敗した場合は-1が返ります。
また、以下の値が返ることもあります。
ID_PSREBOOTSYSTEM(0x00000003)ページがPSM_REBOOTSYSTEMメッセージをプロパティシートに送信しました。ユーザーの変更を有効にするには、コンピュータを再起動する必要があります。
ID_PSRESTARTWINDOWS(0x00000002)ページがPSM_RESTARTWINDOWSメッセージをプロパティシートに送信しました。ユーザーの変更を有効にするには、Windowsを再起動する必要があります。
モードレスプロパティシートの場合の戻り値は、プロパティシートのウィンドウハンドルです。

プロパティシートで[OK]や[適用]ボタンを押すと、各ページのプロシージャーにWM_NOTIFYメッセージが送信されます。 そのときの通知コードがPSN_APPLYであれば、設定情報を取得し反映する処理を行います。

スクリプト


ソース一式:PropSheetTest.zip

プロパティシートを使ってフォントの書式を設定するサンプルです。

ダイアログリソース:
LANGUAGE 17, SUBLANG_DEFAULT
200 DIALOG 0, 0, 260, 180
STYLE DS_SETFONT | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP
CAPTION "書式"
FONT 9, "MS UI Gothic"
{
    EDITTEXT        40000, 75, 25, 165, 17, ES_AUTOHSCROLL, WS_EX_LEFT
    EDITTEXT        40001, 75, 50, 165, 17, ES_AUTOHSCROLL | ES_NUMBER, WS_EX_LEFT
    AUTOCHECKBOX    "太字(&B)", 40002, 25, 100, 60, 10, 0, WS_EX_LEFT
    AUTOCHECKBOX    "斜体(&I)", 40003, 25, 115, 60, 10, 0, WS_EX_LEFT
    AUTOCHECKBOX    "下線(&U)", 40004, 90, 100, 60, 10, 0, WS_EX_LEFT
    AUTOCHECKBOX    "打ち消し線(&S)", 40005, 90, 115, 60, 10, 0, WS_EX_LEFT
    GROUPBOX        "スタイル(&Y):", 65535, 15, 85, 145, 55, 0, WS_EX_TRANSPARENT
    LTEXT           "フォント名(&N):", 65535, 16, 27, 37, 9, SS_LEFT, WS_EX_LEFT
    LTEXT           "フォントサイズ(&Z):", 65535, 16, 52, 46, 9, SS_LEFT, WS_EX_LEFT
}

LANGUAGE 17, SUBLANG_DEFAULT
201 DIALOG 0, 0, 260, 180
STYLE DS_SETFONT | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP
CAPTION "文字列"
FONT 9, "MS UI Gothic"
{
    EDITTEXT        40000, 75, 25, 165, 17, ES_AUTOHSCROLL, WS_EX_LEFT
    LTEXT           "タイトル文字列(&T):", 65535, 16, 27, 55, 9, SS_LEFT, WS_EX_LEFT
}
resource.h:
#define IDC_EDIT_FONTNAME                       40000
#define IDC_EDIT_TITLE                          40000
#define IDC_EDIT_FONTSIZE                       40001
#define IDC_CHK_BOLD                            40002
#define IDC_CHK_ITALIC                          40003
#define IDC_CHK_UNDERLINE                       40004
#define IDC_CHK_STRIKEOUT                       40005
ソースファイル:
//HSP3.5から対応。

#include "comctl32.as"
#include "user32.as"
#include "kernel32.as"
#include "shell32.as"
#include "hscallbk.as"

#include "resource.h"

#packopt name "プロパティシート表示サンプル"
#packopt runtime "runtime.hrt"

#uselib ""
#func _PropWndProc "" int, int, int
#func _PropPageProc1 "" int, int, int, int
#func _PropPageProc2 "" int, int, int, int
setcallbk pPropWndProc, _PropWndProc, *PropWndProc
setcallbk pPropPageProc1, _PropPageProc1, *PropPageProc1
setcallbk pPropPageProc2, _PropPageProc2, *PropPageProc2

#define PROPSHEETPAGE_SIZE 13
#define PROPSHEETHEADER_SIZE 13

#define WM_DESTROY 0x0002
#define WM_SETTEXT 0x000C
#define WM_NOTIFY 0x004E
#define BM_GETCHECK 0x00F0
#define BM_SETCHECK 0x00F1
#define WM_INITDIALOG 0x0110

#define PSN_APPLY -202

#define PSP_DEFAULT 0x00000000
#define PSH_DEFAULT 0x00000000


#define mhwnd callbkarg(0)
#define mmsg callbkarg(1)
#define mwp callbkarg(2)
#define mlp callbkarg(3)
#define mplp callbkarg(2)

//プロパティシートで使う設定項目用の変数
sdim FontName,0x101
sdim sTitle,0x101
FontName = "MS ゴシック" //フォント名
FontSize = 12 //フォントサイズ
FontStyle = 0 //フォントスタイル
sTitle = "タイトル" //タイトル

button gosub "表示!", *ShowProp

stop
*ShowProp
	dim psp,PROPSHEETPAGE_SIZE		//PROPSHEETPAGE構造体
	dim psh,PROPSHEETHEADER_SIZE	//PROPSHEETHEADER構造体
	dim hPsp,3						//プロパティページハンドル
	
	//前準備
	psp(0) = PROPSHEETPAGE_SIZE*4	//dwSize
	psp(1) = PSP_DEFAULT			//dwFlags
	psp(2) = hinstance	 			//hInstance
	psp(3) = 0			 			//pszTemplate
	psp(4) = 0		 				//hIcon
	psp(5) = 0		 				//pszTitle
	psp(6) = 0						//pfnDlgProc
	psp(7) = 0		 				//lParam
	psp(8) = 0		 				//pfnCallback
	psp(9) = 0		 				//pcRefParent

	//タブページ1を作る
	psp(3) = 200		 			//pszTemplate
	psp(6) = varptr(pPropPageProc1)	//pfnDlgProc
	hPsp(0)=CreatePropertySheetPage(varptr(psp))
	
	//タブページ2を作る
	psp(3) = 201		 			//pszTemplate
	psp(6) = varptr(pPropPageProc2)	//pfnDlgProc
	hPsp(1)=CreatePropertySheetPage(varptr(psp))
	
	szCaption="はじめてのプロパティシート" //タイトル
	psh(0) = PROPSHEETHEADER_SIZE*4	//dwSize
	psh(1) = PSH_DEFAULT			//dwFlags
	psh(2) = hwnd		 			//hwndParent
	psh(3) = hDLLInstance		 	//hInstance
	psh(4) = 0						//hIcon / pszIcon
	psh(5) = varptr(szCaption) 		//pszCaption
	psh(6) = 2					 	//nPages
	psh(7) = 0					 	//nStartPage / pStartPage
	psh(8) = varptr(hPsp)		 	//ppsp / phpage
	psh(9) = varptr(pPropWndProc)	//pfnCallback
	psh(10) = 0					 	//hbmWatermark / pszbmWatermark
	psh(11) = 0					 	//hplWatermark
	psh(12) = 0					 	//hbmHeader / pszbmHeader
	ret = PropertySheet(varptr(psh))
	if (ret == -1){ //作成失敗
		mes "作成失敗"
	}else:if (ret == 0){ //変更を保存しない
		mes "キャンセル"
	}else:if (ret >= 1){ //変更を保存する
		mes "OK"
	}

	//変更した設定を反映
	color 255, 255, 255:boxf
	color 0, 0, 0:pos 40,40
	font FontName, FontSize, FontStyle
	mes sTitle
return
*PropWndProc
	return 0
return

*PropPageProc1
	switch mmsg
	case WM_INITDIALOG //ダイアログが初期化される
		//GetDlgItemでIDからウィンドウハンドルを取得し、文字列を設定する。

		//フォント名入力ボックス
		SendMessage GetDlgItem(mhwnd, IDC_EDIT_FONTNAME), WM_SETTEXT, 0, varptr(FontName)
		
		//フォントサイズ入力ボックス
		string=strf("%u",FontSize)
		SendMessage GetDlgItem(mhwnd, IDC_EDIT_FONTSIZE), WM_SETTEXT, 0, varptr(string)
				
		SendMessage GetDlgItem(mhwnd, IDC_CHK_BOLD), BM_SETCHECK, (FontStyle&&1)!=0, 0
		SendMessage GetDlgItem(mhwnd, IDC_CHK_ITALIC), BM_SETCHECK, (FontStyle&&2)!=0, 0
		SendMessage GetDlgItem(mhwnd, IDC_CHK_UNDERLINE), BM_SETCHECK, (FontStyle&&4)!=0, 0
		SendMessage GetDlgItem(mhwnd, IDC_CHK_STRIKEOUT), BM_SETCHECK, (FontStyle&&8)!=0, 0
		
		return 1
	swbreak
	case WM_NOTIFY
		dupptr hdr, mlp, 3*4
		if (hdr(2) == PSN_APPLY){//[OK]か[適用]ボタンが押された
			//GetDlgItemTextでダイアログ上のコントロールの文字列を取得する。
			
			GetDlgItemText mhwnd, IDC_EDIT_FONTNAME, varptr(FontName), 0x100
			FontSize = GetDlgItemInt(mhwnd, IDC_EDIT_FONTSIZE, 0, 0)
			
			FontStyle = 0
			FontStyle |= (SendMessage(GetDlgItem(mhwnd, IDC_CHK_BOLD), BM_GETCHECK, 0, 0)!=0) * 1
			FontStyle |= (SendMessage(GetDlgItem(mhwnd, IDC_CHK_ITALIC), BM_GETCHECK, 0, 0)!=0) * 2
			FontStyle |= (SendMessage(GetDlgItem(mhwnd, IDC_CHK_UNDERLINE), BM_GETCHECK, 0, 0)!=0) * 4
			FontStyle |= (SendMessage(GetDlgItem(mhwnd, IDC_CHK_STRIKEOUT), BM_GETCHECK, 0, 0)!=0) * 8
		}
	swbreak
	swend
	return 0
return

*PropPageProc2
	switch mmsg
	case WM_INITDIALOG //ダイアログが初期化される
		//GetDlgItemでIDからウィンドウハンドルを取得し、文字列を設定する。
		SendMessage GetDlgItem(mhwnd, IDC_EDIT_TITLE), WM_SETTEXT, 0, varptr(sTitle)
		return 1
	swbreak
	case WM_NOTIFY
		dupptr hdr, mlp, 3*4
			if (hdr(2) == PSN_APPLY){//[OK]か[適用]ボタンが押された
			//GetDlgItemTextでダイアログ上のコントロールの文字列を取得する。
			GetDlgItemText mhwnd, IDC_EDIT_TITLE, varptr(sTitle), 0x100
		}
	swbreak
	swend
	return 0
return
実行サンプル
[表示!]ボタンを押すとプロパティシートが表示されます。
[書式]タブでフォントの設定、[文字列]タブで表示する文字列を変更できます。
OKを押すと設定した書式が反映され、HSPウィンドウに文字列が描画されます。




[前へ] [戻る] [次へ]

(C)2019 inonote / 無断転載禁止