Code: Select all
EnableExplicit
;Checks if the window is in a visible area on screen with s specified margin if any.
;When is this truly usefull?
;1. When by mistake the x,y position was saved while minimized.
;2. When x,y position saved is wrong.
;3. When the user remove/change/swap multidisplay desktop setup or re-align them.
;4. When the user manages to move to window so far to the side he can't easily grab it
; and in panic or anger quits/kill the program and try to restart it but the settings
; was saved with the weird x,y position.
;5. Probably more reasons...Why this behaviour isn't part of the OS is mind-boggling,
; Would a Open_Viewable window flag been that hard to add to the OS? *laughs*
;If not visible it will attempt to make it visible and return true if it worked.
;False is returned if it fail for some reason, to allow you to handle the error yourself.
;Works fully with Windows 98 or later (multimonitor), there is a fallback for W95 and NT.
;Note! The procedure will un-minimize, move then re-minimize a window if it was previously
;minimized, this lets you open the window in a minimized state without conflict.
;To avoid the window flashing/jumping it might be wise to open the window hidden.
;This procedure is best used at program startup, right after you have loaded the program
;settings for example (x,y,minimized or maximized et.al.) and opened the window hidden.
;Tip! To open the window hidden use #PB_Window_Invisible as a window flag
;and HideWindow(#Window,#False) when done making the window, adding gadgets and so on
;Tip! To Restore (un-minimize) a window, use SetWindowState(#Window,#PB_Window_Normal)
Structure MONITORINFO
cbSize.l
rcMonitor.RECT
rcWork.RECT
dwFlags.l
EndStructure
#MONITOR_DEFAULTTONEAREST=$00000002
Procedure.l WindowForceVisible(window.l,margin.l=0)
Protected result.l=#False,hwnd.l,rect.RECT,hmonitor.l,mi.MONITORINFO,noerror.l=#False,state.l
If IsWindow(window)
hwnd=WindowID(window)
state=GetWindowState(window)
If state=#PB_Window_Minimize
SetWindowState(window,#PB_Window_Normal)
EndIf
If GetWindowRect_(hwnd,rect)
mi\cbSize=SizeOf(MONITORINFO)
If OSVersion()>=#PB_OS_Windows_98
hmonitor=MonitorFromWindow_(hwnd,#MONITOR_DEFAULTTONEAREST)
If hmonitor
noerror=GetMonitorInfo_(hmonitor,mi)
Else
noerror=#False
EndIf
Else ;W95,NT3,NT4 fallback.
noerror=SystemParametersInfo_(#SPI_GETWORKAREA,#Null,mi\rcWork,#Null)
EndIf
If noerror
If (rect\left<(mi\rcWork\left-margin)) Or (rect\top<(mi\rcWork\top-margin)) Or (rect\right>(mi\rcWork\right+margin)) Or (rect\bottom>(mi\rcWork\bottom+margin))
rect\left=mi\rcWork\left+((mi\rcWork\right-mi\rcWork\left)-(rect\right-rect\left))/2
rect\top=mi\rcWork\top+((mi\rcWork\bottom-mi\rcWork\top)-(rect\bottom-rect\top))/2
If SetWindowPos_(hwnd,#Null,rect\left,rect\top,#Null,#Null,#SWP_NOACTIVATE|#SWP_NOZORDER|#SWP_NOSIZE)
result=#True ;Window moved and should now be visible again.
EndIf
Else ;No need to move the window as it is within margin, window visible.
result=#True
EndIf
EndIf
EndIf
If state=#PB_Window_Minimize
SetWindowState(window,state)
EndIf
EndIf
ProcedureReturn result ;If false, there is no guarantee the user can see the window.
EndProcedure
Define event.l,quit.l,x.l,y.l
#Window=1
;Play around with X and Y
x=-2
y=-2
If OpenWindow(#Window,x,y,195,260,"PureBasic Window",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Invisible|#PB_Window_Minimize)
Debug WindowForceVisible(#Window,2) ;Simple huh? ;) A margin of 2 pixels is used here.
HideWindow(#Window,#False)
Repeat
event=WaitWindowEvent()
If event=#PB_Event_CloseWindow ; If the user has pressed on the close button
quit=#True
EndIf
Until quit
EndIf
End