|
|
2021/10/11(Mon) 22:05:42|NO.94133
HSPのコードの中で、好きなタイミングで、
マウスカーソルを変更したり、元のマウスカーソルに戻したりしたいが、
どのようにしたらいいのか解りません。
#include "user32.as"
#define WM_SETCURSOR $00000020 //カーソル変更用
#define HTCLIENT $00000001 //カーソル変更用
LoadCursorFromFile "DATA/変更用カーソル.cur"
変更用カーソルハンドル = stat
oncmd gosub *OnSetCousor,WM_SETCURSOR
stop
*OnSetCousor
if (lparam&0xffff)==HTCLIENT{
SetCursor 変更用カーソルハンドル
return 1
}
return
上のコードだと、最初からマウスカーソルが変更用カーソルになってしまいます。
コードの中で、好きなところで、変更したり、元に戻したりする方法が有りましたら、
教えてください。
|
|
2021/10/12(Tue) 13:43:08|NO.94143
比較用の変数を用意して、それが0ではないなら変更、とするのが手っ取り早いかと思います。
#include "user32.as"
#define WM_SETCURSOR $00000020 //カーソル変更用
#define HTCLIENT $00000001 //カーソル変更用
#const IDC_HAND 32649;手のひらカーソル
;LoadCursorFromFile "DATA/変更用カーソル.cur";システムのカーソルを利用するのでコメントアウト
LoadCursor ,IDC_HAND
変更用カーソルハンドル = stat
カーソル状態 = 0
ボタン文字列 = "変更","元に戻す"
oncmd gosub *OnSetCousor,WM_SETCURSOR
button gosub ボタン文字列,*ChangeState
stop
*OnSetCousor
if カーソル状態&(lparam&0xffff)==HTCLIENT{
SetCursor 変更用カーソルハンドル
return 1
}
return
*ChangeState
カーソル状態 ^= 1
objprm 0,ボタン文字列(カーソル状態)
return
|
|
2021/10/12(Tue) 13:49:01|NO.94144
すみません、一部パラメータが抜けている部分がありました。
以下のように修正してください。
LoadCursor ,IDC_HAND
↓
LoadCursor 0,IDC_HAND
|
|
2021/10/12(Tue) 20:33:43|NO.94151
猪野さん、返信ありがとうございました。
確かにボタンを押すたびに、変更カーソル、元のカーソルに成ります。
しかし、コードの中から、*OnSetCursorを実行したいのです。
そのようなことは、可能でしょうか?
|
|
2021/10/13(Wed) 14:50:59|NO.94154
*OnSetCursorのような割り込み処理は、システムから呼び出される造りになっているため、コードから呼び出しても正しく動作しません。
そのため、カーソルの状態を表す変数を用意して、その値によって表示させるカーソルを切り替えるようにしています。
カーソルを変更する時は、*OnSetCursorやSetCursorは呼び出さず、変数の値を変更してください。
こうした方が分かりやすいでしょうか? 考え方としては初めのものと同じです。
(システムカーソルのハンドルはLoadCursorではなくLoadImageで取得すべきなので修正しましたが、本題とは関係ないので詳細は省きます)
#include "user32.as"
#define WM_SETCURSOR $00000020 //カーソル変更用
#define HTCLIENT $00000001 //カーソル変更用
#const OCR_NORMAL 32512;標準の矢印カーソル
#const OCR_HAND 32649;手のひらカーソル
#const IMAGE_CURSOR 2
#const LR_DEFAULTSIZE $40
#const LR_SHARED $8000
#enum 標準=0
#enum 手のひら
#enum カーソル種類数
dim カーソルハンドル,カーソル種類数
LoadImage 0,OCR_NORMAL,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(標準) = stat
;LoadCursorFromFile "DATA/変更用カーソル.cur";システムのカーソルを利用するのでコメントアウト
;変更用カーソルハンドル = stat
LoadImage 0,OCR_HAND,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(手のひら) = stat
表示するカーソル = 標準
oncmd gosub *OnSetCursor,WM_SETCURSOR
button gosub "標準",*SetNormalCursor
button gosub "手のひら",*SetHandCursor
stop
*OnSetCursor
if (lparam&0xffff)==HTCLIENT {
SetCursor カーソルハンドル(表示するカーソル)
return 1
}
return
*SetNormalCursor
表示するカーソル = 標準
return
*SetHandCursor
表示するカーソル = 手のひら
return

| |
|
2021/10/13(Wed) 17:02:03|NO.94155
SetClassLongを使えばoncmdを利用しなくてもマウスカーソルの変更ができるようです。
http://chokuto.ifdef.jp/urawaza/changecursor2.html
猪野さんのコードを少し弄らせていただきます。
#include "user32.as"
#define WM_SETCURSOR $00000020 //カーソル変更用
#define HTCLIENT $00000001 //カーソル変更用
#const GCL_HCURSOR -12
#const OCR_NORMAL 32512;標準の矢印カーソル
#const OCR_HAND 32649;手のひらカーソル
#const IMAGE_CURSOR 2
#const LR_DEFAULTSIZE $40
#const LR_SHARED $8000
#enum 標準=0
#enum 手のひら
#enum カーソル種類数
dim カーソルハンドル,カーソル種類数
LoadImage 0,OCR_NORMAL,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(標準) = stat
;LoadCursorFromFile "DATA/変更用カーソル.cur";システムのカーソルを利用するのでコメントアウト
;変更用カーソルハンドル = stat
LoadImage 0,OCR_HAND,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(手のひら) = stat
表示するカーソル = 標準
gosub *ChangeCursor
button gosub "標準",*SetNormalCursor
button gosub "手のひら",*SetHandCursor
stop
*SetNormalCursor
表示するカーソル = 標準
gosub *ChangeCursor
return
*SetHandCursor
表示するカーソル = 手のひら
gosub *ChangeCursor
return
*ChangeCursor
SetClassLong hwnd,GCL_HCURSOR,カーソルハンドル(表示するカーソル)
return
|
|
2021/10/14(Thu) 20:18:40|NO.94166
猪野さん、沢渡さんありがとうございます。
おかげで、下のようなことが出来るようになりました。
#include "user32.as"
#define WM_SETCURSOR $00000020
#define HTCLIENT $00000001
#const GCL_HCURSOR -12
#const OCR_NORMAL 32512
#const OCR_HAND 32649
#const IMAGE_CURSOR 2
#const LR_DEFAULTSIZE $40
#const LR_SHARED $8000
#enum 標準=0
#enum 手のひら
#enum カーソル種類数
/*
GetWindowLong hwnd, -20
SetWindowLong hwnd, -20, stat | $00080000 | $00000020
SetLayeredWindowAttributes hwnd, 0, 200, 2
*/
dim カーソルハンドル,カーソル種類数
LoadImage 0,OCR_NORMAL,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(標準) = stat
LoadImage 0,OCR_HAND,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(手のひら) = stat
wait 0
*st
await 1000
表示するカーソル = 標準
gosub *ChangeCursor
await 1000
表示するカーソル = 手のひら
gosub *ChangeCursor
goto *st
stop
*ChangeCursor
mouse -1
SetClassLong hwnd,GCL_HCURSOR,カーソルハンドル(表示するカーソル)
mouse
return
ところが、コメントアウトした部分を実行して、マウス操作を透過するウィンドウにすると、
カーソルが変更が出来なくなってしまいました。
これは、解決不可能ですか?
|
|
2021/10/14(Thu) 22:22:25|NO.94167
拡張ウィンドウスタイルにWS_EX_TRANSPARENT(0x20)を指定した場合だと
「ウィンドウは見えるだけで存在しない」という状態になりますから、
マウスカーソルの変更は適用されないのではないかと。
https://hsp.tv/play/pforum.php?mode=all&num=94055
おそらく、前回の「マウス判定を通過させ、かつマウス入力を検出したい」
という件と組み合わせたいのだと思いますし、
どういうタイミングでマウスカーソルを変更したいのかというのも
関わってきますが、マウスカーソルを変更している間だけは
「マウス判定が通過しない」状態にするというのはどうでしょうか。
以下、赤い四角形を描き、マウスカーソルが赤い四角形の中にある時のみ
マウスカーソルを変更する例です。
#include "modclbk3.hsp"
#include "user32.as"
#define WH_MOUSE_LL 14
#define WM_MOUSEMOVE $0200
#define HTCLIENT $00000001
#const GCL_HCURSOR -12
#const OCR_NORMAL 32512
#const OCR_HAND 32649
#const IMAGE_CURSOR 2
#const LR_DEFAULTSIZE $40
#const LR_SHARED $8000
#enum 標準=0
#enum 手のひら
#enum カーソル種類数
dim point,2
GetWindowLong hwnd, -20
no_trans=stat|$00080000 //ウィンドウは透過するがマウス判定は通過しない
trans=no_trans|$00000020 //ウィンドウが透過しマウス判定も通過する
SetWindowLong hwnd, -20, trans
SetLayeredWindowAttributes hwnd, 0, 200, 2
dim カーソルハンドル,カーソル種類数
LoadImage 0,OCR_NORMAL,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(標準) = stat
LoadImage 0,OCR_HAND,IMAGE_CURSOR,0,0,LR_DEFAULTSIZE|LR_SHARED
カーソルハンドル(手のひら) = stat
cbl = *LowLevelMouseProc
newclbk3 clbkptr, 3, cbl
SetWindowsHookEx WH_MOUSE_LL, clbkptr, 0, 0 // マウス操作を感知した場合ウェイト中に割り込みが入る
hhook=stat
clbk_skip=0 //コールバックをスキップするフラグ
onexit goto *OnQuit
color 255,0,0 : boxf 100,100,200,200
mouse_type=0 //0の場合は通常。1の場合は手のひら
stop
*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
}
if Mstate(1)=WM_MOUSEMOVE {
dupptr lp, Mstate(2), 24, 4 // lParamはMSLLHOOK構造体へのポインタが入っている
point=lp(0),lp(1) : ScreenToClient hwnd,varptr(point) //この時点でlp(0)とlp(1)にはマウスのx座標とy座標が入っている
if (point(0)>=100)&(point(0)<=200)&(point(1)>=100)&(point(1)<=200) {
//マウスカーソルが赤い部分にある場合
if mouse_type=0 {
//手のひらカーソルに変更
mouse_type=1
SetWindowLong hwnd, -20, no_trans
mouse -1
SetClassLong hwnd,GCL_HCURSOR,カーソルハンドル(手のひら)
mouse
}
} else {
//マウスカーソルが赤い部分の外にある場合
if mouse_type=1 {
//通常カーソルに変更
mouse_type=0
SetWindowLong hwnd, -20, trans
mouse -1
SetClassLong hwnd,GCL_HCURSOR,カーソルハンドル(通常)
mouse
}
}
}
CallNextHookEx hhook, Mstate(0), Mstate(1), Mstate(2) : return stat // フックしたデータをそのまま返す
*OnQuit
UnhookWindowsHookEx hhook // フックの終了
end

| |
|
2021/10/15(Fri) 21:44:24|NO.94171
沢渡さん、いろいろアイディアを出していただいて、すみません。
WS_EX_TRANSPARENT(0x20)を指定することは、あきらめました。
マウス操作を透過しなくても良い、別の方法で対応したいと思っています。
|
|