HSP Tips

俺流HSPテンプレートその2

前回のテンプレートを更に細かく仕様変更しました

HSPテンプレート

 以前のテンプレートは、コード量の増大でランタイムコンパイル時に時間がかかりすぎているため(EXE容量には問題なし)、余分な部分を排除することにしました。
 ラベルを連番にし、コメント行でどういう動作をするのか比べるようにしたり、モジュール内で各Win32APIや定数を宣言することに仕様変更しました。

 このテンプレートは、テンプレートの二重起動防止で利用しているシリルさんのモジュールのライセンスにあわせ、NYSLとします。煮るなり焼くなり好きにしてください。




   

Main.hsp

//-------------------------------------------------------------------- 
// 
//   
// 
//   
// 
//-------------------------------------------------------------------- 
*SYS001	//## インクルード 
//-------------------------------------------------------------------- 
// Include 
//-------------------------------------------------------------------- 
#include "windowmessage.hsp"//ウィンドウメッセージの定義 
#include "mod_wrun.hsp"		//二重起動の禁止 
#include "mod_ini.hsp"		//iniファイルの制御 
#include "mod_sc.hsp"		//正確なシステムカラーの取得 
#include "mod_locksel.hsp"	//描画先ウィンドウの固定 
#include "mod_debug.hsp"	//デバッグモジュール 
//-------------------------------------------------------------------- 
// マクロ定義 
//-------------------------------------------------------------------- 
	 
	#define global _exename ""									//実行ファイルの名前(重要) 
	#define global _tit ""										//ソフトウェアタイトル名 
	#define global _ver ""										//ソフトウェアバージョン 
	#define global _ininame _exename+".ini"						//iniファイルの名前 
	#define global startchek 0									//二十起動防止コンパイルチェック 
	#define global _winx ginfo(12)								// ウィンドウの縦のサイズを代入 
	#define global _winy ginfo(13)								//ウィンドウの横のサイズを代入 
	#define global ctype	LOWORD(%1) (%1 & 0xFFFF)			//下位ワード値を取得 
	#define global ctype	HIWORD(%1) ((%1 >> 16 ) & 0xFFFF)	//下位ワード値を取得 
	dir_main_p@	=	dir_cur 
	#define global dir_main dir_main_p@							//exeのあるディレクトリ 
	#define global ctype	objh(%1)	objinfo (%1,2)			//オブジェクトハンドル 
	#define global ctype crgb(%1,%2,%3)			(%1|(%2<<8)|(%3<<16)) 
	 
*SYS002	//## マクロ定義 
 
 
//-------------------------------------------------------------------- 
// パック設定 
//--------------------------------------------------------------------	 
 
	#packopt name _exename 
	#packopt type 0 
	#packopt hide 1 
 
//-------------------------------------------------------------------- 
// 基本変数管理用変数 
//-------------------------------------------------------------------- 
 
	winx=640					//初期ウィンドウの縦のサイズを代入 
	winy=480					//初期ウィンドウの横のサイズを代入 
	winposx=(ginfo(20)-winx)>>1	//ウィンドウの表示位置 
	winposy=(ginfo(21)-winy)>>1	//ウィンドウの表示位置 
 
 
*SYS003	//## 基本変数 
//-------------------------------------------------------------------- 
// ▽モジュールエリア 
//-------------------------------------------------------------------- 
 
 
 
*SYS004	//## モジュール 
 
	 
 
//-------------------------------------------------------------------- 
// 起動準備 
//-------------------------------------------------------------------- 
 
	//重複起動の禁止 
	if wrun()=0{ 
		end 
	} 
	 
	//iniファイルの読み込み 
	iniload _ininame,data 
 
	//iniファイルが存在したかどうか 
	if stat!-1{ 
		//存在した場合 
		winposx=inigetint ("pos","posx",data) 
		winposy=inigetint ("pos","posy",data) 
 
	}else{ 
		//存在しない場合 
 
		 
 
	} 
*SYS005	//## 起動準備 
 
 
	 
*SYS006	//## スクリーン作成 
//-------------------------------------------------------------------- 
// スクリーン作成 
//-------------------------------------------------------------------- 
	 
	//メイン 
	screen 0,winx,winy,6,winposx,winposy	//スクリーンウィンドウの初期化 
	gosub *SUB001						//ウィンドウ位置の記憶 
	title _tit 
	objmode 1 
	objsize 60,21 
	sysfont 17 
 
 
*SYS007	//## オンメッセージ定義 
//-------------------------------------------------------------------- 
// オンメッセージ定義 
//-------------------------------------------------------------------- 
 
	 
	gsel 0 
	onexit *SUB002 
	oncmd gosub *CMD002,WM_MOVE			//ウィンドウが移動 
	oncmd gosub *CMD001,WM_LBUTTONDOWN	//左クリックを押した 
	 
 
*SYS008	//## メインスクリプト 
//-------------------------------------------------------------------- 
// @メインスクリプト 
//-------------------------------------------------------------------- 
 
 
	 
	gsel 0,1			//初期画面表示 
	stop 
	 
*SYS009	//## オンメッセージ処理 
//-------------------------------------------------------------------- 
// オンメッセージ処理 
//-------------------------------------------------------------------- 
 
 
 
 
*CMD001	//左クリックを押した 
	 
	switch ginfo_intid 
 
		//Screen 0 
		case 0 
			locksel_start 0 
 
			if debug(){ 
				title "MOUSE("+mousex+","+mousey+")   _WINX-MOUSE("+(_winx-mousex)+","+(_winy-mousey)+")" 
			} 
			 
			locksel_end 
		 
 
		swbreak 
 
	swend 
	 
	return 
 
	 
*CMD002	//ウィンドウが移動 
	switch ginfo_intid 
 
		//Screen 0 
		case 0 
			locksel_start 0 
			if (LOWORD(lparam)<(ginfo(12)+ginfo(21)))&(HIWORD(lparam)<(ginfo(13)+ginfo(21))){ 
				if (LOWORD(lparam)>-ginfo(12))&(HIWORD(lparam)>-ginfo(13)){ 
					gosub *SUB001	//ウィンドウ位置の記憶 
				} 
			} 
			locksel_end 
		 
		swbreak 
 
 
	swend 
	return 
 
 
 
 
 
*SYS010	//## サブルーチン 
//-------------------------------------------------------------------- 
// サブルーチン 
//-------------------------------------------------------------------- 
 
*SUB001	//ウィンドウ位置の記憶 
	locksel_start 0 
	inisetint ginfo(4),"pos","posx",data 
	inisetint ginfo(5),"pos","posy",data 
	locksel_end 
	return 
	 
*SUB002	//ソフト終了 
	switch wparam 
		case 0 
			chdir dir_main 
			inisave _ininame,data 
			wrunend					//二重起動の防止の解除 
			end 
		swbreak 
	swend 
 
	 
	end 
 
 
 

windowmessage.hsp

 
#define 	WM_ACTIVATE			0x0006	//ウィンドウのアクティブ化・非アクティブ化	 
#define 	WM_CHAR				0x0102	//キーボードからの文字の入力	 
#define 	WM_CLEAR			0x0303	//エディットコントロールのテキストの削除  
#define 	WM_COMMAND			0x0111	//メニューアイテムの選択・コントロールからの通知	 
#define 	WM_CONTEXTMENU		0x007B	//コンテキストメニューを表示するために受け取る通知	 
#define 	WM_COPY				0x0301	//エディットコントロールのテキストのコピー		 
#define 	WM_CUT				0x0300	//エディットコントロールのテキストの切り取り  
#define 	WM_DROPFILES		0x0233	//ファイルがドロップされた	 
#define 	WM_GETFONT			0x0031	//コントロールのフォントを取得	 
#define 	WM_GETICON			0x007F	//ウィンドウのアイコンを取得	 
#define 	WM_GETTEXT			0x000D	//ウィンドウタイトルやコントロールのテキストを取得	 
#define 	WM_GETTEXTLENGTH	0x000E	//ウィンドウタイトルやコントロールのテキストのサイズを取得	 
#define 	WM_KEYDOWN			0x010	//非システムキーが押された	 
#define 	WM_KEYUP			0x0101	//押されていた非システムキーが離された	 
#define 	WM_LBUTTONDBLCLK	0x0203	//マウス左ボタンをダブルクリック	 
#define 	WM_LBUTTONDOWN		0x0201	//マウス左ボタンを押し下げ	 
#define 	WM_LBUTTONUP		0x0202	//マウス左ボタンを離した	 
#define 	WM_MBUTTONDBLCLK	0x0209	//マウス中央ボタンをダブルクリック	 
#define 	WM_MBUTTONDOWN		0x0207	//マウス中央ボタンを押し下げ	 
#define 	WM_MBUTTONUP		0x0208	//マウス中央ボタンを離した 
#define 	WM_MOUSEMOVE		0x0200	//マウス移動時に実行 
#define 	WM_MOUSEHOVER		0x02A1	//マウスが一定時間同じ場所にある 
#define 	WM_MOUSELEAVE		0x02A3	//マウスがウィンドウ外にでる 
#define 	WM_MENUSELECT		0x011F	//メニューアイテムが選択された	 
#define 	WM_MOVE				0x0003	//ウィンドウの移動	 
#define 	WM_NOTIFY			0x004E	//コモンコントロールからの通知	 
#define 	WM_NULL				0x0000	//効果をもたないメッセージ	 
#define 	WM_PASTE			0x0302	//エディットコントロールのテキストの貼り付け	 
#define 	WM_RBUTTONDBLCLK	0x0204	//マウス右ボタンをダブルクリック	 
#define 	WM_RBUTTONDOWN		0x0205	//マウス右ボタンを押し下げ	 
#define 	WM_RBUTTONUP		0x0206	//マウス右ボタンを離した	 
#define 	WM_SETFONT			0x0030	//コントロールのフォントを設定  
#define 	WM_SETTEXT			0x000C	//ウィンドウタイトルやコントロールのテキストを設定  
#define 	WM_SIZE				0x0005	//ウィンドウサイズ変更	 
#define 	WM_SYSCOMMAND		0x0112	//システムメニューアイテム選択  
#define 	WM_UNDO				0x0304	//エディットコントロールの直前の操作を元に戻す	 
#define 	WM_USER				0x0400	//アプリケーション定義メッセージの先頭 
#define 	WM_PAINT			0x000F	//ウィンドウを書きなおすときに送られる 
#define 	WM_CLOSE			0x0010	//アプリケーション終了時に送られる 
#define 	WM_DESTROY			0x0002	//ウィンドウが破棄されたときに送られる 
#define 	WM_GETMINMAXINFO		0x0024	//ウィンドウのサイズが変更されようとしたときに送られる サイズ移動フラグ 
#define 	WM_SYSCOLORCHANGE		0x0015	//システムカラーが変更されたのを知らせる 
#define 	WM_ERASEBKGND		0x0014	//自動で背景を削除されないようにする 
#define 	WM_SHOWWINDOW           0x0018	//ウィンドウが表示されるかされないか 
#define  	WM_COPYDATA                     0x004A 
#define  WM_CANCELJOURNAL                0x004B 
#define  WM_SETFOCUS                     0x0007 
#define  WM_KILLFOCUS                    0x0008 
#define  WM_ENABLE                       0x000A 
#define  WM_QUERYENDSESSION              0x0011 
#define  WM_QUERYOPEN                    0x0013 
#define  WM_ENDSESSION                   0x0016 
#define  WM_QUIT                         0x0012 
#define  WM_WININICHANGE                 0x001A 
#define  WM_SETTINGCHANGE                WM_WININICHANGE 
#define  WM_DEVMODECHANGE                0x001B 
#define  WM_ACTIVATEAPP                  0x001C 
#define  WM_FONTCHANGE                   0x001D 
#define  WM_TIMECHANGE                   0x001E 
#define  WM_CANCELMODE                   0x001F 
#define  WM_SETCURSOR                    0x0020 
#define  WM_MOUSEACTIVATE                0x0021 
#define  WM_CHILDACTIVATE                0x0022 
#define  WM_QUEUESYNC                    0x0023 
#define  WM_PAINTICON                    0x0026 
#define  WM_ICONERASEBKGND               0x0027 
#define  WM_NEXTDLGCTL                   0x0028 
#define  WM_SPOOLERSTATUS                0x002A 
#define  WM_DRAWITEM                     0x002B 
#define  WM_MEASUREITEM                  0x002C 
#define  WM_DELETEITEM                   0x002D 
#define  WM_VKEYTOITEM                   0x002E 
#define  WM_CHARTOITEM                   0x002F 
#define  WM_SETHOTKEY                    0x0032 
#define  WM_GETHOTKEY                    0x0033 
#define  WM_QUERYDRAGICON                0x0037 
#define  WM_COMPAREITEM                  0x0039 
#define  WM_GETOBJECT                    0x003D 
#define  WM_COMPACTING                   0x0041 
#define  WM_COMMNOTIFY                   0x0044  /* no longer suported */ 
#define  WM_WINDOWPOSCHANGING            0x0046 
#define  WM_WINDOWPOSCHANGED             0x0047 
#define  WM_POWER                        0x0048 
#define  WM_MOUSEWHEEL					$0000020A 
#define  WM_HSCROLL						$00000114 
#define  WM_VSCROLL						$00000115 
#define  WM_TIMER							$00000113 
#define  WM_MOVING						 $00000216 

mod_wrun.hsp

注意:このソースコードには、シリルのページさんのページにある2重起動を防止する(HSP)を参考に作っています。謝意。
#module "mod_wrun" 
#uselib "kernel32.dll" 
#func CreateFileMapping "CreateFileMappingA" int,int,int,int,int,str 
#func MapViewOfFile "MapViewOfFile" int,int,int,int,int 
#func UnmapViewOfFile "UnmapViewOfFile" int 
#func CloseHandle "CloseHandle" int 
#func GetLastError "GetLastError" 
#func global GetModuleFileName "GetModuleFileNameA" sptr,sptr,sptr 
 
#uselib "user32.dll" 
#func SetActiveWindow "SetActiveWindow" int 
#func SetForegroundWindow "SetForegroundWindow" int 
 
#define FILE_MAP_WRITE $00000002 
#define FILE_MAP_READ $00000004 
#define PAGE_READWRITE $00000004 
#define ERROR_ALREADY_EXISTS $000000B7 
#define INVALID_HANDLE_VALUE $FFFFFFFF 
 
#define WM_ACTIVATE $00000006 
 
 
 
//複数起動を防止するためのマッピングオブジェクトを作成。 
//返り値	0 すでに起動されている。 
//			1 新規起動 
#defcfunc wrun 
sdim exename,260 
GetModuleFileName 0,varptr(exename),260 
CreateFileMapping INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 1, getpath(exename,8)+"Akicansoft" 
hObj = stat 
if hObj=0{ 
	dialog "共有メモリ作成エラー" 
} 
 
 
GetLastError 
 
 
if (stat == ERROR_ALREADY_EXISTS) { 
	// 既に同名のオブジェクトが存在している 
	//ウィンドウアクティブ 
	MapViewOfFile hObj,FILE_MAP_WRITE,0,0,0 
	pBaseAddress = stat 
	dupptr dp,pBaseAddress,4,4 
	hAppwnd = dp 
	UnmapViewOfFile pBaseAddress 
	SetForegroundWindow hAppwnd 
	return 0 
}else{ 
	// 同名オブジェクトが存在していない 
	// ウィンドウハンドルを書き込む 
	MapViewOfFile hObj,FILE_MAP_WRITE,0,0,0 
	pBaseAddress = stat 
	dupptr dp,pBaseAddress,4,4 
	dp = hwnd 
	UnmapViewOfFile pBaseAddress 
	return 1 
} 
 
 
 
#deffunc wrunend 
CloseHandle hObj 
return 
 
 
 
#global 
 
 
/* 
例 
 
if wrun()=0{ 
 
	end 
} 
 
onexit *@f 
 
 
stop 
 
 
*@ 
	wrunend 
	end 
 
*/ 

mod_ini.hsp

INIファイル制御をAPIを使用せずにモジュールで行っています。項目を指定しないで取得・設定を行うとセクションの全てを取得・設定してしまう変態機能もあります。
#module "mod_ini" 
 
//******************************************************************** 
//	ini操作関数群3 
// 
//  iniload "読み出すファイル名",共通変数	戻り値 = 文字数 
//		ファイルが存在しない場合0byteファイルを作成し-1を返します。 
//  inisave "書き込むファイル名",共通変数	戻り値 = 文字数 
//  取得した文字列 = inigetstr("セクション名","項目",共通変数) 
//		取得したい項目またはセクションが存在しなかった場合は""を返す 
//  取得した数値 = inigetint("セクション名","項目",共通変数) 
//		取得したい項目またはセクションが存在しなかった場合は0を返す 
//  inisetint 代入する値,"セクション名","項目",共通変数		戻り値 = 文字数 
//  inisetstr "代入する文字列","セクション名","項目",共通変数	戻り値 = 文字数 
//  inidel "セクション名","項目",共通変数	戻り値 = 成功フラグ 
//******************************************************************** 
#deffunc iniload str p1,var p2 
exist p1 
if strsize=-1{dm="" 
bsave p1,dm,0 
return -1}else{p2=str(p2) 
notesel p2 
exist p1 : sdim p2,strsize 
 noteload p1 
 
 }return strsize 
#deffunc inisave str p1,var p2 
notesel p2 
notesave p1 
return strlen(str(p2)) 
 
#defcfunc inigetstr str p1, str p2, var p3 
cc=0 
s3=0 
s2="" 
s4=0 
notesel p3 
repeat notemax 
noteget s1,cc 
if "["+p1=strmid(s1,0,1+strlen(p1)){ 
s6=cc 
repeat notemax 
cc+ 
noteget s1,cc 
if strmid(s1,0,1)="["{s3=1 
break}if p2!""{if strmid(s1,0,strlen(p2))=p2{ 
getstr s2,s1,strlen(p2) 
getstr s2,s2,1 
s3=1 
break}}else{if s1=""{if s4=0{s4=1 
s5=cc-1}}else{s4=0} 
s2+=s1+"\n"}loop 
if s4=1{notesel s2 
repeat notemax 
notedel s5-s6 
loop}}if s3=1{break}cc+ 
loop 
if p2=""{s2=strmid(s2,0,strlen(s2)-2)}return str(s2) 
 
#defcfunc inigetint str p1, str p2, var p3 
return int(inigetstr(p1,p2,p3)) 
 
#deffunc inidel str p1, str p2, var p3 
d6=1 
s6=0 
cc=0 
notesel p3 
repeat notemax 
noteget s1,cc 
if "["+p1 = strmid(s1,0,1+strlen(p1)){ 
gjcc=cc 
if p2=""{repeat notemax-gjcc 
notedel cc 
noteget s7,cc 
if "["=strmid(s7,0,1){d6=1 
s6=1 
break} 
loop}repeat notemax 
cc+ 
noteget s1,cc 
if (strmid(s1,0,strlen(p2))=p2)&(d6=0){notedel cc 
s6=1 
break}loop}if s6=1{break}cc+ 
loop 
return 
 
#deffunc inisetstr str p3,str p1, str p2, var p4 
s6=0 
cc=0 
ju=0 
sss=0 
add=0 
notesel p4 
repeat notemax 
noteget s1,cc 
if "["+p1=strmid(s1,0,1+strlen(p1)){ 
if cc+1=notemax{p4=p4+"\n"}decc=cc 
sss=1 
repeat notemax 
cc+ 
noteget s1,cc 
getstr gggg,s1,0,'=' 
if (gggg=p2)&(p2!""){noteadd str(p2)+"="+str(p3),cc+add,1 
s6=1 
break}if ("["=strmid(s1,0,1))|(notemax=cc){ 
add=-1 
noteget s1,cc-1 
if s1!""{noteadd "",cc,0 
add=0}if p2!""{noteadd str(p2)+"="+str(p3),cc+add,0}else{ 
repeat notemax-decc 
noteget s1,decc+2 
if "["=strmid(s1,0,1){break}notedel decc+1 
loop 
noteadd p3,decc+1,1} 
s6=1 
break}loop}if s6=1{break}cc+ 
loop 
if sss=0{cc=0 
repeat notemax 
noteget s1,cc 
if "["=strmid(s1,0,1){ju=1} 
loop 
if ju=0{noteadd "["+p1+"]",0,1 
if p2!""{noteadd ""+p2+"="+p3+"\n",1,1}else{noteadd ""+p3+"\n",1,1}} 
if ju=1{p4+="\n\n" 
noteget s1,notemax-3 
if s1!""{p4+="\n"}noteadd "["+p1+"]",notemax-2,1 
if p2!""{ 
noteadd ""+p2+"="+p3+"\n",notemax-1,1}else{noteadd ""+p3+"\n",notemax-1,1}}}return 
#deffunc inisetint int p3, str p1, str p2, var p4 
inisetstr str(p3),p1,p2,p4 
return 
 
 
#global 

mod_locksel.hsp

描画先ウィンドウを変更したあとに、もとの描画先ウィンドウに戻すための処理を関数化したものです。ウィンドウズメッセージの処理に利用しています。
#module "mod_locksel" 
 
 
//gselをロックしてgsel 0=ロック 1=開放 , 変更するウィンドウID 
#deffunc lockgsel int p1, int p2 
if ginfo_sel!p2{ 
	if p1=0{ 
		lock_gsel_id=ginfo_sel 
		gsel p2 
	}else{ 
		gsel lock_gsel_id 
	} 
} 
return 
 
 
#deffunc locksel_start int p1 
if length(lock_gsel_id)=1:dim lock_gsel_id,256 
lock_gsel_id(count)=ginfo_sel 
count+ 
gsel p1 
return 
 
 
 
#deffunc locksel_end 
count- 
if count<0:dialog "locksel_startがありません",1,"Error":end 
gsel lock_gsel_id(count) 
 
return 
 
 
#global 

mod_debug.hsp

デバッグ用モジュールです。debugという関数が定義されていますが、HSP3.1では”#ifdef _debug”という機能が追加されたので、この機能はあまり使っていません。
#module 
 
#defcfunc debug 
if hspstat=1:return 1:else:return 0 
 
#global