a2d+AlphaLayer.hsp

common\ a2d+AlphaLayer.hsp

//
//	a2d+AlphaLayer.hsp - ver.2.4									by MIZUSHIKI
//
#if __hspver__<=$3507
#packopt manifest "usedAlphaLayer.manifest" ;HSP3.5用(3.5.1では効果なし)
#ifdef _debug
#include "mod_regexp.as"
#endif
#endif

#include "a2d.hsp"
#include "modclbk3.hsp"	// コールバック関数用モジュール

#ifndef _init_@AlphaLayerMod

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	a2d+AlphaLayer を使用するための種々確認と処理(デバッグ時)
//		usedAlphaLayer.manifest,usedAlphaLayer.version(HSP3.51)の作成
//			・実行ファイル自動作成の際に利用します。
//			・HSP3.51では#packopt manifestだけでは書き換えが動作せず、version(もしくはicon)も#packoptしないといけない。(HSP3.5はOK)
//		hsptmp内に#packopt manifest,version があるか確認(HSP3.51)
//			・HSP3.51では#packoptがメインスクリプトにないと機能しないので無ければ書いてもらうように促す。
//		デバッグ実行ランタイム(hsp3.exe)のマニフェスト確認と改造
//			・マニフェストでWindows8をサポートしていることが明記されていないといけないので改造する。
//
//		※ HSP Ver.3.6β1以上を使用すればこれらは全て不要になります。
//		  デフォルトでマニフェストにWindows8(7/8/8.1/10)のサポートOS IDが付くようになりました。
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if __hspver__<$3601
#ifdef _debug
#if __hspver__<$3507
	dialog "HSP3.5以下だと標準機能でマニフェストの書き換えができないのでHSP3.5以上を使用してください。\n\n---\nおすすめはHSP3.6β1以上です。\nデバッグ実行ランタイム(hsp3.exe)の改造等が不要になります。",1,"a2d+AlphaLayer モジュール"
	end
#endif
;hsp3.exeに「windows8以降の機能に対応する」というマニフェストが付加されているか確認→置換処理→再起動促し
__manifest_kakunin__ ;
#endif
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	AlphaLayerモジュール本体
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#module AlphaLayerMod

#uselib "USER32.dll"
#func SetParent "SetParent" int,int
#func GetWindowLong "GetWindowLongA" int,int
#func SetWindowLong "SetWindowLongA" int,int,int
#cfunc GetDC "GetDC" sptr
#func ReleaseDC "ReleaseDC" sptr,sptr
#func UpdateLayeredWindow "UpdateLayeredWindow" int,int,int,int,int,int,int,int,int
#cfunc DefWindowProc "DefWindowProcA" int,int,int,int
#func SetWindowPos "SetWindowPos" sptr,sptr,sptr,sptr,sptr,sptr,sptr
#func SetActiveWindow "SetActiveWindow" int
#func GetWindowRect "GetWindowRect" int, int
#func ScreenToClient "ScreenToClient" int, int
#func GetParent "GetParent" int
#func FindWindowExA  "FindWindowExA" sptr,sptr,sptr,sptr
#func GetWindowRgnBox "GetWindowRgnBox" int,int
#func SetWindowRgn "SetWindowRgn" int,int,int
#func RegisterClassEx "RegisterClassExA" sptr
#func CreateWindowEx "CreateWindowExA" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#func DestroyWindow "DestroyWindow" sptr
#cfunc IsWindowVisible "IsWindowVisible" int
#func CallWindowProc "CallWindowProcA" sptr,sptr,sptr,sptr,sptr
#func CallWindowProcW "CallWindowProcW" wptr,wptr,wptr,wptr,wptr

#uselib "KERNEL32.dll"
#func GlobalAlloc "GlobalAlloc" sptr,sptr
#func GlobalFree "GlobalFree" sptr

#uselib "GDI32.dll"
#cfunc CreateCompatibleDC "CreateCompatibleDC" sptr
#cfunc CreateCompatibleBitmap "CreateCompatibleBitmap" sptr,sptr,sptr
#func SelectObject "SelectObject" sptr,sptr
#func DeleteDC "DeleteDC" sptr
#func StretchDIBits "StretchDIBits" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#func DeleteObject "DeleteObject" sptr
#func CreateRectRgn "CreateRectRgn" int,int,int,int
#func GetStockObject "GetStockObject" int
#uselib "gdiplus.dll"
#func GdipGetPropertyItemSize "GdipGetPropertyItemSize" int,int,int
#func GdipGetPropertyItem "GdipGetPropertyItem" int,int,int,int
#func GdipImageGetFrameDimensionsList "GdipImageGetFrameDimensionsList" int,int,int
#func GdipImageGetFrameCount "GdipImageGetFrameCount" int,int,int
#func GdipImageSelectActiveFrame "GdipImageSelectActiveFrame" int,int,int

#define WS_POPUP          0x80000000
#define WS_CHILD          0x40000000
#define WS_EX_LAYERED     0x00080000
#define ULW_COLORKEY      0x00000001
#define ULW_ALPHA         0x00000002
#define ULW_OPAQUE        0x00000004
#define ULW_EX_NORESIZE   0x00000008
#define AC_SRC_OVER       0x00000000
#define AC_SRC_ALPHA      0x00000001
#define CAPTUREBLT        0x40000000
#define GWL_STYLE         -16
#define GWL_EXSTYLE       -20	;拡張ウィンドウスタイル
#define WS_EX_TRANSPARENT $20	;マウスイベントの透過
#define DIB_RGB_COLORS    0x0
#define SRCCOPY           0x00CC0020
#define BI_RGB            0x0
#define WM_MOUSEACTIVATE  0x21
#define MA_NOACTIVATE     3

#define HWND_TOP 0	//Z オーダーの先頭
#define HWND_BOTTOM 1	//Z オーダーの最後
#define HWND_TOPMOST -1	//常に一番手前に表示される最前面ウィンドウにする
#define HWND_NOTOPMOST -2	//最前面ウィンドウ以外のすべてのウィンドウの前
#define SWP_NOSIZE 1	//サイズを変更しない
#define SWP_NOMOVE 2	//位置を変更しない
#define SWP_NOZORDER 4	//Zオーダーを変更しない
#define SWP_NOREDRAW 8	//変更に伴う再描画をしない
#define SWP_NOACTIVATE $10	//ウィンドウをアクティブにしない
#define SWP_FRAMECHANGED $20	//SetWindowLong関数を使用後に変更を適用
#define SWP_SHOWWINDOW $40	//ウィンドウを表示する
#define SWP_HIDEWINDOW $80	//ウィンドウを隠す
#define SWP_NOCOPYBITS $100	//クライアント領域の内容全体を破棄
#define SWP_NOOWNERZORDER $200	//オーナーウィンドウの Z オーダーを変更しない
#define SWP_NOSENDCHANGING $400	//WM_WINDOWPOSCHANGINGメッセージを送らない
#define SWP_DEFERERASE $2000	//WM_SYNCPAINTメッセージを送らない
#define SWP_ASYNCWINDOWPOS $4000	//非同期処理(?)
#define SWP_DRAWFRAME SWP_FRAMECHANGED
#define SWP_NOREPOSITION SWP_NOOWNERZORDER


#deffunc _init_@AlphaLayerMod
	dim rect, 4
	dim rgnRect,4
	winbmscr = 0
	hwnds = 0
	alphas = 0  ; UpdateLayeredWindowで指定したアルファ値を取得できる関数はないものか
	wintypes = 0
	_templabel = 0
	oldprocs = 0
	st = 0
	ctx = 0
	size = 0
	bitmapdata = 0
	tmpimage = 0
	guid = 0
	frames = 0
	nsizedelay = 0
	nsize = 0

	framess = 0
	loopCounts = 0
	lpDelay_GblAllocs = 0

	dummyVal = 0
	
	// BITMAPINFOHEADER構造体
	dim BITMAPINFOHEADER, 10
	BITMAPINFOHEADER(0) = 40				// biSize
	;BITMAPINFOHEADER(1) = biWidth			// biWidth
	;BITMAPINFOHEADER(2) = biHeight			// biHeight
	BITMAPINFOHEADER(3) = 1 | (32 << 16)	// biPlanes & biBitCount
	BITMAPINFOHEADER(4) = BI_RGB			// biCompression
	// BITMAPINFO構造体
	dim BITMAPINFO, 2
	BITMAPINFO(0) = varptr(BITMAPINFOHEADER)	//メンバをもつ
	// psize
	dim psize,2
	;psize(0) = biWidth
	;psize(1) = biHeight
	// pptSrc
	dim pptSrc,2
	pptSrc(0) = 0
	pptSrc(1) = 0
	// pblend
	sdim pblend, 4
	poke pblend, 0, AC_SRC_OVER
	poke pblend, 1, 0
	poke pblend, 2, 255
	poke pblend, 3, AC_SRC_ALPHA

	//コールバック用
	ldim labels,1
	
	_dummyLabel_ = *__dummy__@AlphaLayerMod
	
	//ダミーの関数を定義
	newclbk3 Proc, 4, *WndProc@AlphaLayerMod

	//-ウィンドウクラスの登録-----------------------------------------------------------//
	ClassName = "alalLayer"
	GetStockObject 2
	hBrush = stat

	dim wcex, 12
	wcex.0 = 48
	wcex.1 = 0
	wcex.2 = Proc
	wcex.3 = 0
	wcex.4 = 0
	wcex.5 = 0;g_hInstance
	wcex.6 = 0;hIcon
	wcex.7 = 0;hCursor
	wcex.8 = hBrush
	wcex.9 = 0
	wcex.10= varptr(ClassName)
	wcex.11= 0;hIcon
	
	RegisterClassEx varptr(wcex)
	//----------------------------------------------------------------------------------//
	return
*WndProc@AlphaLayerMod
	return
	
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Artlet2D に機能を追加
//
#const	PixelFormat32bppPARGB $E200B

#deffunc alGetBitmapPVData_start var ps, var pv ; size, vvar
	if imgValid@a2d {
		if imgValid@a2d ! 3 : frames = 1 : else : frames = framess(imgID@a2d)
		; LockBits して bitmap image へのポインタを得る
		rect@a2d = 0, 0, imgWidth@a2d, imgHeight@a2d * frames
		dim BitmapData@a2d, 8
		GdipBitmapLockBits@a2d imgImage@a2d, varptr(rect@a2d), 1, PixelFormat32bppPARGB, varptr(BitmapData@a2d)
		;GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
		ps = BitmapData@a2d(0) * BitmapData@a2d(1) * 4  ; Width * Height * ByPP
		if BitmapData@a2d(4)==0 || ps==0 {
			GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
			return -1
		}
		dupptr pv, BitmapData@a2d(4), ps
		;開いたままにして
		return 0
	}
	return -1
#deffunc alGetBitmapPVData_end
	if imgValid@a2d {
		GdipBitmapUnlockBits@a2d imgImage@a2d, varptr(BitmapData@a2d)
		;閉じる
		return 0
	}
	return -1
	
#defcfunc alGetFramesCount
	if imgValid@a2d = 3 {
		if length(framess) <= imgID@a2d :return 1
		return framess(imgID@a2d)
	}
	return 1
#defcfunc alGetLoopCount
	if imgValid@a2d = 3 {
		if length(loopCounts) <= imgID@a2d : return -1
		return loopCounts(imgID@a2d)
	}
	return -1
#deffunc alGetFramesDelay array dlys
	if imgValid@a2d = 3 {
		dim dlys,1
		if length(framess) <= imgID@a2d : return 0
		if framess(imgID@a2d) == 0 : return 0
		if length(lpDelay_GblAllocs) <= imgID@a2d : return 0
		if lpDelay_GblAllocs(imgID@a2d) == 0 : return 0

		dim dlys, framess(imgID@a2d)

		dupptr hMem, lpDelay_GblAllocs(imgID@a2d), framess(imgID@a2d)*4, 4
		repeat framess(imgID@a2d)
			dlys(cnt) = hMem(cnt)  ; ミリ秒単位。GIFは10ミリ秒単位だけどロード時に10倍している
		loop

		return framess(imgID@a2d)
	}
	return 0
;-----------------------------------------------------------
#define global alCreateImageByAnimationFile(%1,%2,%3=1,%4=0,%5=dummyVal@AlphaLayerMod) _alCreateImageByAnimationFile@AlphaLayerMod %1,%2,%3,%4,%5
#deffunc _alCreateImageByAnimationFile@AlphaLayerMod int p1, str p2, int p3, int p4, array p5  ; ID, filename, divFrame, divLoopCount, (divDelay)

	alInitModule
	if gdiplusToken@a2d {
		divFrame = p3 : if divFrame < 1 : divFrame = 1
		
		GdipLoadImageFromFile@a2d p2, varptr(tmpImage); ファイルから読み込み
		if( tmpImage == 0 ): return -1
		
		GdipGetImageWidth@a2d  tmpImage, varptr(w@a2d)
		GdipGetImageHeight@a2d tmpImage, varptr(h@a2d)
	
		GdipImageGetFrameDimensionsList tmpImage , varptr(guid) , 1;最初のディメンションのGUIDを取得
		GdipImageGetFrameCount tmpImage , varptr(guid) , varptr(frames);フレーム数を取得
		
		GdipGetPropertyItemSize tmpImage ,  0x5100 , varptr(nSizeDelay);ディレイを格納するサイズを取得
		sdim Delay , nSizeDelay
		GdipGetPropertyItem tmpImage ,  0x5100 , nSizeDelay , varptr(Delay);ディレイを取得
		GdipGetPropertyItemSize tmpImage , 0x5101 , varptr(nSize);ループ数を格納するサイズを取得
		sdim loopCount_ , nSize
		GdipGetPropertyItem tmpImage , 0x5101 , nSize , varptr(loopCount_);ループ数を取得
		loopCount = wpeek(loopCount_,16)
		//alCreateImage p1, w@a2d, h@a2d * frames	; 強制的に 32bpp にするために 2 pass でロード
		; 有効化
		alDeleteImage p1, 1	; Image ID 削除
		imgValidArr@a2d(p1) = 3 - 2*(frames<=1) ; Image ID を有効化
		alSelectImage p1	; 選択 (dup-context change)

		; プロパティ 設定
		imgWidth@a2d  = w@a2d
		imgHeight@a2d = h@a2d
		framess(p1) = frames
		loopCounts(p1) = loopCount
		if length(lpDelay_GblAllocs) > p1 : if lpDelay_GblAllocs(p1) != 0 : GlobalFree lpDelay_GblAllocs(p1) : lpDelay_GblAllocs(p1) = 0
		if frames > 1 {
			lpDelay_GblAllocs(p1) = GlobalAlloc( $0/*GMEM_FIXED*/, nSizeDelay)
			dupptr hMem, lpDelay_GblAllocs(p1), nSizeDelay, 4
			memcpy hMem, Delay, nSizeDelay-16, 0, 16
			repeat nSizeDelay/4
				hMem(cnt) *= 10  ; GIFは10ミリ秒単位なのでここで10倍してしまう
			loop
			
		}else : if divFrame > 1 {
			frames = 1
			// pngとかでも分割指定があるときは縦画像をp3コマで割ってアニメーションとする
			imgValidArr@a2d(p1) = 3
			imgHeight@a2d = h@a2d / divFrame
			framess(p1) = divFrame
			loopCounts(p1) = p4
			
			lpDelay_GblAllocs(p1) = GlobalAlloc( $0/*GMEM_FIXED*/, divFrame*4)
			dupptr hMem, lpDelay_GblAllocs(p1), divFrame*4, 4
			dim dummyVal,1 : dummyVal = 100  ; デフォルト100ms
			repeat divFrame
				if length(p5) > cnt : last = p5(cnt)
				hMem(cnt) = last
			loop
		}

		; オフスクリーンバッファ Image / Graphics 作成
		GdipCreateBitmapFromScan0@a2d w@a2d, h@a2d*(frames), 0, PixelFormat32bppARGB@a2d, 0, varptr(imgImage@a2d)
		GdipGetImageGraphicsContext@a2d imgImage@a2d, varptr(imgGraphics@a2d)

		; デフォルト Brush / Pen 作成
		GdipCreateSolidFill@a2d 0xff000000, varptr(imgBrush@a2d)
		GdipCreatePen2@a2d imgBrush@a2d, 1, UnitPixel@a2d, varptr(imgPen@a2d) ; (default PenWidth = 1px)

		; Graphics 高画質モードに設定
		GdipSetSmoothingMode@a2d imgGraphics@a2d, 2	; SmoothingModeHighQuality = QualityModeHigh
		GdipSetPixelOffsetMode@a2d imgGraphics@a2d, 2	; PixelOffsetModeHighQuality = QualityModeHigh
		GdipSetTextRenderingHint@a2d imgGraphics@a2d, 4	; TextRenderingHintAntiAlias
	;	GdipSetCompositingQuality imgGraphics, 2 ; CompositingQualityHighQuality = QualityModeHigh
		
		repeat frames
			GdipImageSelectActiveFrame tmpImage , varptr(guid) , cnt;アクティヴなフレームを選択
			GdipDrawImageRectRectI@a2d imgGraphics@a2d, tmpImage, 0, h@a2d * cnt, w@a2d, h@a2d, 0, 0, w@a2d, h@a2d, UnitPixel@a2d, 0, 0, 0
		loop
	

		GdipDisposeImage@a2d tmpImage
		tmpImage = 0
		return 0
	}
	return -1

;-----------------------------------------------------------
#deffunc setAcitiDfp6 int p1, int p2
	dfp6 = p1
	if p1 = 9999 : dfp6 = imgHeightArr@a2d(p2)
	return
#deffunc setAcitiDfp6_2 int p1, int p2, int p3
	dfp6 = p1
	if p1 = 9999 {
		dfp6 = imgHeightArr@a2d(p2)
		if dfp6 > imgHeightArr@a2d(p3) : dfp6 = imgHeightArr@a2d(p3)
	}
	return
;-----------------------------------------------------------
; Copy (prm : srcID, destID, destX, destY, width, height, srcX, srcY)
#undef alCopyImageToImage
#undef alCopyImageToScreen
#undef alCopyScreenToImage
#define global alCopyImageToImage(%1=0, %2=0, %3=0, %4=0, %5=9999, %6=9999, %7=0, %8=0)		setAcitiDfp6_2 %6,%1,%2 :alStretchImageToImage %1, %2, %7, %8, %5, dfp6@AlphaLayerMod, %3, %4, %5, dfp6@AlphaLayerMod
#define global alCopyImageToScreen(%1=0, %2=0, %3=0, %4=0, %5=9999, %6=9999, %7=0, %8=0)	setAcitiDfp6 %6,%1 :alStretchImageToScreen %1, %2, %7, %8, %5, dfp6@AlphaLayerMod, %3, %4, %5, dfp6@AlphaLayerMod
#define global alCopyScreenToImage(%1=0, %2=0, %3=0, %4=0, %5=9999, %6=9999, %7=0, %8=0)	setAcitiDfp6 %6,%2 :alStretchScreenToImage %1, %2, %7, %8, %5, dfp6@AlphaLayerMod, %3, %4, %5, dfp6@AlphaLayerMod

;-----------------------------------------------------------
//↓これでは消せないことが分かった(@AlphaLayerMod内で#undefしても@a2dモジュール内で使われるalCreateImageは何故か@a2d内で生き残っていてそちらが使われる)
;#undef alCreateImage
;#define global alCreateImage(%1=0, %2=640, %3=480)	framess@AlphaLayerMod(%1)=1:alCreateImage_ %1, %2, %3
// imgValidArr@a2d = 3 を記憶することで差別化
// Artlet2D に機能を追加
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	
// ウィンドウにアルファレイヤーを追加する
#define global alalSetParent(%1,%2=-1,%3=0,%4=0,%5=0,%6=_dummyLabel_@AlphaLayerMod) _alalSetParent@AlphaLayerMod %1,%2,%3,%4,%5,%6
#deffunc _alalSetParent@AlphaLayerMod int imageID, int haritukeID,  int hide, int posX, int posY, label clbkLabel

	if imageID == haritukeID : return
	if haritukeID < 0 {
		//p2省略時:描画先ウィンドウ
		mref winBMSCR, 96+ginfo_sel
		haritukeHWND = winBMSCR(13)
	}else :if length(hwnds)>haritukeID {
		//p2 ID:既存アルファレイヤーの子レイヤーにする
		if hwnds(haritukeID) != 0 : haritukeHWND = hwnds(haritukeID) :else : return
	}else :if haritukeID < IMGS_MAX@a2d {
		//上で引っかからなかったけど512未満なのは何かの間違いだから戻る
		return
	}else {
		//p2 ID以上の数値:ウィンドウハンドルと想定する
		haritukeHWND = haritukeID
	}
	
	if imageID<IMGS_MAX@a2d {
		if imgValidArr@a2d(imageID) = 0 : return
	}

	if length(hwnds)>imageID {
		if hwnds(imageID) != 0 && wintypes(imageID) == 0 : DestroyWindow hwnds(imageID)
	}

	if imageID<IMGS_MAX@a2d {
		mae_imageID = alGetID()
		alSelectImage imageID
	}
	sxs(imageID) = alGetWidth()
	sys(imageID) = alGetHeight()
	CreateWindowEx WS_EX_LAYERED|WS_EX_TRANSPARENT, "alalLayer", "{imageID:"+imageID+"}", 0x86000000, posX, posY, alGetWidth(), alGetHeight(), 0, 0, 0/*g_Instance*/, 0
	alalLayerHwnd = stat
	if imageID<IMGS_MAX@a2d {
		alSelectImage mae_imageID
	}
	hwnds(imageID) = alalLayerHwnd
	alphas(imageID) = 255
	wintypes(imageID) = 0  ; hwnds増えるとき必ず一緒に

	GetWindowLong alalLayerHwnd, GWL_STYLE
	SetWindowLong alalLayerHwnd, GWL_STYLE, stat|WS_CHILD|WS_POPUP^WS_POPUP
	SetParent alalLayerHwnd, haritukeHWND

	if imageID<IMGS_MAX@a2d {
		_alalRedraw imageID, -1 ; ImageID → AlphaLayer に内容をコピー
	}else {
		_alalRedraw imageID, alGetID() ; カレントImageID → AlphaLayer に内容をコピー
	}
	alalShow imageID				; ・何故かWindows 10 May 2020 Update(Ver.20H1)のアプデ辺りから、一度 WS_VISIBLE にしてから ~WS_VISIBLE しないと表示されてしまう。
									;  しかも、~WS_VISIBLE で作成したけど見えてしまっているこの状態は、IsWindowVisible()辺りでは非表示状態であると認識してしまう。何故。
	if hide == 1 : alalHide imageID	; ・その関係なのか[孫レイヤー]を作りたい場合は、一度[子レイヤー]を表示状態のまま作り、[孫レイヤー]を全て貼り付けた後に alalHide() で[子レイヤー]を非表示にするという処置を行う必要がある。

	clbkLabel_ = clbkLabel
	if lpeek(clbkLabel_,0) != lpeek(_dummyLabel_,0) : _setClbk@AlphaLayerMod imageID, clbkLabel
	
	return alalLayerHwnd


// 透過ウィンドウを作る
#define global alalWindow(%1,%2,%3=0,%4=0,%5=0) _alalWindow@AlphaLayerMod %1,%2,%3,%4,%5
#deffunc _alalWindow@AlphaLayerMod int imageID, int windowID,  int p3, int posX, int posY

	if imageID<IMGS_MAX@a2d {
		if imgValidArr@a2d(imageID) = 0 : return
	}
	
	if length(hwnds)>imageID {
		if hwnds(imageID) != 0 && wintypes(imageID) == 0 : DestroyWindow hwnds(imageID)
	}
	
	if imageID<IMGS_MAX@a2d {
		mae_imageID = alGetID()
		alSelectImage imageID
	}
	
	sxs(imageID) = alGetWidth()
	sys(imageID) = alGetHeight()
	
	bgscr windowID, alGetWidth(), alGetHeight(), screen_hide, posX, posY
	alalLayerHwnd = hwnd
	hwnds(imageID) = alalLayerHwnd
	alphas(imageID) = 255
	wintypes(imageID) = 1  ; hwnds増えるとき必ず一緒に
	
	SetWindowLong alalLayerHwnd, GWL_EXSTYLE, GetWindowLong(alalLayerHwnd, GWL_EXSTYLE) | WS_EX_LAYERED
	if (p3 & 2) {
		oncmd gosub *NCHITTEST@AlphaLayerMod, 0x0084/*WM_NCHITTEST*/
	}
	if (p3 & 4) {
		alalWindow_SetTransparent imageID, 1
	}
	
	if imageID<IMGS_MAX@a2d {
		alSelectImage mae_imageID
	}
	

	if imageID<IMGS_MAX@a2d {
		_alalRedraw imageID, -1 ; ImageID → AlphaLayer に内容をコピー
	}else {
		_alalRedraw imageID, alGetID() ; カレントImageID → AlphaLayer に内容をコピー
	}
	
	if (p3 & 1) == 0 : alalShow imageID
	
	return alalLayerHwnd
	
*NCHITTEST@AlphaLayerMod
	mref bmscr, 96 + ginfo_intid
	//既定のプロシージャを呼び出して
	ret = DefWindowProc( bmscr(13), 0x0084/*WM_NCHITTEST*/, wparam, lparam )
	if ret == 1/*HTCLIENT*/ {
		//マウスがクライアント内にあるときタイトルバー上にあると見せかける
		return 2/*HTCAPTION*/
	}
	return ret

#deffunc alalWindow_SetTransparent int imageID, int p2
	if length(hwnds)<=imageID :return
	if p2 == 0 {
		SetWindowLong hwnds(imageID), GWL_EXSTYLE, GetWindowLong(hwnds(imageID), GWL_EXSTYLE) | WS_EX_TRANSPARENT ^ WS_EX_TRANSPARENT
	}else {
		SetWindowLong hwnds(imageID), GWL_EXSTYLE, GetWindowLong(hwnds(imageID), GWL_EXSTYLE) | WS_EX_TRANSPARENT
	}
	return

;コールバックをセットする
#define global alalCallback(%1,%2=0) _tempLabel@AlphaLayerMod=%2: _whichClbk@AlphaLayerMod %1

#deffunc _whichClbk@AlphaLayerMod int imageID

	if vartype(_tempLabel)==1 {
		//セット
		_setClbk@AlphaLayerMod imageID, _tempLabel
	}else {
		if _tempLabel == 0 {
			//解除
			_unsetClbk@AlphaLayerMod imageID
		}else {
			//再開
			if length(labels)<=imageID :return
			if lpeek(labels(imageID),0) == 0 :return
			_setClbk@AlphaLayerMod imageID, labels(imageID)
		}
	}
	return

#deffunc _setClbk@AlphaLayerMod int imageID, label clbkLabel
	if length(hwnds)<=imageID :return
	labels(imageID) = clbkLabel
	
	_flg_=0
	if length(oldprocs)>imageID {
		if oldprocs(imageID) != 0 {
			_flg_ = 1
		}
	}
	if _flg_==0 {
		GetWindowLong hwnds(imageID), -4;	// ウィンドウプロシージャのアドレス取得
		oldprocs(imageID) = stat
	}
	newclbk3 newproc, 4, *clbk@AlphaLayerMod;
	SetWindowLong hwnds(imageID), -4, newproc;		// ウィンドウプロシージャの書き換え
	
	GetWindowLong hwnds(imageID), GWL_EXSTYLE
	SetWindowLong hwnds(imageID), GWL_EXSTYLE, stat | WS_EX_TRANSPARENT ^ WS_EX_TRANSPARENT

	return
;コールバックを解除
#deffunc _unsetClbk@AlphaLayerMod int imageID
	if length(hwnds)<=imageID :return
	
	if length(oldprocs)>imageID {
		if oldprocs(imageID) != 0 {
			SetWindowLong hwnds(imageID), -4, oldprocs(imageID);		// ウィンドウプロシージャの書き換え
			oldprocs(imageID) = 0
		}
	}
	GetWindowLong hwnds(imageID), GWL_EXSTYLE
	SetWindowLong hwnds(imageID), GWL_EXSTYLE, stat | WS_EX_TRANSPARENT
	return
#deffunc _AllUnsetCallbackAlphaLayer //_deinit_で呼び出し
	foreach oldprocs
		if oldprocs(cnt)!=0 {
			SetWindowLong hwnds(cnt), -4, oldprocs(cnt);		// ウィンドウプロシージャの書き換え
			oldprocs(cnt) = 0
		}
	loop
	return

*clbk@AlphaLayerMod
		dupptr msg, lparam, wparam*4, 4
		
		_imageID = -1
		foreach hwnds
			if msg(0) == hwnds(cnt) : _imageID = cnt :break
		loop
		if _imageID == -1 {
			return  DefWindowProc(msg(0), msg(1), msg(2), msg(3));
		}
		
		if length(oldprocs)>_imageID {
			if oldprocs(_imageID) != 0 {
				mref st,64
				st = msg(0)
				mref ctx,68
				ctx(8)  = msg(1);iParam
				ctx(9)  = msg(2) ;wParam
				ctx(10) = msg(3) ;lParam
				ctx(201)= _imageID;hspctx.intwnd_id
				gosub labels(_imageID)
			}
			if stat == -1 {
				// 通常通り
				return CallWindowProc(oldprocs(_imageID), msg(0), msg(1), msg(2), msg(3));
			}
		}
		// メッセージをスルー
		return  DefWindowProc(msg(0), msg(1), msg(2), msg(3));
		
	return

#define global alalRedraw(%1,%2=-1,%3=0) _alalRedraw %1,%2,%3
#deffunc _alalRedraw int imageID, int _setImageID, int pp3 //, local hdc_, local hMemDC, local hBitmap
	if length(hwnds)<=imageID :return

	setImageID = imageID
	if _setImageID >= 0 : setImageID = _setImageID // alalSetParentで512より大きい数値を指定していたらimageIDに囚われなくてすむ。第2引数のimageをセットする。

	al_ID = alGetID()
	alSelectImage setImageID

	alGetBitmapPVData_start size, bitmapdata
	if stat==-1 {
		alSelectImage al_ID
		return
	}
	al_width = alGetWidth()
	al_height = alGetHeight()
	

/* _init_で定義
	if BITMAPINFOHEADER == 0 {
		// BITMAPINFOHEADER構造体
		dim BITMAPINFOHEADER, 10
		BITMAPINFOHEADER(0) = 40				// biSize
		;BITMAPINFOHEADER(1) = biWidth			// biWidth
		;BITMAPINFOHEADER(2) = biHeight			// biHeight
		BITMAPINFOHEADER(3) = 1 | (32 << 16)	// biPlanes & biBitCount
		BITMAPINFOHEADER(4) = BI_RGB			// biCompression
		// BITMAPINFO構造体
		dim BITMAPINFO, 2
		BITMAPINFO(0) = varptr(BITMAPINFOHEADER)	//メンバをもつ
		// psize
		dim psize,2
		;psize(0) = biWidth
		;psize(1) = biHeight
		// pptSrc
		dim pptSrc,2
		pptSrc(0) = 0
		pptSrc(1) = 0
		// pblend
		sdim pblend, 4
		poke pblend, 0, AC_SRC_OVER
		poke pblend, 1, 0
		poke pblend, 2, 255
		poke pblend, 3, AC_SRC_ALPHA
	}
*/
	biWidth  = sxs(imageID)	//ginfo_sx
	biHeight = sys(imageID)	//ginfo_sy

	if imgValidArr@a2d(setImageID) ! 3 : frames = 1 : else : frames = framess(setImageID)
	
	BITMAPINFOHEADER(1) = biWidth			// biWidth
	BITMAPINFOHEADER(2) = biHeight*frames	// biHeight
	psize(0) = biWidth
	psize(1) = biHeight
	poke pblend, 2, alphas(imageID)
	

	hdc_    = GetDC( hwnds(imageID) )
	hMemDC  = CreateCompatibleDC(hdc_)
	hBitmap = CreateCompatibleBitmap(hdc_, biWidth, biHeight)
	ReleaseDC hwnds(imageID), hdc_
	SelectObject hMemDC, hBitmap
	StretchDIBits hMemDC, 0, 0, biWidth, biHeight, 0, al_height*(pp3+1) +1, al_width, -al_height, varptr(bitmapdata), BITMAPINFO, DIB_RGB_COLORS, SRCCOPY
	hdc_ = GetDC( hwnds(imageID) )
	UpdateLayeredWindow hwnds(imageID), hdc_, 0, varptr(psize), hMemDC, varptr(pptSrc), 0, varptr(pblend), ULW_ALPHA	//layerBMSCR.4 == hdc
	ReleaseDC hwnds(imageID), hdc_
	DeleteDC hMemDC
	DeleteObject hBitmap //更新

	alGetBitmapPVData_end
	alSelectImage al_ID
	return

#deffunc alalAlpha int imageID, int bAlpha
	if length(hwnds)<=imageID :return
	poke pblend, 2, bAlpha
	UpdateLayeredWindow hwnds(imageID), 0, 0, 0, 0, 0, 0, varptr(pblend), ULW_ALPHA
	alphas(imageID) = bAlpha
	return

#deffunc alalShow int imageID
	if length(hwnds)<=imageID :return
	SetWindowPos hwnds(imageID), 0, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW
	return
#defcfunc alalIsShown int imageID
	if length(hwnds)<=imageID :return 0
	return IsWindowVisible( hwnds(imageID) )
	
#deffunc alalHide int imageID
	if length(hwnds)<=imageID :return
	SetWindowPos hwnds(imageID), 0, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW
	return

#define global alalGetRect(%1=-1,%2,%3=-2147483648) _getRect@AlphaLayerMod %1,%2,%3
#deffunc _getRect@AlphaLayerMod int imageID, array _rect, int scID
	if length(hwnds)<=imageID :return
	dim _rect,4
	_hwnd = hwnd
	if imageID >= 0 : _hwnd = hwnds(imageID)
	GetWindowRect _hwnd, varptr(_rect)
	GetWindowRgnBox _hwnd, varptr(rgnRect)
	if stat == 0 : rgnRect = 0,0, _rect(2)-_rect(0), _rect(3)-_rect(1)

	_rect(2) = _rect(0)+rgnRect(2), _rect(1)+rgnRect(3)
	_rect(0) = _rect(0)+rgnRect(0), _rect(1)+rgnRect(1) 

	if scID == -2147483648 {
		GetParent _hwnd : _hwnd = stat
	}else :if scID >= 0 {
		if length(hwnds)<=scID :return
		_hwnd = hwnds(scID)
	}else {
		return ;スクリーン座標を返す
	}
	
	size = _rect(2)-_rect(0),_rect(3)-_rect(1)
	if _hwnd!0 : ScreenToClient _hwnd, varptr(_rect) : _rect(2) = _rect(0)+size(0), _rect(1)+size(1)
	return


#define global alalWidth(%1=-1,%2=-2147483648,%3=-2147483648,%4=-2147483648,%5=-2147483648,%6=0) _width@AlphaLayerMod %1,%2,%3,%4,%5,%6
#define defGetWindowRect(%1,%2) GetWindowRect %1, varptr(%2) : size = %2(2)-%2(0),%2(3)-%2(1) : GetParent %1 : if stat!0 : ScreenToClient stat, varptr(%2) : %2(2) = %2(0)+size(0), %2(1)+size(1)
#deffunc _width@AlphaLayerMod int imageID, int w, int h, int x, int y, int type
	_w=w : _h=h : _x=x : _y=y
	rgnflg = 1

	_hwnd = hwnd
	scMaxSizeX = ginfo_sx
	scMaxSizeY = ginfo_sy
	if imageID >= 0 : _hwnd = hwnds(imageID) : scMaxSizeX = sxs(imageID) : scMaxSizeY = sys(imageID)
	
	defGetWindowRect _hwnd, rect
	GetWindowRgnBox _hwnd, varptr(rgnRect)
	if stat <= 1 : rgnRect = 0,0, rect(2)-rect(0), rect(3)-rect(1) : rgnflg=0
	mae_rgnRect = rgnRect(0),rgnRect(1),rgnRect(2),rgnRect(3)
	
	//サイズ_w,_h
	if _w==-2147483648 : _w = rgnRect(2)-rgnRect(0) :else :if _w<0 :_w=0
	if _h==-2147483648 : _h = rgnRect(3)-rgnRect(1) :else :if _h<0 :_h=0
	
	//基準点_x,_y
	if _x==-2147483648 {
		switch(type)
			case 1
				_x = rect(0) + rgnRect(2)
				swbreak
			case 2
				_x = rect(0) + rgnRect(2)
				swbreak
			case 3
				_x = rect(0) + rgnRect(0)
				swbreak
			case 4
				_x = rect(0) + rgnRect(0) + (rgnRect(2)-rgnRect(0))/2
				swbreak
			case 5
				_x = rect(0) + rgnRect(0) + (rgnRect(2)-rgnRect(0))/2
				swbreak
			case 6
				_x = rect(0) + rgnRect(2)
				swbreak
			case 7
				_x = rect(0) + rgnRect(0) + (rgnRect(2)-rgnRect(0))/2
				swbreak
			case 8
				_x = rect(0) + rgnRect(0)
				swbreak
			default
				_x = rect(0) + rgnRect(0)
		swend
	}
	if _y==-2147483648  {
		switch(type)
			case 1
				_y = rect(1) + rgnRect(1)
				swbreak
			case 2
				_y = rect(1) + rgnRect(3)
				swbreak
			case 3
				_y = rect(1) + rgnRect(3)
				swbreak
			case 4
				_y = rect(1) + rgnRect(1) + (rgnRect(3)-rgnRect(1))/2
				swbreak
			case 5
				_y = rect(1) + rgnRect(1)
				swbreak
			case 6
				_y = rect(1) + rgnRect(1) + (rgnRect(3)-rgnRect(1))/2
				swbreak
			case 7
				_y = rect(1) + rgnRect(3)
				swbreak
			case 8
				_y = rect(1) + rgnRect(1) + (rgnRect(3)-rgnRect(1))/2
				swbreak
			default
				_y = rect(1) + rgnRect(1)
		swend
	}
	
	//基準点からサイズを修正する
	switch(type)
		case 1 :
			rgnRect(0) = rgnRect(2) - _w : if rgnRect(0) < 0			: rgnRect(0) = 0
			;rgnRect(1) = rgnRect(1)
			;rgnRect(2) = rgnRect(2)
			rgnRect(3) = rgnRect(1) + _h : if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
			swbreak
		case 2 :
			rgnRect(0) = rgnRect(2) - _w : if rgnRect(0) < 0 			: rgnRect(0) = 0
			rgnRect(1) = rgnRect(3) - _h : if rgnRect(1) < 0 			: rgnRect(1) = 0
			;rgnRect(2) = rgnRect(2)
			;rgnRect(3) = rgnRect(3)
			swbreak
		case 3 :
			;rgnRect(0) = rgnRect(0)
			rgnRect(1) = rgnRect(3) - _h : if rgnRect(1) < 0 			: rgnRect(1) = 0
			rgnRect(2) = rgnRect(0) + _w : if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			;rgnRect(3) = rgnRect(3)
			swbreak
		case 4 :
			rgnRect(0) = mae_rgnRect(0) + (mae_rgnRect(2)-mae_rgnRect(0))/2 - _w/2	: if rgnRect(0) < 0 			: rgnRect(0) = 0
			rgnRect(1) = mae_rgnRect(1) + (mae_rgnRect(3)-mae_rgnRect(1))/2 - _h/2	: if rgnRect(1) < 0 			: rgnRect(1) = 0
			rgnRect(2) = mae_rgnRect(2) - (mae_rgnRect(2)-mae_rgnRect(0))/2 + _w/2	: if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			rgnRect(3) = mae_rgnRect(3) - (mae_rgnRect(3)-mae_rgnRect(1))/2 + _h/2	: if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
			swbreak
		case 5 :
			rgnRect(0) = mae_rgnRect(0) + (mae_rgnRect(2)-mae_rgnRect(0))/2 - _w/2	: if rgnRect(0) < 0 			: rgnRect(0) = 0
			;rgnRect(1) = rgnRect(1)
			rgnRect(2) = mae_rgnRect(2) - (mae_rgnRect(2)-mae_rgnRect(0))/2 + _w/2	: if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			rgnRect(3) = rgnRect(1) + _h : if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
			swbreak
		case 6 :
			rgnRect(0) = rgnRect(2) - _w : if rgnRect(0) < 0			: rgnRect(0) = 0
			rgnRect(1) = mae_rgnRect(1) + (mae_rgnRect(3)-mae_rgnRect(1))/2 - _h/2	: if rgnRect(1) < 0 			: rgnRect(1) = 0
			;rgnRect(2) = rgnRect(2)
			rgnRect(3) = mae_rgnRect(3) - (mae_rgnRect(3)-mae_rgnRect(1))/2 + _h/2	: if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
			swbreak
		case 7 :
			rgnRect(0) = mae_rgnRect(0) + (mae_rgnRect(2)-mae_rgnRect(0))/2 - _w/2	: if rgnRect(0) < 0 			: rgnRect(0) = 0
			rgnRect(1) = rgnRect(3) - _h : if rgnRect(1) < 0 			: rgnRect(1) = 0
			rgnRect(2) = mae_rgnRect(2) - (mae_rgnRect(2)-mae_rgnRect(0))/2 + _w/2	: if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			;rgnRect(3) = rgnRect(3)
			swbreak
		case 8 :
			;rgnRect(0) = rgnRect(0)
			rgnRect(1) = mae_rgnRect(1) + (mae_rgnRect(3)-mae_rgnRect(1))/2 - _h/2	: if rgnRect(1) < 0 			: rgnRect(1) = 0
			rgnRect(2) = rgnRect(0) + _w : if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			rgnRect(3) = mae_rgnRect(3) - (mae_rgnRect(3)-mae_rgnRect(1))/2 + _h/2	: if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
			swbreak
		default
			;rgnRect(0) = rgnRect(0)
			;rgnRect(1) = rgnRect(1)
			rgnRect(2) = rgnRect(0) + _w : if rgnRect(2) > scMaxSizeX	: rgnRect(2) = scMaxSizeX
			rgnRect(3) = rgnRect(1) + _h : if rgnRect(3) > scMaxSizeY	: rgnRect(3) = scMaxSizeY
	swend
	//基準点から左上x,yにする
	switch(type)
		case 1
			_x -= mae_rgnRect(2)
			_y -= mae_rgnRect(1)
			swbreak
		case 2
			_x -= mae_rgnRect(2)
			_y -= mae_rgnRect(3)
			swbreak
		case 3
			_x -= mae_rgnRect(0)
			_y -= mae_rgnRect(3)
			swbreak
		case 4
			_x -= (mae_rgnRect(2)-mae_rgnRect(0))/2 + mae_rgnRect(0)
			_y -= (mae_rgnRect(3)-mae_rgnRect(1))/2 + mae_rgnRect(1)
			swbreak
		case 5
			_x -= (mae_rgnRect(2)-mae_rgnRect(0))/2 + mae_rgnRect(0)
			_y -= mae_rgnRect(1)
			swbreak
		case 6
			_x -= mae_rgnRect(2)
			_y -= (mae_rgnRect(3)-mae_rgnRect(1))/2 + mae_rgnRect(1)
			swbreak
		case 7
			_x -= (mae_rgnRect(2)-mae_rgnRect(0))/2 + mae_rgnRect(0)
			_y -= mae_rgnRect(3)
			swbreak
		case 8
			_x -= mae_rgnRect(0)
			_y -= (mae_rgnRect(3)-mae_rgnRect(1))/2 + mae_rgnRect(1)
			swbreak
		default
			_x -= mae_rgnRect(0)
			_y -= mae_rgnRect(1)
	swend
	if rgnRect(0) != mae_rgnRect(0) || rgnRect(1) != mae_rgnRect(1) || rgnRect(2) != mae_rgnRect(2) || rgnRect(3) != mae_rgnRect(3) {
		if (rgnRect(2)-rgnRect(0)) == scMaxSizeX && (rgnRect(3)-rgnRect(1)) == scMaxSizeY {
			if rgnflg == 1 {
				SetWindowRgn _hwnd, 0, 1
			}
		}else {
			CreateRectRgn rgnRect(0), rgnRect(1), rgnRect(2), rgnRect(3)
			SetWindowRgn _hwnd, stat, 1
		}
	}
	if _x != rect(0) || _y != rect(1) {
		SetWindowPos _hwnd, 0, _x,_y, 0,0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE
	}
	
	return

;// Zオーダー操作
#define global alalZtop(%1) _zOrder@AlphaLayerMod %1, -2	//HWND_TOP
#define global alalZbottom(%1) _zOrder@AlphaLayerMod %1, -1	//HWND_BOTTOM
#define global alalZnext(%1,%2) _zOrder@AlphaLayerMod %1, %2	//hWndInsertAfter
#deffunc _zOrder@AlphaLayerMod int imageID, int _flg
	flg = _flg
	if flg < 0 {
		flg += 2
	}else {
		flg = hwnds(flg)
	}
	SetWindowPos hwnds(imageID), flg, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
	return
*__dummy__@AlphaLayerMod
	return

// カーソルがアルファレイヤーに乗っているか
#define global ctype alalIsOnLayer(%1,%2=ginfo_mx,%3=ginfo_my) _alalIsPointOnLayer@AlphaLayerMod(%1,%2,%3)
#defcfunc _alalIsPointOnLayer@AlphaLayerMod int imageID, int _mx, int _my, local _rect
	if length(hwnds)<=imageID :return 0
	if alalIsShown(imageID) == 0 : return 0
	// まずalalGetRectでリージョンを考慮したRectの中に収まっているかを確認
	alalGetRect imageID,_rect,-1
	if _mx<_rect(0) || _rect(2)<_mx || _my<_rect(1) || _rect(3)<_my : return 0
	// 次に通常のGetWindowRectを使ってPoint下のA2dイメージでの座標を割り出す
	GetWindowRect hwnds(imageID), varptr(_rect)
	_rect(0) = _mx - _rect(0), _my - _rect(1)
	_rect(2) = alGetID()
	alSelectImage imageID
	_rect(3) = alGetPixel( _rect(0), _rect(1) )
	alSelectImage _rect(2)
	// ピクセルのアルファ値がゼロでなければ乗っている判定
	return ( ARGB_A( _rect(3) ) != 0 )

#deffunc _deinit_@AlphaLayerMod onexit
	_AllUnsetCallbackAlphaLayer
	repeat length(hwnds)
		if hwnds(cnt) == 0 : continue
		SetWindowPos hwnds(cnt), 0, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW
		SetParent hwnds(cnt),0
		if wintypes(imageID) == 0 : DestroyWindow hwnds(cnt)
	loop
	repeat length(lpDelay_GblAllocs)
		if lpDelay_GblAllocs(cnt) == 0 : continue
		GlobalFree lpDelay_GblAllocs(cnt)
	loop
	return

#global
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	a2d+AlphaLayer を使用するための種々確認と処理(デバッグ時)
#if __hspver__<$3601
#ifdef _debug

#module a2d_al_debug
#uselib "KERNEL32.DLL"
	#define BeginUpdateResource BeginUpdateResourceA
	#func BeginUpdateResourceA "BeginUpdateResourceA" sptr,sptr
	#func BeginUpdateResourceW "BeginUpdateResourceW" wptr,wptr
	#define UpdateResource UpdateResourceA
	#func UpdateResourceA "UpdateResourceA" sptr,sptr,sptr,sptr,sptr,sptr
	#func UpdateResourceW "UpdateResourceW" wptr,wptr,wptr,wptr,wptr,wptr
	#define EndUpdateResource EndUpdateResourceA
	#func EndUpdateResourceA "EndUpdateResourceA" sptr,sptr
	#func EndUpdateResourceW "EndUpdateResourceW" wptr,wptr
#uselib "msvcrt"
	#func rename "rename" str, str

#deffunc __manifest_kakunin__@a2d_al_debug
	flg=0
	//下記すべてを満たせば、改造済みとみなして何もせず戻る。
	//1.マニフェスト(usedAlphaLayer.manifest)の有無
	//2.バージョンリソース(usedAlphaLayer.version)の有無(HSP3.51のみ)
	//3.hsptmpに#packopt manifest,versionが書いてあるか(HSP3.51のみ)
	exist "usedAlphaLayer.manifest"
	flg = (strsize = -1)
	if hspver != $3507 { //HSP3.51
		exist "usedAlphaLayer.version"
		flg |= (strsize = -1)
		
		exist "hsptmp"
		if strsize != -1 {
			msize = strsize :if msize > 12*1024 : msize = 12*1024
			sdim m,msize+1
			bload "hsptmp",m,msize
			packopt_flg = (match(m,"#packopt\\smanifest")=="") || (match(m,"#packopt\\sversion")=="") ;後でメインスクリプトに←を書いて欲しい警告をする。
			flg |= packopt_flg
		}
	}
	if flg == 0 :return //何もせず戻る。
	
	//hsp3.exeファイルパス
	path_exe = dir_exe+"\\hsp3.exe"
	//サポートOS
	id_w8os = "4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38"
	//マニフェスト中身
	buf_manifest = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"> \n<assemblyIdentity \nversion=\"1.0.0.0\" \nprocessorArchitecture=\"X86\" \nname=\"OnionSoftware.hsp3.exe\"\ntype=\"win32\"\n/> \n<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"> \n  <application>\n    <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\"/>\n  </application>\n</compatibility>\n<description>XPStyle</description> \n<dependency> \n<dependentAssembly> \n<assemblyIdentity \ntype=\"win32\" \nname=\"Microsoft.Windows.Common-Controls\" \nversion=\"6.0.0.0\" \nprocessorArchitecture=\"X86\" \npublicKeyToken=\"6595b64144ccf1df\" \nlanguage=\"*\" \n/> \n</dependentAssembly> \n</dependency> \n</assembly>"
	//Version中身
	buf_version = ";行頭「;」でコメントアウト\n;_FILEVERSION=0.0.0.0\n;_PRODUCTVERSION=0.0.0.0\n;Comments=コメント\n;CompanyName=企業名\n;FileDescription=ファイルの説明\n;FileVersion=0.0\n;InternalName=内部名\n;LegalCopyright=著作権\n;OriginalFilename=元のファイル名(test.exeなど)\n;ProductName=製品名\n;ProductVersion=0.0"

	exist path_exe
	if strsize == -1 { return }
	sdim m,strsize
	bload path_exe,m,strsize

	//hsp3.exeの中身を検索してサポートOS表記があるか確認
	if bsearch@a2d_al_debug( 0, varptr.m, strsize, id_w8os, strlen(id_w8os) ) == -1 {
		//無ければ書き換えて良いかを聞く
		if hspver != $3507 {
			;HSP3.51
			dialog "デバッグ実行ランタイム(hsp3.exe)を改造してマニフェストを変更しても良いですか?\n\n・a2d+AlphaLayerはWindows8以降でしか動作しません。\n・hsp3.exeがWindows8の機能に対応していることをマニフェストで宣言することで、デバッグでもa2d+AlphaLayerが使えるようになります。\n\n変更前の「hsp3.exe」は「hsp3_origin.exe」として残りますので問題があれば元に戻せます。\n\n----------\n・実行ファイル自動作成時にもマニフェストが書き換えが必要です。\n・HSP3.51ではメインスクリプトに\n#packopt manifest \"usedAlphaLayer.manifest\"\n#packopt version \"usedAlphaLayer.version\"\nの記述が必要になります。(両ファイルはこのあと自動で生成されます。)\n\n※ HSP Ver.3.6β1からはデフォルトでマニフェストにWindows8のサポートOS IDが記述されており、この改造や追加ファイルは必要ありません。",3,"a2d+AlphaLayer モジュール"
		}else {
			;HSP3.5
			dialog "デバッグ実行ランタイム(hsp3.exe)を改造してマニフェストを変更しても良いですか?\n\n・a2d+AlphaLayerはWindows8以降でしか動作しません。\n・hsp3.exeがWindows8の機能に対応していることをマニフェストで宣言することで、デバッグでもa2d+AlphaLayerが使えるようになります。\n\n変更前の「hsp3.exe」は「hsp3_origin.exe」として残りますので問題があれば元に戻せます。\n\n----------\n・実行ファイル自動作成時にもマニフェストが書き換わります。(モジュール内部に #packopt manifest \"usedAlphaLayer.manifest\" が記述されています。ファイルはこのあと自動生成されます。)\n・自分のマニフェストを使いたい場合は #include \"a2d+AlphaLayer.hsp\" の後で #packopt manifest を宣言してください。後の宣言が優先されます。\n\n※ HSP Ver.3.6β1からはデフォルトでマニフェストにWindows8のサポートOS IDが記述されており、この改造をする必要はありません。",3,"a2d+AlphaLayer モジュール"
		}
		if stat == 7 {
			dialog "変更をキャンセルしました。"
			return
		}

		// オリジナルをコピー → オリジナルをhsp3_originにリネーム → コピーをhsp3にリネーム
		origin_path = getpath(path_exe,1)+"_origin"+getpath(path_exe,2)
		temp_path = getpath(path_exe,1)+"_temp"+getpath(path_exe,2)
		exist origin_path
		if strsize == -1 {
			exist temp_path
			if strsize == -1 {
				bcopy path_exe, temp_path
			}
			// iconins.hsp のコードを参考に。
			;	リソース変更の開始宣言
			path_exe2 = temp_path
			BeginUpdateResource path_exe2, 0// TRUEにして既存のリソース削除
			if stat = 0 {
				dialog "リソース変更に失敗しました。",1,"a2d+AlphaLayer モジュール"
				return
			}
			hResource = stat
	
			;	manifestの反映 ;1033
			UpdateResource hResource, 24/*RT_MANIFEST*/, 1, 1033, varptr(buf_manifest), strlen(buf_manifest)// 決め打ちで 24/1/1033 にしてる。 hsp351とhsp35はOK。
			
			;	リソース変更の終了宣言
			EndUpdateResource hResource, 0
		
			rename path_exe, origin_path
			rename temp_path, path_exe

			updateResourceFlg = 1
		}

	}
	
	;マニフェストを作る。
	exist "usedAlphaLayer.manifest"
	if strsize==-1 {
		notesel buf_manifest
		notesave "usedAlphaLayer.manifest"
		noteunsel
	}
	if hspver != $3507 { //HSP3.51
		;バージョンリソースを作る。
		exist "usedAlphaLayer.version"
		if strsize==-1 {
			notesel buf_version
			notesave "usedAlphaLayer.version"
			noteunsel
		}
	}

	if updateResourceFlg == 1 {
		dialog "完了しました。\n\n一度、終了しますので再度「コンパイル+実行(F5)」をお願いします。"
		end
	}
	
	if packopt_flg == 1 { //HSP3.51のみ
		dialog "メインスクリプト冒頭に以下の2行を追加してください。\n実行ファイル自動作成でマニフェストの変更が必要になります。\n\n----------\n#packopt manifest \"usedAlphaLayer.manifest\"\n#packopt version \"usedAlphaLayer.version\"\n----------\n( Ctrl+C を押せばコピーできます。 )\n\n※ HSP3.5 か HSP3.6β1以降を使えばこの追加は不要になります。",1,"a2d+AlphaLayer モジュール - HSP3.51"
	}
	return
	
#uselib "kernel32.dll"		// マシン語実行用メモリ確保
#func VirtualProtect	"VirtualProtect"	var, int, int, var
#define mdim(%1,%2)dim %1,%2 :VirtualProtect %1,(%2)*4,$40,AZSD
; bsearch 2006/03/29	Ver 0.9
// バイナリサーチ(BM法) : 開始index, bufポインタ, サイズ , 検索キー,検索キーの長さ
// statに開始indexからのバイト数が返ります。見つからない場合は-1
#defcfunc bsearch@a2d_al_debug int i, int pbuf,int size, var key,int lkey
	if bm=0{ mdim bm,49 : pbm=varptr.bm
	bm. 0= $81EC8B55,$000400EC,$10558B00,$758B5653,$01FE8314,$324CB60F,$227557FF
	bm. 7= $4539C033,$928E0F0C,$8B000000,$B60F0855,$D13B1014,$0086840F,$3B400000
	bm.14= $EB7C0C45,$C68B7BEB,$000100B9,$00BD8D00,$F3FFFFFC,$FF468DAB,$C085C933
	bm.21= $F88B5E7E,$111CB60F,$9DBC8941,$FFFFFC00,$7CC83B4F,$8B49EBEF,$B60F0845
	bm.28= $B60F0104,$3BFF327C,$8A2B75C7,$8BFE165C,$418D087D,$381C3AFF,$F88B1C75
	bm.35= $7C8DF92B,$FF85FF37,$5D8B2674,$8A4F4808,$143A1714,$10558B18,$458BEC74
	bm.42= $04B60F08,$858C0301,$FFFFFC00,$7C0C4D3B,$FFC883B2,$C95B5E5F,$000000C3}
	prm=pbuf+i, size-i,varptr.key,lkey : return callfunc(prm, pbm, 4)
#global

#endif
#endif
//	a2d+AlphaLayer を使用するための種々確認と処理(デバッグ時)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

_init_@AlphaLayerMod
#endif