|
 |
|
2018/8/23(Thu) 11:13:47|NO.85167
画像のビューアーを作っています。
ウィンドウのサイズを変更したりするときにドラッグ中も画像のリサイズをしたいと思いまして
WM_TIMERを使ってみたのですが、ウィンドウをドラッグ中にタイマーによる割り込みが入ると
何かがバグって正常に操作を受け付けなくなってしまいます...
しばらくするとランタイムエラーが英語で出てきます。
https://i.imgur.com/VmAx2Um.png
どなたか原因わかりますでしょうか?
HSPは3.51でOSはWindows10 Proです。
以下スクリプトです。
#include "user32.as"
#define WM_TIMER 0x0113
#define timer_id 1 ; タイマーID (0 以外の値)
oncmd gosub *OnTimer, WM_TIMER
onexit *exit
screen 0, ginfo(20), ginfo(21):gosub*bg
; 自ウィンドウのスタイルを変更
; $10000 = 最大化ボタン有効
; $40000 = ウィンドウサイズ可変有効
GetWindowLong hwnd, -16
SetWindowLong hwnd, -16, stat | $10000 | $40000
; 実際に表示するサイズを指定
width 1290, 730
dialog "",16,"":file=refstr:if refstr="":end
ex=getpath(refstr,2):font"",10
if start=0:buffer 1,10,10:start=1:else:gsel 1
if ex=".bmp"|ex=".jpg"|ex=".gif"|ex=".ico"|ex=".png":pos 0,0:picload refstr:color 34,34,34:boxf:pos 0,0:picload refstr,1
ix=ginfo(12):iy=ginfo(13) ;画像の大きさ代入
*redrawimage
gsel 0
wx=ginfo(12):wy=ginfo(13):zy=ginfo(12):zx=ginfo(13) ;ウィンドウの大きさ代入
redraw 0
gosub*bg
if ix>wx|iy>wy{
//画面内に収まらない
zx = double(wx) / ix //横幅の倍率
zy = double(wy) / iy //縦幅の倍率
if zx>zy {
;縦が長い
pos (wx-zy*ix)/2,0 ;画像を表示する座標を決定
gzoom zy*ix, wy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
} else {
;横が長い
pos 0,(wy-zx*iy)/2 ;画像を表示する座標を決定
gzoom wx, zx*iy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
}
}else{
//画面内に収まる
gmode 0,ix,iy
pos (wx-ix)/2,(wy-iy)/2
gcopy 1
}
redraw 1
SetTimer hwnd, timer_id, 200, 0
stop
//背景
*bg
color 34,34,34:boxf
return
*OnTimer
if wparam == timer_id:title""+ginfo(12)+" x "+ginfo(13): gosub *redrawimage
return 0

| |
|
2018/8/23(Thu) 11:21:35|NO.85168
*exit
KillTimer hwnd, timer_id
end
すみません一部抜けてました。
|
|
2018/8/23(Thu) 11:36:49|NO.85169
> ウィンドウのサイズを変更したりするときにドラッグ中も画像のリサイズをしたい
この用途なら、タイマーではなく WM_SIZE を使ったほうが良いかと思われます。
タイマーだと定期的に再描画してしまいますが、
WM_SIZE であればリサイズ時のみの再描画になるので。
#include "user32.as"
#define WM_SIZE 0x0005
screen 0, ginfo(20), ginfo(21):gosub*bg
; 自ウィンドウのスタイルを変更
; $10000 = 最大化ボタン有効
; $40000 = ウィンドウサイズ可変有効
GetWindowLong hwnd, -16
SetWindowLong hwnd, -16, stat | $10000 | $40000
; 実際に表示するサイズを指定
width 1290, 730
dialog "",16,"":file=refstr:if refstr="":end
ex=getpath(refstr,2):font"",10
if start=0:buffer 1,10,10:start=1:else:gsel 1
if ex=".bmp"|ex=".jpg"|ex=".gif"|ex=".ico"|ex=".png":pos 0,0:picload refstr:color 34,34,34:boxf:pos 0,0:picload refstr,1
ix=ginfo(12):iy=ginfo(13) ;画像の大きさ代入
gsel 0 : oncmd gosub *resize, WM_SIZE
gosub *redrawimage
stop
*redrawimage
gsel 0
wx=ginfo(12):wy=ginfo(13):zy=ginfo(12):zx=ginfo(13) ;ウィンドウの大きさ代入
redraw 0
gosub*bg
if ix>wx|iy>wy{
//画面内に収まらない
zx = double(wx) / ix //横幅の倍率
zy = double(wy) / iy //縦幅の倍率
if zx>zy {
;縦が長い
pos (wx-zy*ix)/2,0 ;画像を表示する座標を決定
gzoom zy*ix, wy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
} else {
;横が長い
pos 0,(wy-zx*iy)/2 ;画像を表示する座標を決定
gzoom wx, zx*iy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
}
}else{
//画面内に収まる
gmode 0,ix,iy
pos (wx-ix)/2,(wy-iy)/2
gcopy 1
}
redraw 1
return
//背景
*bg
color 34,34,34:boxf
return
*resize
title""+ginfo(12)+" x "+ginfo(13): gosub *redrawimage
return

| |
|
2018/8/23(Thu) 11:43:06|NO.85170
一応、タイマー版も動くように直しました。
gosub *redrawimage で飛んでいるにもかからわず、中で stop してしまっており、
サブルーチンネストを上限まで使い切ってエラーになっている感じでしょうか。
#include "user32.as"
#define WM_TIMER 0x0113
#define timer_id 1 ; タイマーID (0 以外の値)
oncmd gosub *OnTimer, WM_TIMER
onexit *exit
screen 0, ginfo(20), ginfo(21):gosub*bg
; 自ウィンドウのスタイルを変更
; $10000 = 最大化ボタン有効
; $40000 = ウィンドウサイズ可変有効
GetWindowLong hwnd, -16
SetWindowLong hwnd, -16, stat | $10000 | $40000
; 実際に表示するサイズを指定
width 1290, 730
dialog "",16,"":file=refstr:if refstr="":end
ex=getpath(refstr,2):font"",10
if start=0:buffer 1,10,10:start=1:else:gsel 1
if ex=".bmp"|ex=".jpg"|ex=".gif"|ex=".ico"|ex=".png":pos 0,0:picload refstr:color 34,34,34:boxf:pos 0,0:picload refstr,1
ix=ginfo(12):iy=ginfo(13) ;画像の大きさ代入
gosub *redrawimage
SetTimer hwnd, timer_id, 200, 0
stop
*redrawimage
gsel 0
wx=ginfo(12):wy=ginfo(13):zy=ginfo(12):zx=ginfo(13) ;ウィンドウの大きさ代入
redraw 0
gosub*bg
if ix>wx|iy>wy{
//画面内に収まらない
zx = double(wx) / ix //横幅の倍率
zy = double(wy) / iy //縦幅の倍率
if zx>zy {
;縦が長い
pos (wx-zy*ix)/2,0 ;画像を表示する座標を決定
gzoom zy*ix, wy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
} else {
;横が長い
pos 0,(wy-zx*iy)/2 ;画像を表示する座標を決定
gzoom wx, zx*iy, 1, 0, 0, ix, iy, 1 ;ウィンドウの大きさに合わせて描画
}
}else{
//画面内に収まる
gmode 0,ix,iy
pos (wx-ix)/2,(wy-iy)/2
gcopy 1
}
redraw 1
return
//背景
*bg
color 34,34,34:boxf
return
*OnTimer
if wparam == timer_id:title""+ginfo(12)+" x "+ginfo(13): gosub *redrawimage
return 0
*exit
KillTimer hwnd, timer_id
end

| |
|
2018/8/23(Thu) 12:06:00|NO.85171
おお!ありがとうございます!
WM_SIZE、こんな便利なものがあったとは。
>gosub *redrawimage で飛んでいるにもかからわず、中で stop してしまっており、
returnせずにstopしてましたね...完全に自分のミスでした;;
ご回答いただきありがとうございました。大変助かりました。
|
|