Page 1 of 1

WindowClipVisible / Snap window to Edge or Work Area

Posted: Sat Dec 05, 2009 12:55 pm
by Rescator

Code: Select all

;By Roger Hågensen, EmSai 2009.
;Public Domain.

#MONITORINFOF_PRIMARY=1
#MONITOR_DEFAULTTONULL=0
#MONITOR_DEFAULTTOPRIMARY=1
#MONITOR_DEFAULTTONEAREST=2
Structure MONITORINFO
 cbSize.l
 rcMonitor.RECT
 rcWork.RECT
 dwFlags.l
EndStructure
Structure MONITORINFOEX
 cbSize.l
 rcMonitor.RECT
 rcWork.RECT
 dwFlags.l
 szDevice.s{#CCHDEVICENAME}
EndStructure
Procedure.i WindowClipVisible(window.i)
 Protected result.i=#False,hwnd.i,rect.RECT,hmon.i,mi.MONITORINFO,x.i,y.i,w.i,h.i
 If IsWindow(window)
  hwnd=WindowID(window)
  If GetWindowRect_(hwnd,rect)
   x=rect\left
   y=rect\top
   w=rect\right-x
   h=rect\bottom-y
   mi\cbSize=SizeOf(MONITORINFO)
   hmon=MonitorFromWindow_(hwnd,#MONITOR_DEFAULTTONEAREST)
   If hmon
    If GetMonitorInfo_(hmon,mi)
     If (mi\rcWork\right-w)<rect\left : rect\left=mi\rcWork\right-w : EndIf
     If mi\rcWork\left>rect\left : rect\left=mi\rcWork\left : EndIf
     If (mi\rcWork\bottom-h)<rect\top : rect\top=mi\rcWork\bottom-h : EndIf
     If mi\rcWork\top>rect\top : rect\top=mi\rcWork\top : EndIf
     If (rect\left<>x) Or (rect\top<>y)
      If SetWindowPos_(hwnd,#Null,rect\left,rect\top,rect\right,rect\bottom,#SWP_NOACTIVATE|#SWP_NOZORDER|#SWP_NOSIZE)
       result=#True ;Window moved and should now be within the desktop work area.
      EndIf
     Else
      result=#True ;No need to move the window as it is within the work area.
     EndIf
    EndIf
   EndIf
  EndIf
 EndIf
 ProcedureReturn result ;If false, there is no guarantee the user will be able to see the window.
EndProcedure

;-100 will place the window slightly offscreen, but thanks to WindowClipVisible() it is moved into the work area.
If OpenWindow(1, -100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)

  Repeat
    Event = WaitWindowEvent()

    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    ElseIf Event=#PB_Event_MoveWindow
     WindowClipVisible(1)
    EndIf

  Until Quit = 1
  
EndIf

End

Re: WindowClipVisible / Snap window to Edge or Work Area

Posted: Sun Jul 22, 2012 4:55 pm
by skywalk
Thanks Rescator 8)
Needed this to arrange my dual desktop windows.
You may need to update for Windows 7 borders? Small strip of the top border/frame is cut off.
Not sure if this is correct attribute to add?

Code: Select all

            If SetWindowPos_(hW, #Null, rect\left, rect\top + GetSystemMetrics_(#SM_CXSIZEFRAME)-GetSystemMetrics_(#SM_CYBORDER), rect\right, rect\bottom, #SWP_NOACTIVATE|#SWP_NOZORDER|#SWP_NOSIZE)