I am trying to save a windows x, y and width, height into integers just before maximization, so the window can be restore capable after application restart if closed while maximized.
I thought there would be an event that could be accessed just before maximize when the maximize gadget is pressed.
am I missing something? Thank you.
Window position and size just before maximize
Re: Window position and size just before maximize
Hi Jeromyal,
For Windows only, but can be used at any stage:
• WINDOWPLACEMENT structure
• GetWindowPlacement function
For Windows only, but can be used at any stage:
• WINDOWPLACEMENT structure
• GetWindowPlacement function
Code: Select all
lpwndpl.WINDOWPLACEMENT
GetWindowPlacement_(WindowID(#MainWindow), @lpwndpl)
X = lpwndpl\rcNormalPosition\left
Y = lpwndpl\rcNormalPosition\top
W = lpwndpl\rcNormalPosition\right - lpwndpl\rcNormalPosition\left
H = lpwndpl\rcNormalPosition\bottom - lpwndpl\rcNormalPosition\top
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Re: Window position and size just before maximize
Thanks,
I see how that should work for me but then I guess I still am messing things up.
I will post my program before it get much bigger for review if you dare try to follow my insane code style.
maybe you can spot it. It won't run as is due to other files not included. Sorry.
I see how that should work for me but then I guess I still am messing things up.
I will post my program before it get much bigger for review if you dare try to follow my insane code style.
maybe you can spot it. It won't run as is due to other files not included. Sorry.
Code: Select all
EnableExplicit
#APP_NAME = "Vintage Story Portable Launcher"
#APP_VERSION = "0.1.0"
#APP_AUTHOR = "Jeromy Alexander"
#APP_AUTHOR_EMAIL = "kyja72@hotmail.com"
#USE_ON_ERROR = #True
#Space$ = Chr(32)
#Dark = $191919
#Light = $F0F0F0
Global *Mutex = CreateMutex_(#Null, 1, ReplaceString(#APP_NAME, #Space$, "_"))
If *Mutex <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
CloseHandle_(*Mutex)
End #ERROR_ALREADY_EXISTS
EndIf
XIncludeFile("Vintage Story Portable_Declares.pbi")
XIncludeFile("OnError.pbi")
XIncludeFile("ObjectTheme.pbi")
UseModule ObjectTheme
Macro DQ_String(String)
#DQUOTE$ + string + #DQUOTE$
EndMacro
CreateDirectory("installs")
Enumeration
#Window
#installWindow
#progress
#installtext
#about
#options
#help
#statusbar
#field
#oCheckDark
#editHelp
#editAbout
EndEnumeration
Global wx, wy, ww, wh, wm, event
Global x, y, w, h, dm
If FileSize("VSPL.ini") = -1
If CreateFile(0, "VSPL.ini")
CloseFile(0)
EndIf
EndIf
OpenPreferences("VSPL.ini")
wx = ReadPreferenceInteger("wx", 0)
wy = ReadPreferenceInteger("wy", 0)
ww = ReadPreferenceInteger("ww", 640)
wh = ReadPreferenceInteger("wh", 480)
wm = ReadPreferenceInteger("wm", 0)
OpenWindow(#Window, wx, wy, ww, wh, #APP_NAME + #Space$ + #APP_VERSION, #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_Invisible)
CreateStatusBar(#statusbar, WindowID(#window))
AddStatusBarField(#PB_Ignore)
StatusBarText(#statusbar, 0, "No Selection")
CreateMenu(0, WindowID(#Window))
MenuTitle("File")
MenuItem(1, "&Install...")
MenuItem(2, "&Uninstall...")
MenuBar()
MenuItem(3, "&Preferences")
MenuBar()
MenuItem(4, "&Quit")
MenuTitle("Help")
MenuItem(5, "&Help")
MenuBar()
MenuItem(6, "&About")
DisableMenuItem(0, 2, 1)
ListIconGadget(#field, 0, 0, WindowWidth(#Window), WindowHeight(#Window) - StatusBarHeight(#statusbar) - MenuHeight(), "huh?", WindowWidth(#Window), #PB_ListIcon_AlwaysShowSelection)
SetGadgetAttribute(#field, #PB_ListIcon_DisplayMode, #PB_ListIcon_LargeIcon)
ResizeWindow(#window, wx, wy, ww, wh)
WindowBounds(#Window, 400, 200, #PB_Ignore, #PB_Ignore)
If wm = 16777216
SetWindowState(#Window, 16777216)
EndIf
BindEvent(#PB_Event_SizeWindow, @WindowResize(), #Window)
BindEvent(#PB_Event_MaximizeWindow, @maximized(), #Window)
BindEvent(#PB_Event_RestoreWindow, @restored(), #Window)
If ReadPreferenceInteger("dm", 0)
SetObjectTheme(#ObjectTheme_Auto, #Dark)
Else
SetObjectTheme(#ObjectTheme_Auto, #light)
EndIf
HideWindow(#Window, #False)
loadfield()
Repeat
event = WaitWindowEvent(10)
Select EventWindow()
Case #Window
Select event
Case #PB_Event_CloseWindow
quiting()
Break
Case #PB_Event_Menu
Select EventMenu()
Case 1 ; install
DisableWindow(#Window, #True)
install()
Case 2 ; uninstall
DisableWindow(#Window, #True)
Uninstall()
Case 3 ; preferences
DisableWindow(#Window, #True)
preferences()
Case 4 ; quit
quiting()
Break
Case 5 ; help
DisableWindow(#Window, #True)
help()
Case 6 ; about
DisableWindow(#Window, #True)
about()
EndSelect
EndSelect
Case #about
Select event
Case #PB_Event_CloseWindow
CloseWindow(#about)
DisableWindow(#Window, #False)
SetActiveWindow(#Window)
EndSelect
Case #options
Select event
Case #PB_Event_CloseWindow
CloseWindow(#options)
DisableWindow(#Window, #False)
SetActiveWindow(#Window)
Case #PB_Event_Gadget
If EventGadget() = #oCheckDark
If GetGadgetState(#oCheckDark)
SetObjectTheme(#ObjectTheme_Auto, #Dark)
WritePreferenceInteger("dm", 1)
Else
SetObjectTheme(#ObjectTheme_Auto, #light)
WritePreferenceInteger("dm", 0)
EndIf
EndIf
EndSelect
Case #help
Select event
Case #PB_Event_CloseWindow
CloseWindow(#help)
DisableWindow(#Window, #False)
SetActiveWindow(#Window)
EndSelect
EndSelect
ForEver
Procedure WindowResize()
ResizeGadget(#field, 0, 0, WindowWidth(#Window), WindowHeight(#Window) - StatusBarHeight(#statusbar) - MenuHeight())
wx = x : wy = y : ww = w : wh = h
EndProcedure
Procedure install()
If FileSize("innounp.exe") > 0
Protected installer$ = OpenFileRequester("Select Vintage Story installer", GetUserDirectory(#PB_Directory_Downloads), "Vintage Story Installer|vs_install_win*.exe|Any Executable|*.exe", 0)
If installer$
If RunProgram(".\innounp.exe", " -q -x -b -y " + DQ_String(installer$) + " -d" + DQ_String("..\installs") + " install_script.iss", "installs", #PB_Program_Wait | #PB_Program_Hide)
OpenPreferences(".\installs\install_script.iss")
PreferenceGroup("Setup")
Protected appname.s = ReadPreferenceString("AppName", "Unknown")
Protected appversion.s = ReadPreferenceString("AppVersion", "Unknown")
OpenPreferences("VSPL.ini")
Protected file
If ReadFile(file, ".\installs\install_script.iss")
Protected string.s = ReadString(file, #PB_File_IgnoreEOL)
CloseFile(file)
EndIf
Protected comp, s
Protected line.s
OpenWindow(#installWindow, 0, 0, 500, 120, "Inatalling", #PB_Window_WindowCentered | #PB_Window_TitleBar, WindowID(#Window))
TextGadget(#installtext, 5, 5, WindowWidth(#installWindow) - 10, 80, "Installing " + appname + " " + appversion)
ProgressBarGadget(#progress, 5 , WindowHeight(#installWindow) - 30, WindowWidth(#installWindow) - 10, 24, 0, CountString(string, "Source:") + 1)
comp = RunProgram(".\innounp.exe", "-x -b -y " + DQ_String(installer$) + " -d" + DQ_String("..\installs"), "installs", $E | #PB_Program_Hide)
If comp : s = 0
While ProgramRunning(comp)
If AvailableProgramOutput(comp)
line = ReadProgramString(comp)
s = s + 1
SetGadgetState(#progress, s)
SetGadgetText(#installtext, "Installing " + appname + " " + appversion + Chr(13) + Chr(13) + Str(s) + " of " + Str(CountString(string, "Source:") + 1)+ " files." + Chr(13) + Chr(13) + GetFilePart(line))
EndIf
WindowEvent()
Wend
CloseProgram(comp)
CloseWindow(#installWindow)
DeleteDirectory(".\installs\{autofonts}", "*.*", #PB_FileSystem_Recursive)
DeleteDirectory(".\installs\{tmp}", "*.*", #PB_FileSystem_Recursive)
DeleteFile(".\installs\install_script.iss")
RenameFile(".\installs\{app}", ".\installs\" + appname + " " + appversion)
EndIf
EndIf
EndIf
loadfield()
Else
MessageRequester("Error", ~"innounp.exe is missing.\n\nInstalls can not be done.", #PB_MessageRequester_Error | #PB_MessageRequester_Ok, WindowID(#Window))
EndIf
DisableWindow(#Window, #False)
EndProcedure
Procedure Uninstall()
loadfield()
DisableWindow(#Window, #False)
EndProcedure
Procedure help()
OpenWindow(#help, 0, 0, 500, 400, #APP_NAME + " - Help", #PB_Window_WindowCentered | #PB_Window_Tool | #PB_Window_SystemMenu, WindowID(#Window))
EditorGadget(#editHelp, 0, 0, 500, 400, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
EndProcedure
Procedure about()
OpenWindow(#about, 0, 0, 500, 400, #APP_NAME + " - About", #PB_Window_WindowCentered | #PB_Window_Tool | #PB_Window_SystemMenu, WindowID(#Window))
EditorGadget(#editAbout, 0, 0, 500, 400, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
EndProcedure
Procedure preferences()
OpenWindow(#options, 0, 0, 500, 400, #APP_NAME + " - Preferences", #PB_Window_WindowCentered | #PB_Window_Tool | #PB_Window_SystemMenu, WindowID(#Window))
CheckBoxGadget(#oCheckDark, 5, 5, 480, 24, "Use Darkmode")
dm = ReadPreferenceInteger("dm", GetGadgetState(#oCheckDark))
SetGadgetState(#oCheckDark, dm)
If GetGadgetState(#oCheckDark)
SetObjectTheme(#ObjectTheme_Auto, #Dark)
WritePreferenceInteger("dm", 1)
Else
SetObjectTheme(#ObjectTheme_Auto, #light)
WritePreferenceInteger("dm", 0)
EndIf
EndProcedure
Procedure maximized()
Protected lpwndpl.WINDOWPLACEMENT
GetWindowPlacement_(WindowID(#Window), @lpwndpl)
X = lpwndpl\rcNormalPosition\left
Y = lpwndpl\rcNormalPosition\top
W = lpwndpl\rcNormalPosition\right - lpwndpl\rcNormalPosition\left
H = lpwndpl\rcNormalPosition\bottom - lpwndpl\rcNormalPosition\top
wx = x : wy = y : ww = w : wh = h
EndProcedure
Procedure restored()
EndProcedure
Procedure loadfield()
EndProcedure
Procedure quiting()
WritePreferenceInteger("wx", WindowX(#Window))
WritePreferenceInteger("wy", WindowY(#Window))
WritePreferenceInteger("ww", WindowWidth(#Window))
WritePreferenceInteger("wh", WindowHeight(#Window))
WritePreferenceInteger("wm", GetWindowState(#window))
ClosePreferences()
EndProcedure
Re: Window position and size just before maximize
oh I am a dummy.
found it.
the following change now works along with the code you gave me. Thank you.
found it.
the following change now works along with the code you gave me. Thank you.
Code: Select all
Procedure quiting()
WritePreferenceInteger("wx", wx)
WritePreferenceInteger("wy", wy)
WritePreferenceInteger("ww", ww)
WritePreferenceInteger("wh", wh)
WritePreferenceInteger("wm", GetWindowState(#window))
ClosePreferences()
EndProcedure
Re: Window position and size just before maximize
And if the window is minimized to the taskbar, what will you do? You must remember the last window state before exiting the program.
You don't need to remember the size when maximizing the window, otherwise the user will be forced to manually configure the normal mode each time.
You will also need _SetCoor (to check if the screen size is smaller than the specified coordinates)
You don't need to remember the size when maximizing the window, otherwise the user will be forced to manually configure the normal mode each time.
Code: Select all
If GetWindowState(#window) = #PB_Window_Maximize
wm = 1
Else
wm = 0
EndIf
wm = Bool(GetWindowState(#window)) = #PB_Window_Maximize)
; ...
If wm
SetWindowState(#window, #PB_Window_Maximize)
EndIf
Code: Select all
Repeat
Select WaitWindowEvent()
Case #PB_Event_MaximizeWindow
win\wm = 1
Case #PB_Event_RestoreWindow
win\wm = 0
Code: Select all
EnableExplicit
#Window = 0
Structure win
x.i
y.i
w.i
h.i
m.i
EndStructure
Global win.win
win\w = 222
win\h = 111
Procedure WinCallback(hWnd, Message, WParam, LParam)
Protected w, h
Protected *Rest.RECT = LParam
Protected Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_SIZE
w = LParam & $FFFF ; LoWord
h = LParam >> 16 ; HiWord
ResizeGadget(1, #PB_Ignore, #PB_Ignore, w-20, h-20)
Case #WM_EXITSIZEMOVE
If Not win\m
win\w = WindowWidth(#Window)
win\h = WindowHeight(#Window)
EndIf
w = WindowWidth(#Window)
h = WindowHeight(#Window)
ResizeGadget(1, #PB_Ignore, #PB_Ignore, w-20, h-20)
Case #WM_MOVING
win\x = *Rest\left
win\y = *Rest\top
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
win\x = 222
win\y = 222
Global ini$ = Left(ProgramFilename(), Len(ProgramFilename()) - 3) + "ini"
If FileSize(ini$) = -1
If CreatePreferences(ini$)
PreferenceGroup("Set")
WritePreferenceInteger("x", win\x)
WritePreferenceInteger("y", win\y)
WritePreferenceInteger("width", win\w)
WritePreferenceInteger("height", win\h)
WritePreferenceInteger("maxim", win\m)
ClosePreferences()
EndIf
Else
If OpenPreferences(ini$)
PreferenceGroup("Set")
win\x = ReadPreferenceInteger("x", win\x)
win\y = ReadPreferenceInteger("y", win\y)
win\w = ReadPreferenceInteger("width", win\w)
win\h = ReadPreferenceInteger("height", win\h)
win\m = ReadPreferenceInteger("maxim", win\m)
ClosePreferences()
EndIf
EndIf
Procedure Exit()
If OpenPreferences(ini$)
PreferenceGroup("Set")
WritePreferenceInteger("x", win\x)
WritePreferenceInteger("y", win\y)
WritePreferenceInteger("width", win\w)
WritePreferenceInteger("height", win\h)
WritePreferenceInteger("maxim", win\m)
ClosePreferences()
EndIf
EndProcedure
If OpenWindow(#Window, win\x, win\y, win\w, win\h, "Example...",
#PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
ButtonGadget(1, 10, 10, win\w - 20, win\h - 20, "Button")
If win\m
SetWindowState(#window, #PB_Window_Maximize)
EndIf
; BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
SetWindowCallback(@WinCallback())
;- Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_MaximizeWindow
win\m = 1
ResizeGadget(1, #PB_Ignore, #PB_Ignore, WindowWidth(#Window) - 20, WindowHeight(#Window)-20)
Case #PB_Event_RestoreWindow
win\m = 0
Case #PB_Event_Gadget
Select EventGadget()
Case 1
Debug 1
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(#Window)
Exit()
End
EndSelect
ForEver
EndIf
Re: Window position and size just before maximize
Hi AZJIO,
I agree that it make more sense positioning the code before the window is closed to return the last window (re)size, but your assumption is wrong about the GetWindowPlacement API; see my previous post for links to documentation.
• Minimize the example and close it from the Taskbar.
I agree that it make more sense positioning the code before the window is closed to return the last window (re)size, but your assumption is wrong about the GetWindowPlacement API; see my previous post for links to documentation.
Try the following:JHPJHP wrote:can be used at any stage
• Minimize the example and close it from the Taskbar.
Code: Select all
Macro ScaleFactor
DesktopResolutionX()
EndMacro
Macro ScaleFactorD(value)
(value) / ScaleFactor
EndMacro
If OpenWindow(0, 0, 0, 500, 400, "GetWindowPlacement", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
Debug WindowX(0)
Debug WindowY(0)
Debug WindowWidth(0, #PB_Window_FrameCoordinate)
Debug WindowHeight(0, #PB_Window_FrameCoordinate)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
lpwndpl.WINDOWPLACEMENT
GetWindowPlacement_(WindowID(0), @lpwndpl)
X = ScaleFactorD(lpwndpl\rcNormalPosition\left)
Y = ScaleFactorD(lpwndpl\rcNormalPosition\top)
W = ScaleFactorD(lpwndpl\rcNormalPosition\right - lpwndpl\rcNormalPosition\left)
H = ScaleFactorD(lpwndpl\rcNormalPosition\bottom - lpwndpl\rcNormalPosition\top)
Debug "---"
Debug X
Debug Y
Debug W
Debug H
EndIf
Last edited by JHPJHP on Tue Oct 15, 2024 5:52 pm, edited 1 time in total.
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Re: Window position and size just before maximize
Thanks for the GetWindowPlacement Api
Great, it indeed recovers the good positions whatever the state normal, minimized or maximized.
I will be able to improve the save part in my example Keep Windows Size & Position Between Run (Win), it's really much better than
Great, it indeed recovers the good positions whatever the state normal, minimized or maximized.
I will be able to improve the save part in my example Keep Windows Size & Position Between Run (Win), it's really much better than
Code: Select all
If GetWindowState(Window) <> #PB_Window_Normal
SetWindowState(Window, #PB_Window_Normal)
EndIf
GetWindowRect_(WindowID(Window), @WinRect)
Re: Window position and size just before maximize
I am aware of GetWindowPlacement, but it cannot open a window beautifully if it is saved on one monitor and opened on another with smaller dimensions. In this case, you will get a window outside the viewport of the screen.