Yes, it's a bit annoying isn't it. You get the same sort of problems with javascript with different commands using either inside or outside of a window with respect to dimensions.
A long while ago I knocked up this code in preperation for a game menu where user could swap between window and fullscreen mode in any resolution. Like you I found that setting window size within code does not set window size as expected, so you actually need to add width and height of window borders and caption bar, otherwise window will be squashed and text will look blurry.
So a few calls to windows dlls to get the various window border sizes and height of title bar, and bobs your uncle.
I also found that changing to fullscreen mode had other effects that is what the 'changed' variable does.
This code assumes you have set ide to compile in 640 * 480 windowed mode as startup.
resizable=1 : rem 0=no 1=yes
mode=1 : rem start off in compiled mode of 640*480 windowed mode
changed=0
sync on : sync rate 0 : autocam off
if resizable = 0
set window layout resizable,1,1
endif
#constant SM_CXSCREEN = 0
#constant SM_CYSCREEN = 1
#constant SM_CYCAPTION = 4
#constant SM_CXFIXEDFRAME = 7
#constant SM_CYFIXEDFRAME = 8
#constant SM_CXSIZEFRAME = 32
#constant SM_CYSIZEFRAME = 33
hdc as dword
load dll "user32.dll",1
load dll "gdi32.dll",2
dtop_w=call dll(1,"GetSystemMetrics",SM_CXSCREEN)
dtop_h=call dll(1,"GetSystemMetrics",SM_CYSCREEN)
if resizable = 0
win_edge_width=call dll(1,"GetSystemMetrics",SM_CXFIXEDFRAME)
win_edge_height=call dll(1,"GetSystemMetrics",SM_CYFIXEDFRAME)
else
win_edge_width=call dll(1,"GetSystemMetrics",SM_CXSIZEFRAME)
win_edge_height=call dll(1,"GetSystemMetrics",SM_CYSIZEFRAME)
endif
win_caption_height=call dll(1,"GetSystemMetrics",SM_CYCAPTION)
hdc=call dll(1, "GetDC", 0)
dtop_c=call dll(2, "GetDeviceCaps", hdc, 12)
call dll 1, "ReleaseDC", 0, hdc
delete dll 1
delete dll 2
do
make object cube 1,10 : position camera 0,0,-50
do
turn object left 1,0.01 : pitch object up 1,0.02
set cursor 0,0
print "Current Mode = ";mode
print
print "1 = Window 640 * 480 * ";dtop_c
print "2 = Window 800 * 600 * ";dtop_c
print "3 = Full Screen Exclusive 640 * 480 * 32"
print "4 = Full Screen Exclusive 800 * 600 * 32"
print
print "Screen = ";dtop_w;" * ";dtop_h;" * ";dtop_c
print "Window = ";screen width();" * ";screen height();" * ";screen depth()
print "FPS = ";screen fps()
i$=inkey$()
if i$="1" and mode <> 1 then exit
if i$="2" and mode <> 2 then exit
if i$="3" and mode <> 3 then exit
if i$="4" and mode <> 4 then exit
sync
loop
clearup()
mode=val(i$)
select mode
case 1 : w=640 : h=480 : d=dtop_c : gosub win : endcase
case 2 : w=800 : h=600 : d=dtop_c : gosub win : endcase
case 3 : set window off : set display mode 640,480,32 : changed=1 : endcase
case 4 : set window off : set display mode 800,600,32 : changed=1 : endcase
endselect
backdrop on
sync
loop
win:
set window on
set window layout resizable,1,1
if changed=0
w_w=w
w_h=h
if resizable = 0 then dec w_w,2 : dec w_h,2
else
w_w=w+(2*win_edge_width)
w_h=h+(2*win_edge_height)+win_caption_height
endif
set window position (dtop_w/2)-(w_w/2),(dtop_h/2)-(w_h/2)
set display mode w,h,d
set window size w_w,w_h
return
function clearup()
if object exist(1) then delete object 1
endfunction
Boo!