Page 1 of 1

Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 4:39 pm
by RASHAD
The title says it all

Code: Select all

#MONITORINFOF_PRIMARY=1
#MONITOR_DEFAULTTONULL=0
#MONITOR_DEFAULTTOPRIMARY=1
#MONITOR_DEFAULTTONEAREST=2

#SC_Leftsize      = $F001
#SC_Rightsize     = $F002
#SC_Upsize        = $F003
#SC_UpLeftsize    = $F004
#SC_UpRightsize   = $F005
#SC_Dnsize        = $F006
#SC_DnLeftsize    = $F007
#SC_DnRightsize   = $F008
#SC_DragMove      = $F012

; CompilerIf #PB_Compiler_Unicode = 0
;   MessageRequester("Info","Unicode compiler option not set",#MB_ICONINFORMATION)
;   End
; CompilerEndIf

Global  hwnd,r.RECT,hmon,mi.MONITORINFO,x,y,w,h,snap
mi\cbSize=SizeOf(mi)

Procedure sizeCB()
  ResizeGadget(0,10,WindowHeight(0)-36,60,24)
EndProcedure

hwnd=OpenWindow(0,0,0,800,600,"PB_Player",#PB_Window_BorderLess | #WS_BORDER | #PB_Window_Invisible)
SetWindowColor(0,$838383)

ButtonGadget(0,10,564,60,24,"Quit")
HideWindow(0,0,#PB_Window_ScreenCentered)
BindEvent(#PB_Event_SizeWindow,@sizeCB())
SmartWindowRefresh(0,1)

snap = 50
sw = 10
sww = 2*sw
Repeat
  Select WaitWindowEvent(1)         
    Case #PB_Event_MoveWindow
        If IsWindow(0)
          GetWindowRect_(hWnd,r)
          w = r\right - r\left
          h = r\bottom - r\top
        EndIf  
        hmon = MonitorFromWindow_(hWnd,#MONITOR_DEFAULTTONEAREST)
        GetMonitorInfo_(hmon,mi)
        If mi\rcWork\left + snap > r\left : r\left = mi\rcWork\left - 2: EndIf
        If r\left + w >= (mi\rcWork\right - snap): r\left = mi\rcWork\right - w + 2: EndIf
        If mi\rcWork\top + snap > r\top : r\top = mi\rcWork\top - 2 : EndIf
        If r\top + h >= (mi\rcWork\bottom - snap): r\top = mi\rcWork\bottom - h + 2 : EndIf
        MoveWindow_(hWnd,r\left,r\top,w,h,1)
    
    Case #WM_MOUSEMOVE;,#WM_NCMOUSEMOVE
        GetWindowRect_(hWnd,r.RECT)
        mx = DesktopMouseX()
        my = DesktopMouseY()
        Flag = 0
        If mx > r\left+sww And mx < r\right-sww And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          Flag = 1
        ElseIf mx > r\left+sww And mx < r\right-sww And my > r\bottom-sw And my < r\bottom+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          Flag = 2
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\top+sww And my < r\bottom-sww
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          Flag = 3
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\top+sww And my < r\bottom-sww
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          Flag = 4
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          Flag = 5
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\bottom-sw And my < r\bottom+sww
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          Flag = 6
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          Flag = 7
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\bottom-sw And my < r\bottom+sww
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          Flag = 8
        EndIf
       
    Case #WM_LBUTTONDOWN
        If Flag > 0
          ReleaseCapture_()
        EndIf
        If Flag = 0
SetCursor_(LoadCursor_(0, #IDC_HAND))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DragMove,0)
        ElseIf Flag = 1
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Upsize,0)        
        ElseIf Flag = 2
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Dnsize,0)  
        ElseIf Flag = 3
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Leftsize,0) 
        ElseIf Flag = 4
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Rightsize,0) 
        ElseIf Flag = 5
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_UpLeftsize,0) 
        ElseIf Flag = 6
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DnRightsize,0) 
        ElseIf Flag = 7
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_UpRightsize,0) 
        ElseIf Flag = 8
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DnLeftsize,0)  
        EndIf
      
    Case #WM_LBUTTONUP
        Flag = 0
        SendMessage_(hWnd, #WM_SYSCOMMAND, 0, 0)
        
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Quit = 1
      EndSelect

EndSelect        
      
Until Quit = 1

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 5:48 pm
by HanPBF
Works!

This does move only in header area:

Code: Select all

if my>(r\top + 32)
          Flag = -1
        endif
(insert before sizer checks)


Thanks a lot!!!

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 6:08 pm
by HanPBF
How can I react on the end of sizing of window to implement adjustment to a virtual desktop grid?

This seems to give control to windows completely:
SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DnLeftsize,0)

I can put adjust code here:

Code: Select all

Procedure sizeCB()
  ResizeGadget(0,10,WindowHeight(0)-36,60,24)
  
  If IsWindow(0)
    GetWindowRect_(hWnd,r)
    w = r\right - r\left
    h = r\bottom - r\top
  EndIf 
  
  grid = 32
  ; only example for right edge grid...
  if r\right % grid <> 0
    r\right = r\right / grid * grid
    w = r\right - r\left 
  endif
  
  MoveWindow_(hWnd,r\left,r\top,w,h,1)  
EndProcedure
But that flickers as first sizing is done and then correction is done afterwards.

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 6:39 pm
by RASHAD
Hi HanPBF
To avoid resizing the grid flicker :
#1 :
- Create an image with the full dimension of your desktop
- Draw your grid to that image
- Create ImageGadget() with full dimensions + the grid image
- Disable the ImageGadget()
So you can resize the window only at any time

# 2:
- Use #WM_EXITSIZEMOVE to resize the grid

I prefer #1

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 6:51 pm
by HanPBF
Thanks a lot for the response!

This is not triggered at my site:

Code: Select all

case #WM_EXITSIZEMOVE

Through debug event I found this to work (275):

Code: Select all

case 275 ;13115;13118;275;#WM_EXITSIZEMOVE
o.k. it's mouse move...

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 7:13 pm
by RASHAD
Use

Code: Select all

Global  hwnd,r.RECT,hmon,mi.MONITORINFO,x,y,w,h,snap
mi\cbSize=SizeOf(mi)

Procedure winCB(hWnd, uMsg, WParam, LParam)
  Result = #PB_ProcessPureBasicEvents
  Select uMsg
    Case #WM_EXITSIZEMOVE
      ;Put your code here
    
    Case #WM_SIZE
      ResizeGadget(0,10,WindowHeight(0)-36,60,24)
  EndSelect  
  ProcedureReturn Result
EndProcedure


hwnd=OpenWindow(0,0,0,800,600,"PB_Player",#PB_Window_BorderLess | #WS_BORDER | #PB_Window_Invisible)
SetWindowColor(0,$838383)

ButtonGadget(0,10,564,60,24,"Quit")
HideWindow(0,0,#PB_Window_ScreenCentered)
SmartWindowRefresh(0,1)

SetWindowCallback(@winCB())

snap = 50
sw = 10
sww = 2*sw

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 7:17 pm
by nco2k
snapping should happen during the movement of the window, and not after. people could have multiple monitors, and re-adjusting the window might not be the desired effect.

also your implementation is missing a context menu, and the possibility to minimize, maximize, and restore the window. you cant double-click on the titlebar area, to maximize the window, because you dont have a designated titlebar area. dragging the window by clicking anywhere in the client area, might not be the desired effect either. hence the designated titlebar area.

your margin for detecting the mouse-over corner is pretty off. i dont really know why you are transfering a flag like that, when the messages offer all the information you need. a task like this should be done in the WndProc(), as the message queue could block, and your solution could temporarily stop working. and last but not least, the aero-snap functionality is missing. all in all, you are using waaay too much api, for a very simple task.

no offense, but sometimes i wonder, if you look at other peoples code and think to yourself, how can i get rid of all the features and post a really mediocre version of it. :P

c ya,
nco2k

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 7:32 pm
by RASHAD
Why do not you take care of your rubbish code first
And before you comment the others try what you suggesting first and
you will see that it want work :mrgreen:
Everything in my approach can be adjusted like that as per the coder request (not like the others)
I do not see that you are a good helper in any way
Thanks

Edit :Just looked at your rubbish
I do not see any context menu ,no maximize,no minimize even no Close :P
And please add some help text to inform the user that you have a titlebar in a Borderless window :mrgreen:

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 7:58 pm
by nco2k
>> Why do not you take care of your rubbish code first
the WM_NCCALCSIZE method is the recommended way by microsoft, and is used in visual studio itself, and in steam, and in pretty much every professional application, that requires a borderless, sizeable, and skinable window. read the msdn and you will see.

>> And before you comment the others try what you suggest first and you will see that it want work.
i tried your code, and everything i told you is true. my criticism was constructive, but you can choose to ignore it of course.

>> I do not see that you are good helper in any way.
at least i try to follow good standards and practices, while you post simply for the sake of posting. quantity over quality. and this has nothing to do with me or my code. i saw you do this a lot over the past few years, even when i barely visited this site. even though the recommended solution has already been posted, you always felt the need to post your solution, that offered a third of the original functionality, and had a lot of drawbacks and unnecessary api calls. not to mention that you never do any form of error checking. you can post whatever you want, and personally i couldnt care less what you post. i just thought it was pretty amusing. :)

edit1: you can maximize, minimize, or close the window, by clicking in the context menu of the app in the taskbar. or you can maximize and restore the window by double-clicking in the upper area of the window (invisible titlebar). of course im not gonna add skinning. this was just a quick proof-of-concept. you will have to do some adjustments to fit your needs. and like i said, the "titlebar in a borderless window" as you call it, is the recommended way. do your research.

edit2: you have 50 api calls, i have 12, and 4 of them can be replaced by your own values. so how is your code any less complicated?! not to mention the unnecessary libraries like the desktop library. we could discuss this the whole night, but it wouldnt get us anywhere. so we should call it a day. thats why i edited this post, instead of creating a new one. i dont like spamming other peoples threads. especially not when the topic is who has the bigger d*ck. all has been said. so have a good one. :)

edit3: facepalm. why doesnt it surprise me, that my advice went way over your head? you do not need DesktopMouseX/Y(), because WM_MOUSEMOVE and WM_LBUTTONDOWN already return the mouse coordinates. you could use EventlParam() to get the data, or actually use a callback like intended.

c ya,
nco2k

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 8:06 pm
by RASHAD
Why should I use something I do not need it,beside I am using MS functions and if it works fine with windows 10(Reziseable borderless window - no top white strip) that is enough for me
Complicated code is not a proof that it is good
That is why any one will use the one he can understand it and modify it when needed
byby
not to mention the unnecessary libraries like the desktop library
DesktopMouseX() ,DesktopMouseY() do not need any extra lib it is simply as GetCursorPos_() go and check it
And this is just a sample of your nonsense comments .
Try to control yourself

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Fri Dec 01, 2017 9:55 pm
by HanPBF
DELETED

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Sat Dec 02, 2017 4:17 am
by Fangbeast
Thanks for another great example RASHAD. BY the way, you never did reply to my email a few months ago and I forgot why I sent it (Grin).

Do remember why I was contacting you?? (Getting old)

Re: Borderless Window Size-Move-Real Snap to edges[Windows]

Posted: Sat Dec 02, 2017 7:03 am
by Paul
Running Windows 7...
No snapping occurs here.

Tried the other code posted by nco2K and it works doing a proper Windows Snap to Edge.