WindowClipVisible / Snap window to Edge or Work Area

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

WindowClipVisible / Snap window to Edge or Work Area

Post 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
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: WindowClipVisible / Snap window to Edge or Work Area

Post 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)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply