HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
1011
タカダショウゴマウスカーソルを変更、元に戻す方法を教えてください。8解決


タカダショウゴ

リンク

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)を指定することは、あきらめました。
マウス操作を透過しなくても良い、別の方法で対応したいと思っています。



ONION software Copyright 1997-2023(c) All rights reserved.