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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0701
スペースウィンドウレイアウトを自由に変更8解決


スペース

リンク

2015/7/1(Wed) 21:17:22|NO.69925

この様にウィンドウレイアウトを自由に変更するソフトを作りたいのですが、
どうすれば作れるのでしょうか?

http://gyazo.com/98159a26e2cd0029b9f18f3ba8f2c648



この記事に返信する


kanamaru

リンク

2015/7/1(Wed) 21:34:14|NO.69926

hspだとかなり難しいと思います。
この掲示板にオブジェクトを移動できるようにしたプログラムがあるので、
それを基本として、
とある位置にきたらgselで消していたウィンドウにそのオブジェクトと同じ見た目の
オブジェクトを配置して元のウィンドウのオブジェクトは消して…

作るにはマルチスレッドが必要です。



cats

リンク

2015/7/2(Thu) 16:41:01|NO.69932

基本的にはoncmdによるメッセージの監視です。
私の知る限りこれを実装するための関数などは無いので、
まずは自分で仕様をしっかりと決めることが大切です。
提示されたリンク先のものでは、滑らかにウィンドウを挿入したり、
サイズに合わせてフォーム全体を変形しています。
ここまでの機能のものは面倒でしょうが、必要なのであれば作ってみる価値はあります。
あまりプログラムの方面に触れられなくてすいませんが、参考までに。



スペース

リンク

2015/7/2(Thu) 19:07:09|NO.69935

kanamaruさん
catsさん

返信有難うございます。
各部分を子ウィンドウ化してウィンドウの移動をoncmdで検出してなんやかんや・・・という感じですかね。
それだけでももの凄く面倒・・・

他力本願で申し訳ないのですが、誰かがこういう奴の関数とかを教えてくれるのを待ってみます。
せめてこういう奴の名前だけでも知ることができれば検索しやすいのですが・・・



科学太郎

リンク

2015/7/3(Fri) 07:16:40|NO.69941

> 他力本願で申し訳ないのですが、誰かがこういう奴の関数とかを教えてくれるのを待ってみます。
> せめてこういう奴の名前だけでも知ることができれば検索しやすいのですが・・・
画像を見たところMDI(マルチ・ドキュメント・インターフェイス)です。
ネットで「HSP MDI」検索すると何か出ましたよ。

・MDI(Multiple Document Interface)
https://ja.wikipedia.org/wiki/Multiple_Document_Interface

・MDIの実装
http://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200604/06060038.txt

・MDIの実装について
http://hsp.tv/play/pforum.php?mode=pastwch&num=29078

・コールバック用モジュールができました
http://hsp.tv/play/pforum.php?mode=all&num=62130

あとプロシージャを使うためコールバック関数を使えるスクリプトも必要でしょう。
なお、実装が本当に可能かどうかは、私は現在試してません。
API関数の知識で行くとコールバック関数が使えれば実装できそうなんですけど。



科学太郎

リンク

2015/7/3(Fri) 07:20:21|NO.69942

追記。

あと「MDI ドッキング」検索も行った方が良いかもせれない。



スペース

リンク

2015/7/3(Fri) 18:24:29|NO.69944

>>科学太郎さん
ありがとうございます。

なるほど、MDIと言うんですか。
参考になるサイトをまとめて頂き有難うございます。
じっくり読み、自分でもMDIの事をもう少し調べてみます。



774

リンク

2015/7/4(Sat) 18:35:47|NO.69949

この場合 Rebar,CoolBar,ドッカブルウィンドウ(ツールバー) 等にあたるのではないでしょうか?
(件のソフト自体MDIかも知れませんが、画像ではドキュメント開いてませんし…)

Rebar だとするとコチラの方に一応情報はありますが、(英語)
>>https://msdn.microsoft.com/en-us/library/windows/desktop/bb774375%28v=vs.85%29.aspx
挙動や状態管理の大部分は自前で行い、それをOS準拠で表現する部分だけ用意されてるような感じです。

OS準拠に拘らなければ全部自前でやった方が簡単そうですので
ドッカブルっぽいサンプルを…

#define global col_invert Color gInfo.16^$ff,gInfo.17^$ff,gInfo.18^$ff ;色反転 #define global a_wnd _g_array_wnd@ #define global a_id _g_array_id@ Dim a_wnd,3 ;hWnd保持用 Dim a_id :a_id=2 ;子ウィンドウ用ID #module #uselib "user32.dll" #func _ScreenToClient "ScreenToClient" sptr,var #func _GetClientRect "GetClientRect" sptr,var #func _SetParent "SetParent" sptr,sptr #cfunc _GetWindowLong "GetWindowLongA" sptr,int #func _SetWindowLong "SetWindowLongA" sptr,int,int #func _SetWindowPos "SetWindowPos" sptr,sptr,int,int,int,int,int #func _GetWindowRect "GetWindowRect" sptr,var #func _SetLayeredWindowAttributes "SetLayeredWindowAttributes" sptr,int,int,int ;--SetWindowLongラッパ(hWnd, OR=0, AND=$FFFFFFFF, type=-16[GWL_Style]) <stat:preValue> #define global wnd_WindowLong(%1,%2=0,%3=$ffffffff,%4=-16) _wnd_WindowLong %1,%2,%3,%4 #deffunc _wnd_WindowLong int p0, int p1, int p2, int p3 _SetWindowLong p0,p3,(_GetWindowLong(p0,p3)&p2)|p1 Return stat ;--スクリーン座標がクライアント領域内か返す(X, Y, hWnd) = hWnd/0 #defcfunc wnd_CheckInside int p0, int p1, int p2, local a Dim a,4 :_GetClientRect p2,a :If(stat==0){Return 0} a.0=p0,p1 :_ScreenToClient p2,a If(a.0==Limit(a.0,0,a.2-1))&&(a.1==Limit(a.1,0,a.3-1)){Return p2} Return 0 ;--レイヤウィンドウ化(hWnd,Alpha[0-255]) #deffunc wnd_Layered int p0, int p1 wnd_WindowLong p0,$80000,,-20 _SetLayeredWindowAttributes p0,0,p1&$ff,2 Return stat ;--ウィンドウ移動(hWnd,X,Y,W,H) #define global wnd_SetPos(%1,%2=$80000000,%3=$80000000,%4=0,%5=0) _wnd_SetPos %1,%2,%3,%4,%5 #deffunc _wnd_SetPos int p0, int p1, int p2, int p3, int p4, local a a=$220 :If((p1|p2)==$80000000){a|=2} :If((p3|p4)==0){a|=1} _SetWindowPos p0,0,p1,p2,p3,p4,a Return stat ;--ダミーで移動() #deffunc wnd_MoveDummy local a, local b Dim a,5 :a.0=gInfo.4,gInfo.5,gInfo.10,gInfo.11,ginfo.3 a_wnd.2=hWnd :gSel 1 :gMode 0,a.2,a.3 :Pos 0,0 :gCopy a.4 wnd_SetPos hWnd,a.0,a.1,a.2,a.3 :gSel 1,1 SendMsg hWnd,$00a1,2 ;WM_NCLButtonDown gSel 1,-1 :a.0=gInfo.4,gInfo.5 If(wnd_CheckInside(gInfo.0,gInfo.1,a_wnd.0)){ wnd_WindowLong a_wnd.2,$56000000,$7fffffff ;子ウィンドウ化 _SetParent a_wnd.2,a_wnd.0 :_ScreenToClient a_wnd.0,a }else{ wnd_WindowLong a_wnd.2,$86000000,$bfffffff ;子ウィンドウ解除 _SetParent a_wnd.2,0 } wnd_SetPos a_wnd.2,a.0,a.1,a.2,a.3 :gSel a.4,1 Return #global *start Randomize :Screen 0,gInfo.20,gInfo.21,2,,,640,480 :Title "Base" wnd_WindowLong hWnd,$50000 :wnd_SetPos hWnd SysColor 15 :BoxF :Font msGothic,12 :ObjMode 2 Button gosub "&Add Child",*add_child :a_wnd.0=hWnd BgScr 1,gInfo.20,gInfo.21,2,,,160,120 ;移動用のダミーウィンドウ wnd_Layered hWnd,128 :wnd_WindowLong hWnd,a_wnd.0,,-8 :a_wnd.1=hWnd gSel 0,1 :Gosub *add_child STOP *add_Child ;--子ウィンドウ追加 ;BgScrにタイトルバーとか描いちゃった方が色々やり易いと思います i=Rnd(gInfo.20-160),Rnd(gInfo.21-120) BgScr a_id,gInfo.20,gInfo.21,2,i.0,i.1,160,120 wnd_WindowLong hWnd,a_wnd.0,,-8 ;Baseをオーナー化してタスクバーに出ないように HsvColor Rnd(192),Rnd(128)|128,Rnd(192)+64 :BoxF Font msGothic,10,1 :col_invert :BoxF 3,3,160-4,15 col_invert :Pos 5,4 :Mes StrF("child #%d",gInfo.3) oncmd gosub *cmd_Move@,$0084 ;WM_NCHitTest oncmd gosub *cmd_Move@,$00a1 ;WM_NCLButtonDown oncmd gosub *cmd_Move@,$0005 ;WM_Size gSel gInfo.3,1 :Redraw 0 :a_id++ Return gInfo.3 *cmd_Move ;--移動系のoncmdあれこれ gSel gInfo.24 If(iParam==$0084){;WM_NCHitTest BgScrに通常ウィンドウのような挙動をさせる i=gInfo.0-gInfo.4,gInfo.1-gInfo.5,gInfo.10,gInfo.11,0 ;X,Y,W,H,flg If(i.0<3){i.4|=1} :If(4>(i.2-i.0)){i.4|=4} ;周囲3pxを"ウィンドウの枠"として扱ってます If(i.1<3){i.4|=2} :If(4>(i.3-i.1)){i.4|=8} ;システム既定値で判定するなら GetSystemMetrics 等で取得 If(i.4==0)&&(i.1<16){i.4=16} ;同上,上部12pxをタイトルバーとして Switch i.4 Case 1 : Return 10 ;htLeft Case 2 : Return 12 ;htTop Case 3 : Return 13 ;htTopLeft Case 4 : Return 11 ;htRight Case 6 : Return 14 ;htTopRight Case 8 : Return 15 ;htBottom Case 9 : Return 16 ;htBottomLeft Case 12 : Return 17 ;htBottomRight Case 16 : Return 2 ;htCaption タイトルバー => 移動 Default : Return 1 ;htClient swEnd } If(iParam==$0005){;WM_Size タイトルバー部分だけ描画 i=gInfo.10 :pGet 0,0 :BoxF 0,0,i-1,15 col_invert :BoxF 3,3,i-4,15 col_invert :Pos 5,4 :Mes StrF("child #%d",gInfo.3) Redraw 1 :Redraw 0 } ;WM_NCLButtonDown 子ウィンドウは親の外へ出せないので、移動はダミーで行う If(iParam==$00a1)&&(wParam==2){wnd_MoveDummy :Return 0} Return



スペース

リンク

2015/7/4(Sat) 22:19:53|NO.69955

>>774さん
ありがとうございます。
非常にわかりやすいサンプル有難うございます。
とりあえずある程度は自前で処理しようかと思います。

皆さん、ありがとうございました。



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