「マウス操作を透過した上で、かつ、マウス操作を検出できるようにしたい」
ということでしょうか?
相当な難問であるように思いましたが、以下のスレを参考に、
コールバックモジュールを利用してやってみました。
(当方コールバックを使うのは初めてなので、大部分以下のスレのあらやさんのコードのコピペですが)
http://hsp.tv/play/pforum.php?mode=pastwch&num=84110
なお、この方法だとWM_LBUTTONDBLCLK等を使ってのダブルクリック検出は
できないようなので、ちょっと面倒ですが、ダブルクリック受け付け時間を取得し、
自前でダブルクリック判定を行うようにしています。
#include "modclbk3.hsp"
#define NULL 0
#define WH_MOUSE_LL 14
#define WM_MOUSEWHEEL 0x020A
#include "user32.as"
#include "winmm.as"
#define WM_LBUTTONDOWN $0201
#define WM_LBUTTONUP $0202
#define WM_RBUTTONDOWN $0204
#define WM_RBUTTONUP $0205
#define WM_MBUTTONDOWN $0207
#define WM_MBUTTONUP $0208
#define True 1
#define False 0
GetDoubleClickTime : dc_time=stat //ダブルクリック受付時間を取得
can_ldc=0 : can_rdc=0 : can_mdc=0 //ダブルクリック受付フラグ
time_lc=0 : time_rc=0 : can_mc=0 //最後にクリックした時の時間
dim point,2
bgscr 0, 640, 480
透過ウィンドウハンドル = hwnd
GetWindowLong 透過ウィンドウハンドル, -20
SetWindowLong 透過ウィンドウハンドル, -20, stat | $00080000 | $00000020 //マウス操作透過ウィンドウ用
SetLayeredWindowAttributes 透過ウィンドウハンドル, 0, 50, 2 //0, 0, 2 で透明
MoveWindow 透過ウィンドウハンドル, 50, 50, 640, 480, 1
gmousew = 0 //mousewの代わりにこれを使う
cbl = *LowLevelMouseProc
newclbk3 clbkptr, 3, cbl
SetWindowsHookEx WH_MOUSE_LL, clbkptr, NULL, 0 // マウス操作を感知した場合ウェイト中に割り込みが入る
hhook=stat
clbk_skip=0 //コールバックをスキップするフラグ
onexit goto *OnQuit
lbd = false
ldc = false
rbd = false
rdc = false
mbd = false
mdc = false
wheel=0
repeat
redraw 0
color 255,255,255 : boxf : color 0,0,0
pos 0,0
mes "左クリック:"+lbd
mes "左ダブルクリック:"+ldc
mes "右クリック:"+rbd
mes "右ダブルクリック:"+rdc
mes "中クリック:"+mbd
mes "中ダブルクリック:"+mdc
mes "マウスホイール:"+wheel
redraw 1
await 16
loop
*LowLevelMouseProc
dupptr MstateD, lparam, wparam*4, 4
if clbk_skip {
CallNextHookEx hhook, MstateD(0), MstateD(1), MstateD(2) : return stat
}
dim Mstate,wparam : memcpy Mstate,MstateD,wparam*4,0,0
// Mstate(0)=フックコード(nCode) Mstate(1)=メッセージ識別子(wParam) Mstate(2)=メッセージデータ(lParam)
if( Mstate(0) < 0 ) {
// フックコードが0未満の場合はフックを中止して制御を元に戻さなければいけない。
CallNextHookEx hhook, Mstate(0), Mstate(1), Mstate(2) : return stat
}
dupptr lp, Mstate(2), 24, 4; // lParamはMSLLHOOK構造体へのポインタが入っている
point=lp(0),lp(1) : ScreenToClient 透過ウィンドウハンドル,varptr(point)
if (point(0)>=0)&(point(0)<640)&(point(1)>=0)&(point(1)<480) {
//マウスの位置が透過ウィンドウの範囲内の時のみ処理を行う
//この時点で配列point内にはマウスのX座標とY座標が入っている
if Mstate(1)=WM_MOUSEWHEEL {
gmousew = lp(2)>>16 // MSLLHOOK構造体のメンバmouseDataの上位ビットがホイール情報
gosub *OnMouseWheel
} else {
gmousew=0
switch Mstate(1)
case WM_LBUTTONDOWN
gosub *on_LButtonDown
swbreak
case WM_LBUTTONUP
gosub *on_LButtonUp
swbreak
case WM_RBUTTONDOWN
gosub *on_RButtonDown
swbreak
case WM_RBUTTONUP
gosub *on_RButtonUp
swbreak
case WM_MBUTTONDOWN
gosub *on_MButtonDown
swbreak
case WM_MBUTTONUP
gosub *on_MButtonUp
swbreak
swend
}
}
CallNextHookEx hhook, Mstate(0), Mstate(1), Mstate(2) : return stat // フックしたデータをそのまま返す
*OnMouseWheel
wheel = gmousew
if 0 != wheel {
if 0 < wheel {
gosub *wheel_Up
} else {
gosub *wheel_Down
}
}
return
*on_LButtonDown
if can_ldc {
TimeGetTime
if stat<time_lc+dc_time {
gosub *on_LButtonDblClk
can_ldc=0 : return
}
}
TimeGetTime : time_lc=stat : can_ldc=1
lbd = true
return
*on_LButtonUp
clbk_skip=1 : wait 30 : clbk_skip=0
if ldc {
//ダブルクリック時処理
lbd = false : ldc = false
} else {
if lbd {
//クリック時処理
lbd = false : ldc = false
}
}
return
*on_LButtonDblClk
ldc = true
return
*on_RButtonDown
if can_rdc {
TimeGetTime
if stat<time_rc+dc_time {
gosub *on_RButtonDblClk
can_rdc=0 : return
}
}
TimeGetTime : time_rc=stat : can_rdc=1
rbd = true
return
*on_RButtonUp
clbk_skip=1 : wait 30 : clbk_skip=0
if rdc {
//右ダブルクリック時処理
rbd = false : rdc = false
} else {
if rbd {
//右クリック時処理
rbd = false : rdc = false
}
}
return
*on_RButtonDblClk
rdc = true
return
*on_MButtonDown
if can_mdc {
TimeGetTime
if stat<time_mc+dc_time {
gosub *on_MButtonDblClk
can_mdc=0 : return
}
}
TimeGetTime : time_mc=stat : can_mdc=1
mbd = true
return
*on_MButtonUp
clbk_skip=1 : wait 30 : clbk_skip=0
if mdc {
//ミドルボタンダブルクリック時処理
mbd = false : mdc = false
} else {
if mbd {
//ミドルボタンクリック時処理
mbd = false : mdc = false
}
}
return
*on_MButtonDblClk
mdc = true
return
*wheel_Up
//ホイール上回転時処理
return
*wheel_Down
//ホイール下回転時処理
return
*OnQuit
UnhookWindowsHookEx hhook // フックの終了
end