|
|
|
2010/4/11(Sun) 13:27:57|NO.31927
こんにちは。
画像ビューアを作ろうと思ってAPIでウィンドウにスクロールバーを付けたのですが
ドラッグでウィンドウを最大サイズにしたときスクロールバーが消えません。
横方向にドラッグすると消えます。また機能的には無効になっているようです。
環境はVista 64bitです。よろしくお願いします。
#uselib "user32.dll"
#func global GetWindowLong "GetWindowLongA" int, int
#func global SetScrollInfo "SetScrollInfo" int, int, int, int
#func global SetWindowLong "SetWindowLongA" int, int, int
#func global SetWindowPos "SetWindowPos" int, int, int, int, int, int, int
#define global WM_SIZE 0x5
#define global WS_VSCROLL 0x200000
#define global GWL_STYLE -16
#define global SWP_NOSIZE 0x1
#define global SWP_NOMOVE 0x2
#define global SWP_NOZORDER 0x4
#define global SWP_FRAMECHANGED 0x20
#define global SB_VERT 1
#define global SIF_RANGE 0x1
#define global SIF_PAGE 0x2
#define global SIF_POS 0x4
#define global SIF_TRACKPOS 0x10
#const global SIF_ALL SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
#define global TRUE 1
gsel 0, -1
xpic = 640
ypic = 480
screen 1, xpic, ypic, 0, 0, 0, xpic / 3, ypic / 4
picload dirinfo(1) + "/sample/demo/sky_bg.jpg", 1
oncmd gosub *MESSAGE, WM_SIZE
dim si, 7
si.0 = 28
si.1 = SIF_ALL
si.2 = 0
si.3 = ypic - 1
si.5 = 0
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat | WS_VSCROLL
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED
stop
*MESSAGE
ip = iparam
lp = lparam
if ip == WM_SIZE {
si.4 = wpeek(lp, 2)
SetScrollInfo hwnd, SB_VERT, varptr(si), TRUE
}
return
| |
|
2010/4/11(Sun) 16:24:49|NO.31933
追記:
調べてみて nPage > (nMax - nMin + 1) のときスクロールバーが消えるらしいので
No.31927 のスクリプトではスクロールバーは消えなくて当然だと思ったのですが
ウィンドウを縦方向に最大にしてから横方向へスクロールすると消えるんですよね…
ページサイズを si.4 = wpeek(lp, 2) + 1 などとクライアントサイズより少し大きめに
設定すると消えるのですが、消えないときや、再度ウィンドウを縮小したときに出現する
ときとしないときがあり安定しません。
引き続きよろしくお願いします。
|
|
2010/4/12(Mon) 01:33:14|NO.31943
こんな方法はいかがでしょうか。
#uselib "user32.dll"
#func global GetWindowLong "GetWindowLongA" int, int
#func global SetScrollInfo "SetScrollInfo" int, int, int, int
#func global SetWindowLong "SetWindowLongA" int, int, int
#func global SetWindowPos "SetWindowPos" int, int, int, int, int, int, int
#define global WM_SIZE 0x5
#define global WS_VSCROLL 0x200000
#define global GWL_STYLE -16
#define global SWP_NOSIZE 0x1
#define global SWP_NOMOVE 0x2
#define global SWP_NOZORDER 0x4
#define global SWP_FRAMECHANGED 0x20
#define global SB_VERT 1
#define global SIF_RANGE 0x1
#define global SIF_PAGE 0x2
#define global SIF_POS 0x4
#define global SIF_TRACKPOS 0x10
#const global SIF_ALL SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
#define global TRUE 1
gsel 0, -1
xpic = 640
ypic = 480
screen 1, xpic, ypic, 0, 0, 0, xpic / 3, ypic / 4
picload dirinfo(1) + "/sample/demo/sky_bg.jpg", 1
oncmd gosub *MESSAGE, WM_SIZE
dim si, 7
si.0 = 28
si.1 = SIF_ALL
si.2 = 0
si.3 = ypic; - 1 ←バーが残るようにする
si.5 = 0
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat | WS_VSCROLL
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED
stop
*MESSAGE
ip = iparam
lp = lparam
if ip == WM_SIZE {
si.4 = wpeek(lp, 2)
SetScrollInfo hwnd, SB_VERT, varptr(si), TRUE
}
if ginfo(13) == ypic && hHidden == 0 {//最大サイズなら
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat ^ WS_VSCROLL//スクロールバーを消す
fHidden = 1//非表示フラグ
}else{
if fHidden == 1{
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat | WS_VSCROLL//スクロールバーを付ける
fHidden = 0
}
}
return
| |
|
2010/4/12(Mon) 03:16:15|NO.31946
どうも無くなったスクロールバー部分の再描画がされてないので
スクロールバーの表示だけが残っている様です。
(だからスクロールバーは使えなくなる)
なのでウィンドウサイズをチェックしておいて最大幅になったら
width命令でウィンドウ全体を再描画させるとスクロールバーも消えてくれました。
(ちょっと不自然かもしれませんが・・・)
#include "user32.as"
#define global WM_SIZE 0x5
#define global WS_VSCROLL 0x200000
#define global GWL_STYLE -16
#define global SWP_NOSIZE 0x1
#define global SWP_NOMOVE 0x2
#define global SWP_NOZORDER 0x4
#define global SWP_FRAMECHANGED 0x20
#define global SB_VERT 1
#define global SIF_RANGE 0x1
#define global SIF_PAGE 0x2
#define global SIF_POS 0x4
#define global SIF_TRACKPOS 0x10
#define global SIF_ALL 0x17
#define global TRUE 1
#define global SM_CXVSCROLL $00000002
#define global WM_VSCROLL $00000115 ;垂直スクロールメッセージ
gsel 0, -1
xpic = 640
ypic = 480
screen 1, xpic, ypic, 0, 0, 0, xpic / 3, ypic / 4
picload dirinfo(1) + "/sample/demo/sky_bg.jpg", 1
oncmd gosub *MESSAGE, WM_SIZE
oncmd gosub *SCROLL, WM_VSCROLL
dim si, 7
si.0 = 28
si.1 = SIF_ALL
si.2 = 0
si.3 = ypic - 1
si.4 = 0
si.5 = 0
si.6 = 0
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat | WS_VSCROLL
SetScrollInfo hwnd, SB_VERT, varptr(si), 1
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED
GetSystemMetrics SM_CXVSCROLL :sb_w=stat ;スクロールバーの幅
*main
title ""+win_w+" "+win_h
; 下の処理だとスクロールバーの幅分だけサイズが変わってしまう
;if win_h >= ypic :width win_w, win_h
wait 10
goto *main
stop
*MESSAGE
oncmd 0
ip = iparam
lp = lparam
win_w = wpeek(lp, 0)
win_h = wpeek(lp, 2)
if ip == WM_SIZE {
si.4 = win_h
SetScrollInfo hwnd, SB_VERT, varptr(si), TRUE
}
; 下の処理だと下までドラッグした時の挙動が不自然に
if win_h >= ypic {
;ShowScrollBar hwnd, SB_VERT, 0 ;無くても良いかも?
width win_w, win_h
} else {
;ShowScrollBar hwnd, SB_VERT, 1
width win_w+sb_w, win_h
}
oncmd 1
return
*SCROLL
oncmd 0
ip=iparam
wp=wparam
lp=lparam ;スクロールしているスクロールバーのハンドル
bar_pos=(wp>>16)&$ffff ;wparamの上位ワード(nPos)
wp=wp&$ffff ;wparamの下位ワード(通知コード)
GetScrollInfo hwnd, SB_VERT, varptr(si)
switch wp
case 0 ;SB_LINELEFT or SB_LINEUP
si(5)-=1
swbreak
case 1 ;SB_LINERIGHT or SB_LINEDOWN
si(5)+=1
swbreak
case 2 ;SB_PAGELEFT or SB_PAGEUP
si(5)-=10
swbreak
case 3 ;SB_PAGERIGHT or SB_PAGEDOWN
si(5)+=10
swbreak
case 5 ;SB_THUMBTRACK
si(5)=bar_pos
swbreak
swend
SetScrollInfo hwnd, SB_VERT, varptr(si), 1
groll 0, si(5)
oncmd 1
return
>また機能的には無効になっているようです
この部分の意味を取り違えていたのでスクロール処理まで
入れてしまいました、スクリプトが長くなってしまってすみません(汗)
| |
|
2010/4/13(Tue) 00:20:10|NO.31959
uさん、ありさんご回答ありがとうございます。
uさんの方は私のと挙動が似てますね?
おまけにスクロールバーが付いたり消えたりします><
ありさんの方はスクロール機能を付けてくれたんですね。
確かに消える!けどウィンドウサイズが一定しない、と。
>どうも無くなったスクロールバー部分の再描画がされてないので
>スクロールバーの表示だけが残っている様です。
>(だからスクロールバーは使えなくなる)
私もさらに調べてみたんですけど、ウィンドウを最大にしたときは
スクロールバーは自前で消去しなきゃならないみたいです。
C言語系の解説サイトでWM_PAINTメッセージで処理している部分が
それなんですが、スクロールバーと関係があると思わなかったので
スルーしてました…
で、↓が改良版。サムをドラッグでスクロールします。
お2人ともありがとうございました。
#uselib "user32.dll"
#func global GetWindowLong "GetWindowLongA" int, int
#func global SetScrollInfo "SetScrollInfo" int, int, int, int
#func global SetWindowLong "SetWindowLongA" int, int, int
#func global SetWindowPos "SetWindowPos" int, int, int, int, int, int, int
#define global WM_SIZE 0x5
#define global WM_PAINT 0xF
#define global WM_VSCROLL 0x115
#define global WS_VSCROLL 0x200000
#define global GWL_STYLE -16
#define global SWP_NOSIZE 0x1
#define global SWP_NOMOVE 0x2
#define global SWP_NOZORDER 0x4
#define global SWP_FRAMECHANGED 0x20
#define global SB_VERT 1
#define global SB_THUMBTRACK 5
#define global SIF_RANGE 0x1
#define global SIF_PAGE 0x2
#define global SIF_POS 0x4
#define global SIF_TRACKPOS 0x10
#const global SIF_ALL SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
#define global TRUE 1
gsel 0, -1
wid_main = 1
wid_buf = 2
;バッファに画像をロード
buffer wid_buf
picload dirinfo(1) + "/sample/demo/sky_bg.jpg"
xpic = ginfo(12)
ypic = ginfo(13)
;画像の右端と下端が分かるように線を引く
color 255, 0, 0
line xpic, ypic - 1, 0, ypic - 1
line xpic - 1, ypic, xpic - 1, 0
;メインウィンドウを作成
screen wid_main, xpic, ypic, 0, 0, 0, xpic / 2, ypic / 2
gcopy wid_buf, 0, 0, xpic, ypic
oncmd gosub *MESSAGE, WM_SIZE
oncmd gosub *MESSAGE, WM_PAINT
oncmd gosub *MESSAGE, WM_VSCROLL
dim si, 7
si.0 = 28
si.1 = SIF_ALL
si.2 = 0
si.3 = ypic - 1
si.5 = 0
si.6 = 0
GetWindowLong hwnd, GWL_STYLE
SetWindowLong hwnd, GWL_STYLE, stat | WS_VSCROLL
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED
stop
*MESSAGE
ip = iparam
lp = lparam
wp = wparam
switch ip
case WM_SIZE
xclient = wpeek(lp, 0)
yclient = wpeek(lp, 2)
si.4 = yclient
if yclient >= si.3 + 1 { ;スクロールバーが消去されるならばサムの位置を初期化
si.5 = si.2
}
SetScrollInfo hwnd, SB_VERT, varptr(si), TRUE
swbreak
case WM_VSCROLL
switch wpeek(wp, 0)
case SB_THUMBTRACK
si.5 = wpeek(wp, 2)
swbreak
swend
groll 0, si.5
SetScrollInfo hwnd, SB_VERT, varptr(si), TRUE
swbreak
case WM_PAINT
pos ginfo(8), ginfo(9)
gcopy wid_buf, ginfo(8), ginfo(9), xclient, yclient
swbreak
swend
return
| |
|