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