It is currently Sun Dec 06, 2020 2:48 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Thu Nov 30, 2017 6:17 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Sep 15, 2003 5:55 am
Posts: 1344
if you need a borderless, sizeable window, then #WM_NCCALCSIZE + #WM_NCHITTEST is the recommended way. here are some additional information about modifying and removing the window frame: https://msdn.microsoft.com/en-us/library/bb688195%28VS.85%29.aspx

MSDN wrote:
To remove the standard window frame, you must handle the WM_NCCALCSIZE message, specifically when its wParam value is TRUE and the return value is 0. By doing so, your application uses the entire window region as the client area, removing the standard frame.

i made this as a quick/incomplete example. you should adjust the offsets, and take a look at microsofts dwm api. you should also consider doing your own painting. but that would go beyond the scope of what i was trying to demonstrate, with this short example.

also keep in mind that its recommended to create a linker option file, that specifically targets windows vista and higher: /SUBSYSTEM:WINDOWS,6.0. this way windows will not interfere with your size and position, and you will actually get what you actually see.

anyway, i hope it can be of some use. :)

Code:
;Sizeable & Moveable Borderless-Window, with Snap-To-Edge & Aero-Snap by nco2k

EnableExplicit

;adjust to match your skin.
Global BorderWidth = GetSystemMetrics_(#SM_CXSIZEFRAME)
Global BorderHeight = GetSystemMetrics_(#SM_CYSIZEFRAME)
Global TitleBarHeight = GetSystemMetrics_(#SM_CYCAPTION)

;dont set too high or too low. 5-10 is the sweet-spot.
Global SnapWidth = 10
Global SnapHeight = 10

;dont modify!
Global IsSnappedX = #False
Global IsSnappedY = #False

Procedure.w GET_X_LPARAM(lParam)
  ProcedureReturn lParam
EndProcedure

Procedure.w GET_Y_LPARAM(lParam)
  ProcedureReturn lParam >> 16
EndProcedure

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  Protected Result = #PB_ProcessPureBasicEvents, *minmaxinfo.MINMAXINFO, CXSIZEFRAME, CYSIZEFRAME, CYCAPTION, *nccalcsize_params.NCCALCSIZE_PARAMS, WorkAreaRect.RECT, *WindowRect.RECT, WindowRect.RECT, WindowWidth, WindowHeight, MouseX, MouseY, IsCaption, IsTop, IsBottom, IsLeft, IsRight
 
  Select uMsg
   
    Case #WM_GETMINMAXINFO
     
      Result = #False
     
      *minmaxinfo = lParam
      *minmaxinfo\ptMinTrackSize\x = GetSystemMetrics_(#SM_CXMINTRACK)
      *minmaxinfo\ptMinTrackSize\y = BorderHeight * 2 + TitleBarHeight + 1
     
    Case #WM_NCCALCSIZE
     
      Result = #False
     
      If wParam = #True
       
        CXSIZEFRAME = GetSystemMetrics_(#SM_CXSIZEFRAME)
        CYSIZEFRAME = GetSystemMetrics_(#SM_CYSIZEFRAME)
        CYCAPTION = GetSystemMetrics_(#SM_CYCAPTION)
       
        *nccalcsize_params = lParam
        *nccalcsize_params\rgrc[0]\left - CXSIZEFRAME
        *nccalcsize_params\rgrc[0]\top - CYCAPTION - CYSIZEFRAME
        *nccalcsize_params\rgrc[0]\right + CXSIZEFRAME
        *nccalcsize_params\rgrc[0]\bottom + CYSIZEFRAME
       
      EndIf
     
    Case #WM_NCHITTEST
     
      Result = #HTNOWHERE
     
      If GetWindowRect_(hWnd, @WindowRect) And WindowRect\right > WindowRect\left And WindowRect\bottom > WindowRect\top
       
        MouseX = GET_X_LPARAM(lParam) - WindowRect\left
        MouseY = GET_Y_LPARAM(lParam) - WindowRect\top
       
        If MouseX > -1 And MouseY > -1
         
          If MouseY >= BorderHeight And MouseY < TitleBarHeight + BorderHeight And MouseX >= BorderWidth And MouseX < WindowRect\right - WindowRect\left - BorderWidth
            IsCaption = #True
          Else
            If MouseY < BorderHeight
              IsTop = #True
            ElseIf MouseY >= WindowRect\bottom - WindowRect\top - BorderHeight
              IsBottom = #True
            EndIf
            If MouseX < BorderWidth
              IsLeft = #True
            ElseIf MouseX >= WindowRect\right - WindowRect\left - BorderWidth
              IsRight = #True
            EndIf
          EndIf
         
          If IsCaption = #True
            Result = #HTCAPTION
          ElseIf IsTop = #True
            If IsLeft = #True
              Result = #HTTOPLEFT
            ElseIf IsRight = #True
              Result = #HTTOPRIGHT
            Else
              Result = #HTTOP
            EndIf
          ElseIf IsBottom = #True
            If IsLeft = #True
              Result = #HTBOTTOMLEFT
            ElseIf IsRight = #True
              Result = #HTBOTTOMRIGHT
            Else
              Result = #HTBOTTOM
            EndIf
          ElseIf IsLeft = #True
            Result = #HTLEFT
          ElseIf IsRight = #True
            Result = #HTRIGHT
          Else
            Result = #HTCLIENT
          EndIf
         
        EndIf
       
      EndIf
     
    Case #WM_MOVING
     
      Result = #True
     
      If SystemParametersInfo_(#SPI_GETWORKAREA, 0, @WorkAreaRect, 0) And WorkAreaRect\right > WorkAreaRect\left And WorkAreaRect\bottom > WorkAreaRect\top
       
        *WindowRect = lParam
       
        WindowWidth = *WindowRect\right - *WindowRect\left
        WindowHeight = *WindowRect\bottom - *WindowRect\top
       
        If WindowWidth > 0 And WindowHeight > 0
         
          If (IsSnappedX = #False And *WindowRect\left >= WorkAreaRect\left And *WindowRect\left < WorkAreaRect\left + SnapWidth) Or (IsSnappedX = #True And *WindowRect\left = WorkAreaRect\left - 1)
            *WindowRect\left = WorkAreaRect\left
            *WindowRect\right = *WindowRect\left + WindowWidth
            IsSnappedX = #True
          ElseIf (IsSnappedX = #False And *WindowRect\right > WorkAreaRect\right - SnapWidth And *WindowRect\right <= WorkAreaRect\right) Or (IsSnappedX = #True And *WindowRect\right = WorkAreaRect\right + 1)
            *WindowRect\left = WorkAreaRect\right - WindowWidth
            *WindowRect\right = *WindowRect\left + WindowWidth
            IsSnappedX = #True
          ElseIf IsSnappedX = #True
            If *WindowRect\left > WorkAreaRect\left And *WindowRect\left < WorkAreaRect\left + SnapWidth
              *WindowRect\left = WorkAreaRect\left + SnapWidth
              *WindowRect\right = *WindowRect\left + WindowWidth
              IsSnappedX = #False
            ElseIf *WindowRect\right > WorkAreaRect\right - SnapWidth And *WindowRect\right < WorkAreaRect\right
              *WindowRect\left = WorkAreaRect\right - WindowWidth - SnapWidth
              *WindowRect\right = *WindowRect\left + WindowWidth
              IsSnappedX = #False
            EndIf
          EndIf
         
          If (IsSnappedY = #False And *WindowRect\top >= WorkAreaRect\top And *WindowRect\top < WorkAreaRect\top + SnapHeight) Or (IsSnappedY = #True And *WindowRect\top = WorkAreaRect\top - 1)
            *WindowRect\top = WorkAreaRect\top
            *WindowRect\bottom = *WindowRect\top + WindowHeight
            IsSnappedY = #True
          ElseIf (IsSnappedY = #False And *WindowRect\bottom > WorkAreaRect\bottom - SnapHeight And *WindowRect\bottom <= WorkAreaRect\bottom) Or (IsSnappedY = #True And *WindowRect\bottom = WorkAreaRect\bottom + 1)
            *WindowRect\top = WorkAreaRect\bottom - WindowHeight
            *WindowRect\bottom = *WindowRect\top + WindowHeight
            IsSnappedY = #True
          ElseIf IsSnappedY = #True
            If *WindowRect\top > WorkAreaRect\top And *WindowRect\top < WorkAreaRect\top + SnapHeight
              *WindowRect\top = WorkAreaRect\top + SnapHeight
              *WindowRect\bottom = *WindowRect\top + WindowHeight
              IsSnappedY = #False
            ElseIf *WindowRect\bottom > WorkAreaRect\bottom - SnapHeight And *WindowRect\bottom < WorkAreaRect\bottom
              *WindowRect\top = WorkAreaRect\bottom - WindowHeight - SnapHeight
              *WindowRect\bottom = *WindowRect\top + WindowHeight
              IsSnappedY = #False
            EndIf
          EndIf
         
        EndIf
       
      EndIf
     
  EndSelect
 
  ProcedureReturn Result
EndProcedure

OpenWindow(0, 200, 200, 800, 600, "Sizeable & Moveable Borderless-Window", #PB_Window_Invisible | #PB_Window_BorderLess | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)

SetWindowCallback(@WndProc(), 0)

SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, GetStockObject_(#DKGRAY_BRUSH))
SetWindowPos_(WindowID(0), 0, 0, 0, 0, 0, #SWP_NOZORDER | #SWP_NOMOVE | #SWP_NOSIZE | #SWP_NOREDRAW | #SWP_FRAMECHANGED)

HideWindow(0, #False)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow : End

edit1: fixed IdeasVacuum's issue?
edit2+3: quick infotext added.

c ya,
nco2k

_________________
If OSVersion() = #PB_OS_Windows_ME : End : EndIf


Last edited by nco2k on Wed Dec 06, 2017 12:43 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Thu Nov 30, 2017 8:44 pm 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6263
Location: Wales, UK
Win7 x64 PB5.61 x64

Hi nco2k

After a few moves/resizes, the title bar and border appear - is that by design?

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Fri Dec 01, 2017 2:46 pm 
Offline
Moderator
Moderator

Joined: Thu Dec 31, 2009 11:05 pm
Posts: 1113
Location: Gernsbach (Germany)
Very good. Image

_________________
ImageImageImageImage Image


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Sat Dec 02, 2017 6:32 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Oct 06, 2007 11:20 pm
Posts: 292
Location: France
Thank you :!:

_________________
~Ar-S~

My webSite (french) with PB apps : LDVMULTIMEDIA
PB - 5.4x LTS / 5.7x - W10 x64 - Ryzen 7 3700x
Repeat : try : until done = 1


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Tue Dec 05, 2017 2:06 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4808
Location: Lyon - France
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Wed Dec 06, 2017 2:50 am 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 6263
Location: Wales, UK
So this code is borderless and moveable (and translucent):

Code:
OpenWindow(1,0,0,200,200,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered)

SetWindowColor(1,RGB(0,0,255))

SetWindowLongPtr_(WindowID(1), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(1), #GWL_EXSTYLE) | #WS_EX_LAYERED)
                                          ;Transparency
SetLayeredWindowAttributes_(WindowID(1),0,156,#LWA_ALPHA)

ButtonGadget(2,0,0,20,20,"X")

Repeat
    Select WaitWindowEvent()
        Case #PB_Event_CloseWindow, #PB_Event_Gadget
            Break
        Case #WM_LBUTTONDOWN
            SendMessage_(WindowID(1), #WM_NCLBUTTONDOWN, #HTCAPTION , #Null)
    EndSelect
ForEver


If the #PB_Window_SizeGadget flag is added, the Window is displayed with borders and title bar. Doesn't that make it a PB bug? :wink:

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Wed Dec 06, 2017 3:37 am 
Offline
Addict
Addict
User avatar

Joined: Mon Sep 15, 2003 5:55 am
Posts: 1344
creating a simple, borderless and movable window is not a problem. in order to enable the aero-snap functionality, you have to add a sizeable-frame to your window. i already said that you will want to do your own painting, when doing something like this. plus you have aero disabled, which introduces another problem as you can see. windows uses a whole different method of compositing the screen, than it does with aero enabled.

try enabling double buffering and see if it helps:
Code:
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_COMPOSITED)

but in the long run, you will want to do this properly. the link i provided contains some very valuable information.

c ya,
nco2k

_________________
If OSVersion() = #PB_OS_Windows_ME : End : EndIf


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Mon Sep 14, 2020 3:56 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Fri Apr 25, 2003 5:10 pm
Posts: 555
Location: Doubs - France
Hi nco2k,
I've taken a deeper look to your code and finaly i decided to use it in a project i'm on.
Many Thanks for this.
So far, it works perfectly and as I wish. I have modified and simplified it a lot to fit my code.

There is something I'm not able to do, could you explain more and give me an example of linker option file.
nco2k wrote:
also keep in mind that its recommended to create a linker option file, that specifically targets windows vista and higher: /SUBSYSTEM:WINDOWS,6.0. this way windows will not interfere with your size and position, and you will actually get what you actually see.

_________________
A+
Denis


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Thu Sep 17, 2020 5:18 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Sep 15, 2003 5:55 am
Posts: 1344
in your compiler options, there is a field called linker options file: https://www.purebasic.com/documentation ... ptions.png

create a new text file and add /SUBSYSTEM:WINDOWS,6.0 to it. then select that file as your linker option file.

that will turn this: https://i.imgur.com/pdYXHCF.png

into this: https://i.imgur.com/vmxTkOy.png

both windows have the exact same coordinates, but notice how the borders and close button get cut off in the first pic?

MSFT wrote:
Quote:
Due to compatability requirements, certain metrics are reported in such a way that they're not consistent with what is actually drawn on the screen when Aero Glass (more accurately, "Windows Vista Aero") is enabled. This sort of approach is needed in order to change the look of the system for the vast majority of apps for which this isn't an issue.

However, there's been a recent change in the system which will be coming out in Vista RC1 that will return the correct rendered value from GetWindowRect() for executables that are linked with "winver = 6.0". This allows new and newly-linked applications to get the "correct" values from GetWindowRect().

c ya,
nco2k

_________________
If OSVersion() = #PB_OS_Windows_ME : End : EndIf


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Thu Sep 17, 2020 5:47 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat May 05, 2007 5:31 pm
Posts: 769
Location: Linz, Austria
If someone needs a borderless window with shadow... Borderless window with native shadow (Vista+)

_________________
Et cetera is my worst enemy


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Thu Sep 17, 2020 7:50 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Sep 15, 2003 5:55 am
Posts: 1344
@chi if you want shadows, all you have to do is put this in my code:
Code:
Structure MARGINS
  cxLeftWidth.l
  cxRightWidth.l
  cyTopHeight.l
  cyBottomHeight.l
EndStructure

Prototype DwmExtendFrameIntoClientArea_(hWnd, *pMarInset)
Global DwmExtendFrameIntoClientArea_.DwmExtendFrameIntoClientArea_

Define DwmapiDLL = OpenLibrary(#PB_Any, "Dwmapi.dll")
If DwmapiDLL
 
  DwmExtendFrameIntoClientArea_ = GetFunction(DwmapiDLL, "DwmExtendFrameIntoClientArea")
  If DwmExtendFrameIntoClientArea_
   
    Define margins.MARGINS
    margins\cyBottomHeight = 1
   
    DwmExtendFrameIntoClientArea_(WindowID(0), @margins)
   
  EndIf
 
  CloseLibrary(DwmapiDLL)
EndIf

but the bottom pixel will glitch out (with your code too btw) and show part of the frame. it will go away once you handle WM_PAINT properly.

c ya,
nco2k

_________________
If OSVersion() = #PB_OS_Windows_ME : End : EndIf


Top
 Profile  
Reply with quote  
 Post subject: Re: Sizeable & Moveable Borderless-Window, with Snap
PostPosted: Fri Sep 18, 2020 5:45 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Fri Apr 25, 2003 5:10 pm
Posts: 555
Location: Doubs - France
@nco2k

Ok i will try, Thank you.

@chi
I've already seen your code but nco2k's code better suits my needs.
Thank you

_________________
A+
Denis


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 30 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye