Windows positioning

Previous topic - Next topic

Ian Price

I've incorporated a routine in my game to allow for various resolutions and windows sizing - offering 1x, 2x and fullscreen modes. These allow you to test and view screens, so that you can see if your pc supports such views and let's you play at your chosen resolution.

They all work well however after returning from fullscreen mode to windowed mode, the game window returns to position 0,0 on the actual screen.

This demonstrates the problem - press SPACE a few times

Code (glbasic) Select
SETSCREEN 320,240,0

WHILE true

IF KEY(57)
 INC toggle,1
 
 IF toggle>1 THEN toggle=0
 
 IF toggle=0 THEN SETSCREEN 320,240,0
 IF toggle=1 THEN SETSCREEN 320,240,1

ENDIF

PRINT "PRESS SPACE TO SEE PROBLEM",50,50

SHOWSCREEN

WEND
Can GLB be made to return the game screen to the centre of physical screen? I know in BlitzMax you had to access Win32 commands to move the game screen.
I came. I saw. I played.

Quentin

you can use the function MoveWindow from user32.dll.
Unfortunately the sample below works only once, all other calls to the function will fail. Don't know why at the moment. Perhaps its a bug with GLBASIC_HWND() function.


Code (glbasic) Select
scrx = 640
scry = 480
LOCAL result

SETSCREEN scrx, scry, 0

WHILE TRUE

  IF KEY(57)
    WHILE KEY(57); WEND
    INC toggle,1

    IF toggle > 1 THEN toggle = 0

    IF toggle=0
      SETSCREEN scrx, scry, 1
    ENDIF
    IF toggle=1
      SETSCREEN scrx, scry, 0
      result = WinMoveTo(100, 100)
    ENDIF
  ENDIF

  PRINT "PRESS SPACE TO SEE PROBLEM",50,50

  SHOWSCREEN

WEND

FUNCTION _dummy:
ENDFUNCTION

INLINE
  DECLARE(MoveWindow, "user32.dll", (void*, int, int, int, int, int), int);
ENDINLINE


// ------------------------------------------------------------- //
// ---  WINMOVETO  ---
// ------------------------------------------------------------- //
FUNCTION WinMoveTo: x, y

  LOCAL sizex, sizey, ret

  // make only sense in windowed mode
  IF ISFULLSCREEN() = TRUE
    RETURN 0
  ENDIF

  GETSCREENSIZE sizex, sizey

  INLINE
    ret = MoveWindow(GLBASIC_HWND(), x, y, sizex, sizey, TRUE);
  ENDINLINE

  RETURN ret

ENDFUNCTION // WINMOVETO

D2O

@all , Sorry, i write in german ;)
@ Quentin
Tach, das ist ja ne nette sache aber ich versteh das nicht ganz :(

Und zwar die zeile  
Quoteresult = WinMoveTo(100, 100)
Was sind die "100" für werte?
Ich habe zum testen mal 50,50 eigegeben um zu sehen was sich verändert, aber tut sich nichts.

Noch lustiger fand ich das ich   result = WinMoveTo(100, 100) komplett auskommentiert habe,
und das switschen zwischen vollbild und fenster geht trotzdem.

Bin nun etwas verwirrt :)
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Ian Price

Quentin: Cheers, the solution helps, but it still needs sorting out properly methininks.

Nice try though :)
I came. I saw. I played.

Quentin

@D2O
MoveWindow setzt das Programmfenster an die x- und y-Position, die als Parameter mitgegeben werden. Beim Wechsel zwischen Vollbild und Window ist es nun mal leider so, daß das Fenster nach einem Wechsel von Vollbild zu Window in der oberen linken Ecke des Desktop angezeigt wird. Er wollte aber, daß es in der Mitte des Desktop angezeigt wird. Klar?

D2O

Danke, verstanden.
I7 2600K; 8 GB RAM ; Win10 Pro x64 | NVidia GTX 750 TI 2048MB ; Realtec OnBoard Sound;
Lenovo ThinkPad T400: XP Pro
GLB Premium-immer Aktuell

Schranz0r

you need GetDesktopWindow to get the Desktop HWND.
then you need the RECT's of both windows!

Now you can set the exact middle of the Screen

Code (glbasic) Select
X = Desktop.right / 2 - (Window.right-Window.left) / 2
Y = Desktop.bottom / 2 - (Window.bottom -Window.top) / 2
BTW, thats not a bug, MOVE TO GLBasic!
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Ian Price

It may not be a bug, but it's unexpected behaviour that's not required.

Any chance of a function to show this working properly then Schranz0r? ;)
I came. I saw. I played.

Schranz0r

for RECT we need the windows.h header.
And there are the problem, we can't include it!
Massiv errors as result :/
I think that isn't the solution of it...

Only Gernot can fix that problem
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Kitty Hello


blastar

this is not correct:
GETSCREENSIZE sizex, sizey -> MoveWindow(GLBASIC_HWND(), x, y, sizex, sizey, TRUE);

you should add border and windowtitle to the new (old) size of your window or it cuts the visible screen!

Code (glbasic) Select
SETSCREEN 640, 480, 0

WHILE KEY(01) = 0

  PRINT "PRESS 'M' TO MOVE WINDOW",50,50
  PRINT "PRESS 'C' TO CENTER WINDOW",50,60
  PRINT "PRESS 'ESC' TO QUIT",50,70
 
  IF KEY(50) = 1 THEN WinMoveTo(100,100)
  IF KEY(46) = 1 THEN WinCenter()
 
  SHOWSCREEN
WEND
END

FUNCTION _dummy:
ENDFUNCTION

INLINE
}
#ifdef WIN32
   #define SM_CXSCREEN 0
   #define SM_CYSCREEN 1
   #define SM_CXFIXEDFRAME 7
   #define SM_CYFIXEDFRAME 8
   #define SM_CYSIZE 31
   extern "C" __stdcall int GetSystemMetrics(int);  DECLARE(MoveWindow, "user32.dll", (void*, int, int, int, int, int), int);
#endif
namespace __GLBASIC__{
ENDINLINE

FUNCTION WinMoveTo: x, y

LOCAL wbx, wby, wbt, sizex, sizey
GETSCREENSIZE sizex, sizey
INLINE
#ifdef WIN32
wbx = ::GetSystemMetrics(SM_CXFIXEDFRAME);
wby = ::GetSystemMetrics(SM_CYFIXEDFRAME);
wbt = ::GetSystemMetrics(SM_CYSIZE);
    MoveWindow(GLBASIC_HWND(), x, y, sizex + wbx*2, sizey + wby*2 + 1 + wbt, TRUE);
  #endif
  ENDINLINE

ENDFUNCTION

FUNCTION WinCenter:

LOCAL wbx, wby, wbt, sizex, sizey, x, y, sx, sy
GETSCREENSIZE sizex, sizey
INLINE
#ifdef WIN32
sx = ::GetSystemMetrics(SM_CXSCREEN);
sy = ::GetSystemMetrics(SM_CYSCREEN);
wbx = ::GetSystemMetrics(SM_CXFIXEDFRAME);
wby = ::GetSystemMetrics(SM_CYFIXEDFRAME);
wbt = ::GetSystemMetrics(SM_CYSIZE);
#endif
ENDINLINE

x = (sx-(sizex+wbx*2))/2
y = (sy-(sizey+wby*2+1+wbt))/2

INLINE
#ifdef WIN32
    MoveWindow(GLBASIC_HWND(), x, y, sizex + wbx*2, sizey + wby*2 + 1 + wbt, TRUE);
  #endif
  ENDINLINE

ENDFUNCTION

Kitty Hello

OUCH!!!
Why not using SETSCREEN sizex, sizey, FALSE ???

blastar

LOL, you are right - recreate the screen is easier! ;-)

S. P. Gardebiter

Allright I will translate, maybe it's interesting for more people.
Translations:

Quote from: D²O@all , Sorry, i write in german ;)
@ Quentin
Tach, das ist ja ne nette sache aber ich versteh das nicht ganz :(

Und zwar die zeile  
Quoteresult = WinMoveTo(100, 100)
Was sind die "100" für werte?
Ich habe zum testen mal 50,50 eigegeben um zu sehen was sich verändert, aber tut sich nichts.

Noch lustiger fand ich das ich   result = WinMoveTo(100, 100) komplett auskommentiert habe,
und das switschen zwischen vollbild und fenster geht trotzdem.

Bin nun etwas verwirrt :)
@ Quentin
Hello, this is a nice thing, but I think I quite can't understand it :(

I mean the line  
Quoteresult = WinMoveTo(100, 100)
What kind of value is "100"?
I've used 50,50 to test it to see it something changes, but there is nothing which changed.

Even more funny was that I removed the  result = WinMoveTo(100, 100)
and changing between fullscreen and windowed still does work.

Now I'am a bit confused :)

Quote from: Quentin@D2O
MoveWindow setzt das Programmfenster an die x- und y-Position, die als Parameter mitgegeben werden. Beim Wechsel zwischen Vollbild und Window ist es nun mal leider so, daß das Fenster nach einem Wechsel von Vollbild zu Window in der oberen linken Ecke des Desktop angezeigt wird. Er wollte aber, daß es in der Mitte des Desktop angezeigt wird. Klar?
@D2O
MoveWindow sets the Program window to the x- and y-position which is specified as the paramter you saw. If you change between fullscreen and windowed, then the window will be at the top left corner of the desktop. He wanted to display it in the middle of the desktop. Ok?

Quote from: D²ODanke, verstanden.
Understood, thank you.
~ Cave Story rules! ~