| 
					 
							
						
								
									  | 
								 
							 							 
							
						 
						
 
 | 
 | 
 
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 
 
 
  |    |   
  
					 |