Window Maximize Button

Previous topic - Next topic

kamakazieturtle

      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:
Code (glbasic) Select

// ---------------------------------------------- //
// 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.
Code (glbasic) Select

// ---------------------------------------------- //
// 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!

ckrum

There is an option for FULL SCREEN on the options dialog  PROJECT/OPTIONS.

erico

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.

MrTAToad

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

kamakazieturtle

#4
Outdated

MrTAToad

#5
Ah, it looks like I don't use SetWindowLong - I use others instead :

Code (glbasic) Select
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) :

Code (glbasic) Select
WHILE TRUE
SHOWSCREEN
WEND

SUB GLB_WIN32_MSG:
HandleWindows()
ENDSUB


Code (glbasic) Select
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


MrTAToad

#6
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.

kamakazieturtle

#7
Outdated

bigsofty

Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

kamakazieturtle

#9
Outdated

kamakazieturtle

#10
Outdated

kamakazieturtle

#11
Refer to first message in this post for all future updates!