リージョンウィンドウを使い、左クリックすると、マウスの位置に画像を表示するものを作ってみました。
ついでに、ウィンドウを半透明にしています。
後は、アニメーションエフェクトと、
連打への対応をすれば、いい感じになると思います。
// 不定形リージョンウィンドウ作成 モジュール
; HSP開発wiki様からお借りしました https://wiki.hsp.moe/%E4%B8%8D%E5%AE%9A%E5%BD%A2%E3%83%AA%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3.html#g426bdbb
// 必要なものをインクルード
#include "user32.as"
#include "gdi32.as"
#include "winmm.as" // これはリージョン作成に直接関係無し
// ウィンドウ移動制御用の定数
#define global WM_NCLBUTTONDOWN $000000A1
#define global HTCAPTION 2
// リージョン作成用の定数
#define global WINDING 2
// モジュール記述
#module
// CreateWindowRgn p1(targetWin), p2(baseWin)
// targetWin : 不定形リージョンを適用するウィンドウID
// baseWin : 不定形リージョンを作成する絵があるウィンドウID
#deffunc CreateWindowRgn int targetWin, int baseWin
gsel baseWin
mref vram, 66 // 画像データを取得
dim pt, 100000 // 点データ用配列
dim ct, 100000 // 多角形点数記憶用配列
wx = ginfo_winx : wy = ginfo_winy // 画像サイズ取得
pget 0, 0 // 透明色の取得(点(0,0)の色を透明色にする)
tr = ginfo_r : tg = ginfo_g : tb = ginfo_b
// 変数初期化
// 注:yはデータ構造上、下から
x = 0 : y = wy : flg = 0 : count = 0 : pt_cnt = 0 : poly_cnt = 0
repeat wy
repeat wx
// 画像データの構造にそってRGB値を取得
b = peek(vram,count)
count++
g = peek(vram,count)
count++
r = peek(vram,count)
count++
// 透明色と比較
// 内部は説明面倒なので省略。やってることはIIと変わらない。
if (wx == x + 1) | ((r == tr) && (g == tg) && (b == tb)) {
if flg == 1 {
pt(pt_cnt) = x, y-1, x, y
pt_cnt += 4
ct(poly_cnt) = 4
poly_cnt++ : flg = 0
}
} else {
if flg == 0 {
pt(pt_cnt) = x, y, x, y-1
pt_cnt += 4
flg = 1
}
}
x++
loop
x = 0
y--
loop
// 取得した情報からリージョン作成(詳細はMSDNやその他サイト参照)
CreatePolyPolygonRgn varptr(pt), varptr(ct), poly_cnt, WINDING
tmpRgn = stat
gsel targetWin // ターゲットウィンドウをアクティブに
SetWindowRgn hwnd, tmpRgn, 1 // リージョン設定
DeleteObject tmpRgn // 後片付け
return
#global
#define GWL_EXSTYLE $FFFFFFEC
#define WS_EX_TRANSPARENT $00000020
#define WS_EX_TOOLWINDOW $00000080
#define WS_EX_LAYERED $00080000
#define LWA_COLORKEY $00000001
#define LWA_ALPHA $00000002
#define SW_HIDE $0
#define SW_SHOWNA $8
#define SWP_NOSIZE $1
#define SWP_NOZORDER $4
// 画像をバッファに読み込み(HSPのサンプルにある画像を流用)
buffer 1
picload dir_exe+"\\hsptv\\king_knight.bmp"
;picload dir_exe+"\\sample\\pronama2d\\tamane_wizard2_5.png" // 大きい画像(大きいと、それだけリージョン作成に時間がかかる)
winx = ginfo_winx
winy = ginfo_winy
// サイズを画像に合わた、枠なしウィンドウを作成
bgscr 0, winx, winy
// ウィンドウの拡張スタイルを設定(マウス貫通 | タスクバーに表示させない | 不透明度を指定できるように)
SetWindowLong hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_LAYERED
// ウィンドウを半透明に(これで下が透けて見える)
SetLayeredWindowAttributes hwnd, 0, 155 , LWA_ALPHA
// ウィンドウにリージョンを適用して、画像を描画(一番重要なところ)
CreateWindowRgn 0, 1 // リージョンを使い、ウィンドウを画像の形と同じ形状に
gcopy 1, 0, 0, winx, winy // バッファの画像をウィンドウにコピー
// ウィンドウを最前面化して、非表示に
gsel 0, 2
ShowWindow hwnd, SW_HIDE
repeat
// 左クリックで画像表示(長押しには反応しない)
getkey isLClick, 1
if isLClick {
if isFirstClick == 0 {
isFirstClick = 1
// マウスの位置がウィンドウの中心にくるように、ウィンドウを移動
;(標準命令のwidthだと、指定先が画面外だった場合に挙動が変になるので、MoveWindow関数を使用)
;width ,, ginfo_mx-(winx/2), ginfo_my-(winy/2)
MoveWindow hwnd, ginfo_mx-(winx/2), ginfo_my-(winy/2), ginfo_winx, ginfo_winy, 0
// 一定時間ウィンドウを表示する
ShowWindow hwnd, SW_SHOWNA
wait 30
ShowWindow hwnd, SW_HIDE
}
}else{
isFirstClick = 0
}
// Escで終了
getkey isEsc, 27
if isEsc == 1 {
gsel 0,2
dialog "終了"
end
}
wait 1
loop