GLBasic forum

Main forum => GLBasic - en => Topic started by: Ian Price on 2008-Jan-27

Title: Windows positioning
Post by: Ian Price on 2008-Jan-27
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.
Title: Windows positioning
Post by: Quentin on 2008-Jan-27
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
Title: Windows positioning
Post by: D2O on 2008-Jan-27
@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 :)
Title: Windows positioning
Post by: Ian Price on 2008-Jan-28
Quentin: Cheers, the solution helps, but it still needs sorting out properly methininks.

Nice try though :)
Title: Windows positioning
Post by: Quentin on 2008-Jan-28
@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?
Title: Windows positioning
Post by: D2O on 2008-Jan-28
Danke, verstanden.
Title: Windows positioning
Post by: Schranz0r on 2008-Jan-28
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!
Title: Windows positioning
Post by: Ian Price on 2008-Jan-28
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? ;)
Title: Windows positioning
Post by: Schranz0r on 2008-Jan-28
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
Title: Windows positioning
Post by: Kitty Hello on 2008-Jan-28
Try GetSystemMetrics with SM_SXSCREEN(=0) and SM_CYSCREEN params.

http://msdn2.microsoft.com/en-us/library/ms724385(VS.85).aspx

edit: SOLUTION:
http://www.glbasic.com/forum/viewtopic.php?pid=12949
Title: Windows positioning
Post by: blastar on 2008-Apr-15
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
Title: Windows positioning
Post by: Kitty Hello on 2008-Apr-15
OUCH!!!
Why not using SETSCREEN sizex, sizey, FALSE ???
Title: Windows positioning
Post by: blastar on 2008-Apr-15
LOL, you are right - recreate the screen is easier! ;-)
Title: Windows positioning
Post by: S. P. Gardebiter on 2008-Apr-16
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.