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


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0505
さか縦または横サイズ変更で正方形に4解決


さか

リンク

2020/5/5(Tue) 19:54:48|NO.90288

縦または横サイズ変更でウィンドウを正方形にしたいのですが
何かスマートな方法ってありますでしょうか。
普通に考えるとginfo_winx、ginfo_winyでサイズ取得、widthでサイズ変更
なんですが中々単純でないのですよね。


#include "user32.as" GetWindowLong hwnd, -16 SetWindowLong hwnd, -16, stat | $40000 // 可変枠追加 oncmd gosub *resize, 0x0005 // リサイズ stop *resize oncmd 0 ;ここで正方形に oncmd 1 return 0



この記事に返信する


TOMATO

リンク

2020/5/5(Tue) 20:10:30|NO.90289

この辺を移植すれば動くと思います
https://hp.vector.co.jp/authors/VA016117/sizing.html



3k

リンク

2020/5/6(Wed) 16:53:47|NO.90294

遥か昔にやりたいことが同じようなコードを書いたことがあったので、掘り起こしてサンプルとしてこちらに貼っておきます。

結論としては
・WM_SIZINGというメッセージを使うと今回の実装は楽
・WM_SIZINGではユーザーがどの方向でウィンドウを引っ張って変更しようとしているのかが分かる
・かつ、WM_SIZINGで渡ってきたポインタ経由で値を書き換えると、こちらの指定した大きさでウィンドウサイズを固定化できる
という感じです。

本来はウィンドウサイズのアスペクト比固定に使われるものなのですが、正方形にしたいというのもアスペクト比固定の例ですので、転用は可能かなと思います。
WM_SIZINGというキーワードで検索すればHSPのスレッドも引っかかるのですが、あんまりいい感じの処理のがにゃんか見つからなかったです、探し方が悪かったんかな…。

処理として分かりやすいようにサンプルでは横長のウィンドウサイズにしていますが、実際に使う場合はその辺の改造はご自分でお願いします、そんなに難しくはないと思いますが。
おまけで最小ウィンドウサイズも指定できるようになってますが、邪魔だったらその辺は適当に取っ払ってください。

実は探してたのがこれではなかった! とかだったら…その時はすみません。
コメントマシマシで書いたつもりですが分からないところはご随意にツッコミ貰えればと。


// user32のみ使う #include "user32.as" // 定数 #define GWL_STYLE (-16) #define WS_SIZEBOX (0x00040000) #define WM_TIMER (0x0113) #define WM_SIZING (0x0214) // ウィンドウサイズ // ここを変えると正方形含め好きなアスペクト比にできる // 今回はサンプルで分かりやすいように横長にしてる windowSizeX = 500 : windowSizeY = 200 // 最小ウィンドウサイズ windowSizeMinX = 250 : windowSizeMinY = 100 // ウィンドウのアス比固定か isFixWindowAspectRatio = 1 // 自動で求まるもの:ウィンドウのアス比 windowSizeAspectRatio = double(windowSizeX) / double(windowSizeY) // スクリーン作る // ※可変なので最大サイズで作っておく。 //  ディスプレイがもっと大きいかもしれないことを考えるなら、定数で4kとかでもいいかも screen 0, ginfo_dispx, ginfo_dispy, , , , windowSizeX, windowSizeY // 諸々設定 oncmd gosub *winProc_Sizing, WM_SIZING // サイズ変更可に設定 GetWindowLong hwnd, GWL_STYLE windowStyle = stat windowStyle |= (WS_SIZEBOX) SetWindowLong hwnd, GWL_STYLE, windowStyle // チェックボックス pos 10, 2 : objsize 200, 20 : chkbox "ウィンドウサイズアス比固定", isFixWindowAspectRatio // タイマー SetTimer hwnd, 100, 50, 0 oncmd gosub *winProc_Timer, WM_TIMER stop // タイマープロシージャ *winProc_Timer gsel 0 color 222, 222, 222 : boxf 10, 30, 240, 70 color 0, 0, 0 pos 10, 30 : mes "今のウィンドウサイズ" pos 15, 50 : mes strf("(%d, %d)", ginfo_winx, ginfo_winy) return // サイジングプロシージャ *winProc_Sizing if (isFixWindowAspectRatio == 0) : return 1 // クライアントサイズからウィンドウサイズへのマージン計算 gsel 0 tMarginX = ginfo_sizex - ginfo_winx : tMarginY = ginfo_sizey - ginfo_winy // 計算結果出力先 dupptr destLeft, lparam, 4 dupptr destTop, lparam+4, 4 dupptr destRight, lparam+8, 4 dupptr destBottom, lparam+12, 4 // 一回クライアントサイズとして計算 destRight -= tMarginX destBottom -= tMarginY // どの方向のドラッグか switch( wparam ) case 1// 左 case 2// 右 twidth = limitf(destRight - destLeft, windowSizeMinX, ginfo_dispx) // 押し返す if (wparam == 1) { destLeft = destRight - twidth } else { destRight = destLeft + twidth } // 上下は下を伸ばす destBottom = int(0.0 + destTop + twidth/windowSizeAspectRatio) swbreak case 3// 上 case 6// 下 theight = limitf(destBottom - destTop, windowSizeMinY, ginfo_dispy) // 押し返す if (wparam == 3) { destTop = destBottom - theight } else { destBottom = destTop + theight } // 左右は右を伸ばす destRight = int(0.0 + destLeft + theight*windowSizeAspectRatio) swbreak case 4// 左上 case 5// 右上 case 7// 左下 case 8// 右下 twidth = limitf(destRight - destLeft, windowSizeMinX, ginfo_dispx) theight = limitf(destBottom - destTop, windowSizeMinY, ginfo_dispy) // 小さいほうに合わせる if (twidth >= theight*windowSizeAspectRatio) { // 押し返し分 if (wparam == 4 || wparam == 5) { destTop = destBottom - theight } else { destBottom = destTop + theight } // 辻褄合わせ分 if (wparam == 4 || wparam == 7) { destLeft = int(0.0 + destRight - theight*windowSizeAspectRatio) } else { destRight = int(0.0 + destLeft + theight*windowSizeAspectRatio) } } else { // 押し返し分 if (wparam == 4 || wparam == 7) { destLeft = destRight - twidth } else { destRight = destLeft + twidth } // 辻褄合わせ分 if (wparam == 4 || wparam == 5) { destTop = int(0.0 + destBottom - twidth/windowSizeAspectRatio) } else { destBottom = int(0.0 + destTop + twidth/windowSizeAspectRatio) } } swbreak swend // クライアントサイズからウィンドウサイズへ戻す destRight += tMarginX destBottom += tMarginY return 1



さか

リンク

2020/5/6(Wed) 22:32:03|NO.90299

TOMATOさん、3kさん、ありがとうございます。
3kさんのにTOMATOさんの紹介してくれたWM_SIZING入ってますね。

3kさんの良さそうですね。
ポイントとしてはサイズ変更イベント内でサイズ変更してるところ
で工夫が必要なのかなと思います。
クライアントサイズとウィンドウサイズの考慮もしてますね。

必要なところを抜き出させて使わせてもらいます。



さか

リンク

2020/5/6(Wed) 23:08:04|NO.90300

結果、こうさせてもらいました。左上だけちょっと変な動きですが。

#include "user32.as" GetWindowLong hwnd, -16 SetWindowLong hwnd, -16, stat | $40000 // 可変枠追加 oncmd gosub *resize, 0x0214 ;WM_SIZING stop *resize oncmd 0 dupptr destLeft, lparam, 4 dupptr destTop, lparam+4, 4 dupptr destRight, lparam+8, 4 dupptr destBottom, lparam+12, 4 title strf( "%d %d %d %d %d", wparam, destLeft, destTop, destRight, destBottom ) switch( wparam ) case 1// 左 case 2// 右 case 7// 左下 case 8// 右下 destBottom = destTop + destRight - destLeft swbreak case 3// 上 case 6// 下 case 4// 左上 case 5// 右上 destRight = destLeft + destBottom - destTop swbreak swend oncmd 1 return 0
解決とさせていただきます。ありがとうございました。



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