hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
マウスとウィンドウ - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

 HSP2.61   HSP3.0a 

マウスとウィンドウ

マウスの下にあるウィンドウはどのID?

マウスの座標

HSP製のウィンドウが複数ある場合システム変数mousex,yはマウスがクライアント領域に入っているウィンドウの座標を格納しています。

考える:

なぜアクティブなウィンドウの座標ではなくマウスの下にあるウィンドウのクライアント領域座標なのか。

それは多分、ウィンドウ毎にウィンドウプロシージャがありプロシージャはWM_MOUSEMOVEを監視します。
マウスがウィンドウのクライアント領域を通過するとそのウィンドウ(プロシージャ)にWM_MOUSEMOVEが送られます。
このメッセージはその時のマウス座標をそのウィンドウのクライアント座標系で持っています。
そしてプロシージャはHSP内部のマウス座標を管理するグローバル変数にこの座標を格納しているのではないでしょうか?

前置きはこの辺にしておいて・・・ではマウスのしたにあるウィンドウを描画対象にするにはどうしましょう?

答えはマウスの座標とウィンドウの位置関係から求められます。
ここで覚えておきたいのはHSPはマウスの座標を2つ取得できます。(ヘルプを見れば一発なんだけど。)

  1. システム変数mousex,y
  2. 描画情報ginfo 0

サンプル1

  • マウスの下にあるHSPウィンドウにクライアント座標系のマウス座標を描画します。(ついでにアクティブにもしてます。)
  • Zオーダー・移動は考慮しない仕様になってます^^
    filev2_000_mouseoverwnd.as
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    -
    |
    |
    |
    !
    -
    |
    |
    |
    |
    !
     
     
     
     
     
     
    
    ;=====================================================================
    ;   マウスの下にあるHSPウィンドウに描画するサンプル
    ;                                                         for HSP 2.61
    ;   2005/11/12                                          written by kz3
    ;=====================================================================
        
    #include "llmod.as"
     
        screen 0,640,480,2+4
        ginfo 5
        aw = prmx-640
        ah = prmy-480
     
        dim rc, 4
                prm.0 = 48
                prm.1 = 0
        getptr     prm.2, rc
                prm.3 = 0
     
        dllproc "SystemParametersInfoA", prm, 4, D_USER
        if dllret = 0: dialog "DLL呼び出しエラー", 1, "Quit": end
     
        clientw = rc.2-rc.0/2-aw
        clienth = rc.3-rc.1/2-ah
        dskcx = rc.2-rc.0/2
        dskcy = rc.3-rc.1/2
        
        dim wndrc, 5, 5
        wndrc.0.0 = rc.0, rc.1, rc.0+dskcx, rc.1+dskcy
        wndrc.0.1 = 0,0,0,0
        wndrc.0.2 = rc.0+dskcx, rc.1, rc.0+dskcx+dskcx, rc.1+dskcy
        wndrc.0.3 = rc.0, rc.1+dskcy, rc.0+dskcx, rc.1+dskcy+dskcy
        wndrc.0.4 = rc.0+dskcx, rc.1+dskcy, rc.0+dskcx+dskcx, rc.1+dskcy+dskcy
     
        screen 0, clientw, clienth, 4, wndrc.0.0, wndrc.1.0
        title "メインウィンドウ(ID0)"
        screen 2, clientw, clienth, 4, wndrc.0.2, wndrc.1.2
        title "サブウィンドウ(ID2)"
        screen 3, clientw, clienth, 4, wndrc.0.3, wndrc.1.3
        title "サブウィンドウ(ID3)"
        screen 4, clientw, clienth, 4, wndrc.0.4, wndrc.1.4
        title "サブウィンドウ(ID4)"
     
    *catch
        mx = mousex: my = mousey
        color 255,255,255
        repeat 6
            wait 1
            if cnt = 0: ginfo 0
            if cnt = 1: continue cnt+1
            if cnt = 5{
                ginfo 7
                boxf 0,0,prmx,prmy
                continue 0
            }
            if (prmx>=wndrc.0.cnt) & (prmx<=wndrc.2.cnt) & (prmy>=wndrc.1.cnt) & (prmy<=wndrc.3.cnt){
                ginfo 7
                boxf 0,0,prmx,prmy
                gsel cnt,1
                break
            }
        loop
        color 0: pos 0,0
        mes "("+mx+","+my+")"
        goto *catch
     
        stop

サンプル2

filemouseoverwnd_v3.hsp
Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
!
 
-
|
|
|
|
|
!
-
|
|
|
|
|
|
!
 
 
 
 
 
 
 
;=====================================================================
;   マウスの下にあるHSPウィンドウに描画するサンプル
;                                                         for HSP 2.61
;   2005/11/12                                          written by kz3
;
;                                                         for HSP 3.0a
;   2005/11/13                                          移植 by hiroki
;=====================================================================
    
#uselib "user32.dll"
#func   SystemParametersInfoA "SystemParametersInfoA" int,int,sptr,int
 
    screen 0,640,480,2+4
    ;ginfo 5
    ;prmx = ginfo_dispx
    ;prmy = ginfo_dispy
 
    prmx = ginfo_sizex
    prmy = ginfo_sizey
 
    aw = prmx-640
    ah = prmy-480
 
    dim rc, 4
        ;prm.0 = 48
        ;prm.1 = 0
        ;prm.2 = varptr(rc)
        ;prm.3 = 0
 
    SystemParametersInfoA 48 , 0 , varptr(rc) , 0
    if stat = 0: dialog "DLL呼び出しエラー", 1, "Quit": end
 
    clientw = (rc.2-rc.0)/2-aw
    clienth = (rc.3-rc.1)/2-ah
    dskcx = (rc.2-rc.0)/2
    dskcy = (rc.3-rc.1)/2
    
    dim wndrc, 5, 5
    wndrc.0.0 = rc.0, rc.1, rc.0+dskcx, rc.1+dskcy
    wndrc.0.1 = 0,0,0,0
    wndrc.0.2 = rc.0+dskcx, rc.1, rc.0+dskcx+dskcx, rc.1+dskcy
    wndrc.0.3 = rc.0, rc.1+dskcy, rc.0+dskcx, rc.1+dskcy+dskcy
    wndrc.0.4 = rc.0+dskcx, rc.1+dskcy, rc.0+dskcx+dskcx, rc.1+dskcy+dskcy
 
    screen 0, clientw, clienth, 4, wndrc.0.0, wndrc.1.0
    title "メインウィンドウ(ID0)"
    screen 2, clientw, clienth, 4, wndrc.0.2, wndrc.1.2
    title "サブウィンドウ(ID2)"
    screen 3, clientw, clienth, 4, wndrc.0.3, wndrc.1.3
    title "サブウィンドウ(ID3)"
    screen 4, clientw, clienth, 4, wndrc.0.4, wndrc.1.4
    title "サブウィンドウ(ID4)"
 
*catch
    mx = mousex: my = mousey
    color 255,255,255
    repeat 6
        wait 1
        if cnt = 0 {
            ;ginfo 0
            prmx = ginfo_mx
            prmy = ginfo_my
        }
        if cnt = 1 : continue cnt+1
        if cnt = 5 {
            ;ginfo 7
            prmx = ginfo_mesx
            prmy = ginfo_mesy
            boxf 0,0,prmx,prmy
            continue 0
        }
        if (prmx>=wndrc.0.cnt) & (prmx<=wndrc.2.cnt) & (prmy>=wndrc.1.cnt) & (prmy<=wndrc.3.cnt){
            ;ginfo 7
            prmx = ginfo_mesx
            prmy = ginfo_mesy
            boxf 0,0,prmx,prmy
            gsel cnt,1
            break
        }
    loop
    color 0: pos 0,0
    mes "("+mx+","+my+")"
    goto *catch
 
    stop
  • kz3のZオーダー・ウィンドウ移動対応版(簡単な仕様は以下の通り。)
    • スペースキーで最大8個までウィンドウ作成(サイズ不定)
    • クライアント領域にマウスが入っているウィンドウにIDとクライアント座標を表示(タイトルバーは非クライアント領域)
    • メインウィンドウID0を閉じると終了
    • ID2〜8を閉じると一番最後に再利用される。(謎です。
    • filev3_020_mouseoverwnd_a.hsp

コメント

  • HSPの対応バージョンの表記をプラス。しかもRSSタイルとデザインを揃えています!(気が利く!)ただ、フラットなのが残念。 -- kz3 2005-11-12 (土) 10:11:56
  • Zオーダーは監視してないので単純にウィンドウがその位置にあれば描画しますが、WM_MOUSEMOVEがHSP製ウィンドウに送られてこなければ描画内容は更新されません。 -- kz3 2005-11-12 (土) 11:20:17
  • 激しくいろいろやってます。真ん中より上半分はウィンドウ整列処理です。 -- kz3 2005-11-12 (土) 11:21:06
  • ウィンドウの境界は微妙です。 -- kz3 2005-11-12 (土) 11:25:49
  • なんで微妙になってくるんでしょうかね?? -- Charlotte 2005-11-12 (土) 11:28:39
  • ネタはHSP2掲示板より拾ってきたものをグレードアップさせています。 -- kz3 2005-11-12 (土) 11:28:53
  • 今、デスクトップのタスクバーやツールバーを除く描画領域を縦横2等分させた大きさのウィンドウを作っていますが、 例えば100の大きさの半分は50ですよね?
    そこでウィンドウ全体の大きさを50として、左上ウィンドウの左上角のx座標が0とすると右下角のx座標は50ですね?
    次の右上ウィンドウの左上角x座標は全体100の半分なので50です。そして右下角のx座標は50+50で100です。
    左上ウィンドウの右下x座標と右上ウィンドウの左上x座標が50/50でダブってるんですよね。
    で境界判定は50以上、以下としているので・・・実際は枠幅があるので問題ないかな・・・枠なしウィンドウだと影響あるかも。
    でも1pxだけだし気にならないけど! -- kz3 2005-11-12 (土) 11:35:39
  • Zオーダーは自前で管理できるかもです。ウィンドウをアクティブにする(アクセスする)度にZオーダーリストの先頭にIDを持ってくる。MRUです。 -- kz3 2005-11-12 (土) 11:43:42
  • グッドタイミングです。いろいろ調べていたところでした。 hsp2.6をインストして今解読中です。 ありがとう。 -- hiroki? 2005-11-12 (土) 11:52:38
  • [tere]*1)ぷるぷるサンぷる〜!(謎 -- kz3 2005-11-12 (土) 12:26:39
  • あ・・・汗 -- kz3 2005-11-12 (土) 12:26:55
  • 読んでる人は分かると思いますが、ウィンドウの位置情報を更新していないのでズラすとダメです。実際にはループ中かWM_MOVEなどを捕まえて更新する必要があります。 -- kz3 2005-11-12 (土) 13:43:52
  • まずはHSP3に移植だと思いやっと出来たんですが、ID0以外はタスクバーに隠れます。(;_;) -- hiroki? 2005-11-12 (土) 16:09:36
  • ginfo系はprmx,yは廃止ですよ〜? -- kz3 2005-11-12 (土) 16:20:23
  • うん、prmx = ginfo_dispxというふうにやっているんですが。 今2と3のリファレンスを凝視しています。 -- hiroki? 2005-11-12 (土) 16:37:49
  • あ、dispx,yじゃいかんですよ、それはディスプレイであって上のサンプルはデスクトップ描画領域、リストビューのスクリーン座標を取得しています。 -- kz3 2005-11-12 (土) 16:42:44
  • だと思ってginfo_sizexとすると、ウインドー0が画面全体に広がるんです。dimは別にいじらんでもいいしね。 -- hiroki? 2005-11-12 (土) 16:54:40
  • 同じ変数に同じ数値が入っているのに24〜27行目に入った途端HSP3では計算値が変わる。 おかしいな。配列値も同じだし... -- hiroki? 2005-11-13 (日) 09:02:45
  • おはようございます(=。ゞ どんなソース書いてるんですか?^^; -- kz3 2005-11-13 (日) 09:06:02
  • ごめん解決しました。hsp2ではclientw = rc.2-rc.0/2-awでいいんだけど、hsp3は、clientw = (rc.2-rc.0)/2-awと書かないと動いてくれませんでした。 あとはマウスの位置の誤認だけ。 一応添付します。 -- hiroki? 2005-11-13 (日) 09:19:23
  • 今、hsp3.0a化してみて、式の優先順位を直してないんじゃないかな〜って思ったところでした^^; -- kz3 2005-11-13 (日) 09:21:18
  • hirokiさんの何か動作がおかしい^^;描画した座標を消すところ・・・。実はあれ、ループの中でメッセージ描画サイズを取得するより、メッセージを描画した後で取得したほうが1回の呼び出しで済むのでスマートだったりします。 -- kz3 2005-11-13 (日) 09:24:17
  • 式の優先順位は盲点でした。(-_-;) -- hiroki? 2005-11-13 (日) 09:31:00
  • Zオーダー実装中。 -- kz3 2005-11-13 (日) 11:03:59
  • ウィンドウ作成、削除、アクティブウィンドウの変更に関するZオーダーの実装終了しました。 -- kz3 2005-11-13 (日) 11:41:58
  • 仕様を調整。 -- kz3 2005-11-13 (日) 11:50:27
  • やっと僕の移植版が動きました。ふーーっ  一応添付を入れ替えました。 -- hiroki? 2005-11-13 (日) 12:05:13
  • 確認できました〜^^ -- kz3 2005-11-13 (日) 12:26:26
  • あらら 移植版が載ってる。 (^^;) -- hiroki? 2005-11-13 (日) 17:19:52
  • Zオーダー・移動の調整90%終了。でもなんかパっとしない・・・ -- kz3 2005-11-14 (月) 09:29:01
  • とりあえずいいっか、一回出してみよう(・公・# -- kz3 2005-11-14 (月) 09:37:14
  • ウィンドウのリザイズには対応してません^^ -- kz3 2005-11-14 (月) 10:17:33
  • ウィンドウサイズを400x400じゃなくて200+rnd(3)*100のように可変にしておいたほうがより良かったかも。。。 -- kz3 2005-11-14 (月) 10:21:57
  • 謎の再利用仕様はリングバッファの割り当てでそうなってます。BACKWARD()で前面から後ろに検索、という仕様にすればすぐに再利用できたり。。。 -- kz3 2005-11-14 (月) 10:30:25
  • いやいや、むしろそっちの方が前面から後ろにBACKWARD()と文章的にも意味が通ってくるので「_b」を外したバージョンでそのようにしてみます。 -- kz3 2005-11-14 (月) 10:32:44
  • いやいやいや、すぐに再利用してしまうと「リングバッファ」が「リングバッファ」として使われないんです^^;これは検索方向をBACKWARD()にしても同じ。。。 -- kz3 2005-11-14 (月) 10:43:12
  • 「_a」をアップ。まぁタイトルバーなしウィンドウbgscrだと考えてくれればいいです。タイトルはただ単にIDとサイズの確認・閉じる為にあるということで・・・ -- kz3 2005-11-14 (月) 11:17:06
  • なかなか...感動! -- hiroki? 2005-11-14 (月) 11:48:51
  • zOrderによって管理されたZオーダーで、マウス座標からどのウィンドウのクライアント領域にあるのかを、前面frontから後ろへ向かって順に検索するというアルゴリズムを考えましたm_ _m -- kz3 2005-11-14 (月) 12:18:20
  • それ考えてるんだけど、やはりデスクトップ座標から調べないとダメかな。 -- hiroki? 2005-11-14 (月) 12:31:36
  • ん?どういうことですか?? -- kz3 2005-11-14 (月) 12:37:51
  • つまり、マウス操作が必要なウインドーにマウスが入ったときに認識する方法。いまいち意味が...? -- hiroki? 2005-11-14 (月) 13:12:07
  • あ、もしかしたら・・・もっとスマートな方法があるかも。今、閃いたのでテスト中。 -- kz3 2005-11-14 (月) 13:25:45
  • Win32メッセージにはメッセージを受け取ったウィンドウハンドルというものが一緒にプロシージャに渡されるので、それをHSPでどう取得するのかとoncmdのヘルプを見ていたらginfo(24)がそのようです。HSPで使えるようにウィンドウIDという形なので速攻使えます。ウィンドウはWM_MOUSEMOVEを受け取るということは、メッセージを捕まえてやればいい。注意としてはプロシージャに処理を渡さないとmousex,y関連のシステム変数が更新されません。このことから上の「考える」は正しかったということかな・・・。filev3_021_ginfo24.hsp -- kz3 2005-11-14 (月) 13:54:31
  • いまいち描画ウィンドウ切り替わるときに変な位置に表示されますが、ginfo(24)覚えられたので良しとします^^ -- kz3 2005-11-14 (月) 13:59:50
  • おーーーーーっ これすごいです。 まだ手つかずのpaintetc.hspに使える。 -- hiroki? 2005-11-14 (月) 15:31:06
  • 問題は、stickやonkeyとの併用が可能かどうか -- hiroki? 2005-11-14 (月) 15:39:53
  • そかそか oncmdを使わなくても、if ginfo(24)= でもいいんですね。 -- hiroki? 2005-11-14 (月) 15:43:14
  • だめでした。 oncmd抜きでは、0のままでした。 -- hiroki? 2005-11-14 (月) 15:51:42
  • いやダメです。ginfo(24)はoncmdで既存のHSPウィンドウプロシージャにメッセージが渡される前に指定したラベルに処理を割り込ませ(サブクラス化と考えていいかも。)た時にメッセージを横取りしたウィンドウIDなので、oncmdを使わないということはメッセージの横取りをしませんよ、ということなのでダメだと思いますが・・・ -- kz3 2005-11-14 (月) 15:54:50
  • 言う前に試しちゃったのね^^; -- kz3 2005-11-14 (月) 15:55:16
  • stickの併用は出来ると思いますよ。キーとマウスメッセージは違いますから〜 -- kz3 2005-11-14 (月) 15:56:13
  • 実装したら、線とか円とか四角とか書いてくれなくなりました。 こらまた悩む時間がかかりそう。(T_T) -- hiroki? 2005-11-14 (月) 16:13:54
  • 例えば、ID0でクリックを監視し(プログラムもID0のみ使用)、仮にクリックされてそこがID0のウインドウ内かどうかの判定に、oncmdとginfo_selの使用は不可能と判明しました。 理由は、ID0外にマウスが出た時にもクリックの判定は可能だけど、oncmdは機能せずginfo_selはID0のままになります。使えると思ったのに...。 -- hiroki? 2005-11-14 (月) 19:01:08
  • ginfo24ファイルですが、マウスの位置をシステム変数で取得していましたが、バカでした。どうバカなのかは置いといて、WM_MOUSEMOVEを処理したらマウス座標はlparamを使うべきです。というわけでfilev3_021_ginfo24.hsp差し替えましたorz -- kz3 2005-11-15 (火) 08:54:59
  • 同じ動きだと思うけど、こうしないとダメなの? -- hiroki? 2005-11-15 (火) 09:35:04
  • はい、ダメです。mousex,yはWM_MOUSEMOVEで処理されて(と仮定)初めて、座標が設定されますが、oncmdはその本来の処理の前に指定したラベルに飛んで処理をして「return」で本来の処理をします。以前のはまだ設定されていないmousex,yを使っていたので挙動がおかしかったわけです。というわけで一応、前のヤツもUPしておきますorz -- kz3 2005-11-15 (火) 09:58:10
  • 以前のコードはソースに埋め込み、コメントで解説しています^^;(面倒だったorz) -- kz3 2005-11-15 (火) 10:17:49
  • クリックの件はoncmdを使うならクリックに対応するメッセージを指定しないとダメですよ、WM_LBUTTONDOWNなど・・・。 -- kz3 2005-11-15 (火) 10:25:51
  • なかなか難しいもんですね。 コンピーターって...(>_<) -- hiroki? 2005-11-15 (火) 12:05:23
  • 今現在のPaintectを添付しました。 昔の添付がどこかに消えた。 -- hiroki? 2005-11-20 (日) 15:43:39
  • wiki右上の検索ボックスでfilePaintEt.hspにありましたよ。 -- kz3 2005-11-20 (日) 15:45:47
  • ちなみにツールでウィンドウを作るとき、表示位置を(x,0)というようにディスプレイ上部を左上とした時、上部にツールバーを表示している人(僕がそうです)だとそのウィンドウがツールバーの下に(キャプションバーが)隠れたりするので注意です^^; -- kz3 2005-11-20 (日) 15:55:58
  • ご指摘通り、そうなんですよー。 へへ -- hiroki? 2005-11-20 (日) 16:09:47

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

*1 (⊂=((・公・#
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-08 (日) 02:39:19 (2436d)