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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0811
チャーくん横方向 だ け に ドラッグできるウィンドウ5解決


チャーくん

リンク

2014/8/11(Mon) 19:34:38|NO.63715

またまた質問です。
ドラッグできるウィンドウはサンプルにあるのでできるのですが、
それだとx方向とy方向両方に移動してしまいます。x方向だけに、ドラッグできるウィンドウは
できるのですか?
それから、もしよければ、ドラッグ中にもウィンドウの更新をさせる方法を知っていたら、
教えてください。
よろしくお願いします。



この記事に返信する


FunnyMaker

リンク

2014/8/11(Mon) 21:45:43|NO.63725

1つ目の問、横方向のみ移動したい? これは簡単ですね。yを無視すればいいです。

次の問が難しいでしょうね。
多分、今までループでマウスを監視していたのでしょう。
それではドラッグ中に他の処理を進めることは難しいです。できなくはないですが、
少々テクニック(というかタスクの分割。要は自分でms単位の仕事の時間割を組む。)が必要で、仰々しいプログラムになってしまうでしょう。
そんなことをしなくても、「割り込み」を使えば大分楽に実装できます。
そのためにWinAPIを使います。

↓こんなのでどうでしょうか?


*define ;< System > ;< libs > #uselib "user32.dll" #func MoveWindow "MoveWindow" int, int,int, int,int, int ;< GUI > ;< WindowMessage > #define WM_LBUTTONDOWN 0x0201 #define WM_LBUTTONUP 0x0202 #define WM_MOUSEMOVE 0x0200 *Mkwindow ;< screen0 > #define WITH_SCR0 400 #define HEIGHT_SCR0 300 bgscr 0,WITH_SCR0,HEIGHT_SCR0,0 hwnd_scr0 = hwnd oncmd gosub *Interrupt_WM_LBUTTONDOWN, WM_LBUTTONDOWN oncmd gosub *Interrupt_WM_LBUTTONUP, WM_LBUTTONUP oncmd gosub *Interrupt_WM_MOUSEMOVE, WM_MOUSEMOVE pos_scr0_prev = 0,0 pos_mouse_scr0_prev = -1,-1 *Main ;例えばアプリケーションの本業が以下であるとする。(※defineはプリプロセスで消化されるので「業」ではない) ;▽+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++▽ #define INTERVAL_LOOP 10 #define RADIUS 50 #define FONTSIZE 20 #define Math_a 3.0 #define Math_b 1.0 #define Math_α 1.0 #define Math_β 2.0 BgColor = 200,200,200 MesColor = 100,100,100 θ = 0.0 Δθ = deg2rad(90) ;〔rad/sec〕 font msgothic, 25,0 repeat redraw 0 color bgcolor(0),bgcolor(1),bgcolor(2) : boxf θ += Δθ*INTERVAL_LOOP/1000 pos WITH_SCR0/2 + Math_α*cos(Math_a*θ)*RADIUS - 160, HEIGHT_SCR0/2 + Math_β*sin(Math_b*θ)*RADIUS - FONTSIZE color MesColor(0),MesColor(1),MesColor(2) mes "ドラッグ中も制御はHSPに。" redraw 1 await INTERVAL_LOOP loop ;△+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++△ *Interrupt_WM_LBUTTONDOWN pos_scr0_LastMouseLButtonDown = ginfo_wx1, ginfo_wy1 pos_mouse_scr0_LastMouseLButtonDown = mousex, mousey return *Interrupt_WM_LBUTTONUP return *Interrupt_WM_MOUSEMOVE ;ウィンドウのドラッグ処理 getkey KeyCode_LButton_Mouse, 1 if KeyCode_LButton_Mouse = 0 : return ;左ボタンが押されていなければここでおしまい oncmd 0 MoveWindow hwnd_scr0, ginfo_mx - pos_mouse_scr0_LastMouseLButtonDown(0), pos_scr0_LastMouseLButtonDown(1), WITH_SCR0,HEIGHT_SCR0, 1 wait 0 oncmd 1 return

忙しいのでコメントは付けていません。
コードをもとになるべく自分で調べて考えてください。(アルゴリズム的なところは特に。いちいち説明するとキリがないので。)

ググるといいかもしれないヒントのワードを挙げておきます。
「WinAPI」
「割り込み」
「ウィンドウメッセージ」

分からないところがあったら後で聞いてください。時間が許せば回答します。

そうこうしているうちに、もっとエレガントなソリューションを提案してくれる人がいるかもしれません...。



チャーくん

リンク

2014/8/11(Mon) 21:57:23|NO.63726

Wow...!
まさに、望みどおりのスクリプトです!
忙しいのに、すぐに回答してくださりありがとうございます。



FunnyMaker

リンク

2014/8/11(Mon) 22:02:02|NO.63727

つでに...。

先ほど
「WinAPI」でググるといい、と言いましたが、やっぱり「API」で検索した方が無難ですね。
APIというのはWindowsに限った話じゃないですし、"Win"APIの真髄を理解する差し迫った必要性も無いでしょうしね。
「ほう、APIっちゅうのはこういうモンか...。」程度でいいと思います。

ではがんばってください。



掘木

リンク

2014/8/11(Mon) 23:05:41|NO.63730

別方針で考えてみた。

移動範囲制限は自分で移動を記述しなくとも、WM_MOVINGのlparamを弄ることで実現できます。
そして、タイマー駆動にしてしまえばドラッグ中の実行停止の影響を無視できるよね
・・・と、やった結果がこれである。

#uselib "user32.dll" #func SetTimer "SetTimer" int,int,int,nullptr #func KillTimer "KillTimer" int,int,int #define global MYTIMERID 128 // タイマーに付ける番号 #define global TIMERCOUNT 12 // WM_TIMERが発生する間隔(ms) #define global WM_MOVING 0x0216 #define global WM_TIMER 0x0113 iBoxX = 0 iBoxY = 0 iBoxdX = 10 iBoxdY = 10 iBoxSize = 80 // oncmdによる移動検出 oncmd gosub *moving , WM_MOVING // 動作は全部timer任せにする oncmd gosub *timer,WM_TIMER // タイマー設置 SetTimer hwnd,MYTIMERID,TIMERCOUNT onexit *quit stop *quit // タイマーの処分 KillTimer hwnd,MYTIMERID end //移動先の検出(y方向移動をなかったことにする) *moving dupptr p1,lparam,4*4,vartype("int") // 4 * sizeof(LONG) p1(1) = ginfo(5) : p1(3) = ginfo(7) dim p1 // アドレスが無効になるので dup状態から解放しとく。 return // メイン部分相当 *timer redraw 0 color 255,255,255 : boxf color : boxf iBoxX-iBoxSize,iBoxY-iBoxSize,iBoxX+iBoxSize,iBoxY+iBoxSize iBoxX += iBoxdX iBoxY += iBoxdY if ( iBoxX < 0 || iBoxX > 640 ) : iBoxdX *= -1 if ( iBoxY < 0 || iBoxY > 480 ) : iBoxdY *= -1 redraw 1 return
サンプルに実行部分にはバウンディングボックスを入れておきました。
なんというか蛇足感満点だなこりゃ。WM_TIMERの発生タイミングに難があるんだよなあ。



チャーくん

リンク

2014/8/12(Tue) 15:42:59|NO.63748

みなさん、回答ありがとうございます。
とりあえず、満足する形になりました。
また質問すると思いますが、そのときは、またよろしくお願いします。



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