This code enables the maximize button, as well as scaling, to a "Windowed Mode" window on the "Windows OS." It will add an ".ini" file to your programs directory to store all necessary data, such as restoring the window to the last known size, and maximizing the window on program start. The code is not perfect, there are a few workarounds I'd like to eliminate. Anyone who would like to help test this out on different versions of Windows, it would be much appreciated. The best way to test is to make an image the size of your desktop and draw it in the main loop. Okay, the only thing I would like to update in the future is the buffer being refreshed during scaling, but I'm happy with it for now.
WARNING!
Your program must support changes to window resolution!
Main File:
// ---------------------------------------------- //
// Project: Window Maximize Button\Window Scaling //
// File: Main.gbas //
// Start: Sunday, September 28, 2014 //
// IDE Version: 10.283 //
// ---------------------------------------------- //
StartUp()
Main:
CLEARSCREEN
Update()
SHOWSCREEN
GOTO Main
SUB GLB_ON_QUIT:
INIPUT "Window","X","("+Window.X+")"
INIPUT "Window","Y","("+Window.Y+")"
INIPUT "Window","Width",Window.Width
INIPUT "Window","Height",Window.Height
INIPUT "Window","Mode",Window.Mode
INIPUT "Window","Style$",Window.Style$
INIPUT "Gui","Width",Gui.Width
INIPUT "Gui","Height",Gui.Height
INIPUT "Gui","Mode",ISFULLSCREEN()
ENDSUB
Source File: Add to program in the files tab, on the right-hand side of the IDE.
// ---------------------------------------------- //
// Project: Window Maximize Button\Window Scaling //
// File: Inine.gbas //
// Start: Sunday, September 28, 2014 //
// IDE Version: 10.283 //
// ---------------------------------------------- //
GLOBAL DesktopWidth,DesktopHeight
TYPE WindowType
X
Y
Width
Height
Mode
Style$
ENDTYPE
GLOBAL Window AS WindowType
TYPE GuiType
X
Y
Width
Height
PrevX
PrevY
PrevWidth
PrevHeight
Mode
ENDTYPE
GLOBAL Gui AS GuiType
INLINE
}
struct RECT{int Left,Top,Right,Bottom;};
extern "C"
{
int __stdcall GetWindowLongA(void*, int);
int __stdcall SetWindowLongA(void*, int, int);
int __stdcall SetWindowPos(void*, int, int, int, int, int, int);
int __stdcall GetWindowRect(void*, void*);
const int Style=0;
}
#define WS_SIZEBOX 0x00040000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_MAXIMIZE 0x01000000L
#define SWP_FRAMECHANGED 0x0020
#define SWP_SHOWWINDOW 0x0040
#define SWP_NOMOVE 0x0002
#define GWL_STYLE (-16)
RECT Rect;
namespace __GLBASIC__ {
ENDINLINE
FUNCTION StartUp:
GETDESKTOPSIZE DesktopWidth,DesktopHeight
LOCAL A=DOESFILEEXIST("Settings.ini")
IF A=0
INIOPEN "Settings.ini"
Window.Width=648
Window.Height=514
Window.X=((DesktopWidth-Window.Width)/2)
Window.Y=((DesktopHeight-Window.Height)/2)
Gui.Width=640
Gui.Height=480
Gui.Mode=0
Gui.PrevWidth=Gui.Width
Gui.PrevHeight=Gui.Height
SETSCREEN Gui.Width,Gui.Height,Gui.Mode
INLINE
Window.Style_Str=::GetWindowLongA(GLBASIC_HWND(),GWL_STYLE);
::SetWindowLongA(GLBASIC_HWND(),GWL_STYLE,Window.Style_Str|WS_SIZEBOX|WS_MAXIMIZEBOX);
::SetWindowPos(GLBASIC_HWND(),0,Window.X,Window.Y,Window.Width,Window.Height,SWP_FRAMECHANGED);
ENDINLINE
ELSEIF A=1
INIOPEN "Settings.ini"
Window.X=INIGET$("Window","X")
Window.Y=INIGET$("Window","Y")
Window.Width=INIGET$("Window","Width")
Window.Height=INIGET$("Window","Height")
Window.Mode=INIGET$("Window","Mode")
Window.Style$=INIGET$("Window","Style$")
Gui.Width=INIGET$("Gui","Width")
Gui.Height=INIGET$("Gui","Height")
Gui.PrevWidth=Gui.Width
Gui.PrevHeight=Gui.Height
Gui.Mode=INIGET$("Gui","Mode")
SETSCREEN Gui.PrevWidth,Gui.PrevHeight,Gui.Mode
INLINE
::SetWindowLongA(GLBASIC_HWND(),GWL_STYLE,Window.Style_Str);
::SetWindowPos(GLBASIC_HWND(),0,Window.X,Window.Y,Window.Width,Window.Height,SWP_FRAMECHANGED);
ENDINLINE
ENDIF
ENDFUNCTION
FUNCTION Update:
LOCAL Flag
IF Window.X=0 AND Window.Y=0 AND Window.Mode=0
Window.X=((DesktopWidth-Window.Width)/2)
Window.Y=((DesktopHeight-Window.Height)/2)
INLINE
::SetWindowPos(GLBASIC_HWND(),0,Window.X,Window.Y,Window.Width,Window.Height,SWP_SHOWWINDOW);
ENDINLINE
ENDIF
INLINE
::GetWindowRect(GLBASIC_HWND(),&Rect);
Window.Width=(Rect.Right-Rect.Left);
Window.Height=(Rect.Bottom-Rect.Top);
Window.X=Rect.Left;
Window.Y=Rect.Top;
Window.Style_Str=::GetWindowLongA(GLBASIC_HWND(),GWL_STYLE);
if(Window.Style_Str&WS_MAXIMIZE){
Window.Mode=1;}
else{
Window.Mode=0;}
ENDINLINE
Gui.Width=(Window.Width-8)
Gui.Height=(Window.Height-34)
IF Gui.Width>Gui.PrevWidth OR Gui.Width<Gui.PrevWidth THEN Flag=1
IF Gui.Height>Gui.PrevHeight OR Gui.Height<Gui.PrevHeight THEN Flag=1
IF Flag=1
VIEWPORT 0,(Gui.PrevHeight-Gui.Height),Gui.Width,Gui.Height
Flag=0
ENDIF
ENDFUNCTION
Please give credit if used. I've worked very hard on this for a long time now. Anyways, enjoy!
There is an option for FULL SCREEN on the options dialog PROJECT/OPTIONS.
I believe Kama wants to be able to maximize a window, so full screen on a window, no resolution change, no hiddin of the window bits.
I´m not sure how to get to it, let´s wait for a master coder to shed some light.
Somewhere, my old TSetup code should be around - in it, I use SetWindowLong to, in this case, centre the executable's window.
If you cant find it, let me know and I'll have a look through my backups
Outdated
Ah, it looks like I don't use SetWindowLong - I use others instead :
FUNCTION CentreWindow%:
INLINE
#ifdef _WIN32_WCE
#elif WIN32
struct __RECT window;
unsigned int deskWidth,deskHeight,windowWidth,windowHeight;
int flags;
HWND hWnd;
hWnd=(HWND) GLBASIC_HWND();
deskWidth=GetSystemMetrics(SM_CXSCREEN);
deskHeight=GetSystemMetrics(SM_CYSCREEN);
if (::GetWindowRect(hWnd,&window))
{
windowWidth=window.right-window.left;
windowHeight=window.bottom-window.top;
flags=SWP_SHOWWINDOW;
if (windowWidth>deskWidth || windowHeight>deskHeight)
{
windowWidth=deskWidth;
windowHeight=deskHeight;
}
else
{
flags|=SWP_NOSIZE;
}
::SetWindowPos(hWnd,HWND_NOTOPMOST,(deskWidth-windowWidth)>>1,(deskHeight-windowHeight)>>1, windowWidth, windowHeight, flags);
::SetActiveWindow(hWnd);
}
else
{
DEBUG("GetWindowRect (window) failed");
}
#else
#endif
ENDINLINE
ENDFUNCTION
There is a GLB_WIN32_MSG subroutine that will receive all messages - the problem is there is actually no easy way of receiving them...
Until now...
Behold, I have finally found a way of receiving Windows messages (it will need to be re-written for Linux, and I have no idea how that system works) :
WHILE TRUE
SHOWSCREEN
WEND
SUB GLB_WIN32_MSG:
HandleWindows()
ENDSUB
INLINE
#define WINAPI __stdcall
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef long LONG;
typedef unsigned int UINT;
typedef unsigned int UINT_PTR;
typedef long LONG_PTR;
typedef int BOOL;
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT;
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG, *LPMSG;
DECLARE(PeekMessageA,"User32.dll",(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg),BOOL);
ENDINLINE
FUNCTION HandleWindows%:
INLINE
MSG msg;
if (PeekMessageA(&msg,NULL,0,0,1))
{
DEBUG("Message code : "); DEBUG(DGNat(msg.message)); DEBUG("\n");
}
ENDINLINE
ENDFUNCTION
Its not totally correct at the moment - the message values seem strange...
It seems that the message codes are correct, but not all of them are received the subroutine - I suspect the program deals with them before the subroutine is called.
Outdated
Well done! :)
Outdated
Outdated
Refer to first message in this post for all future updates!