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