Page 1 of 2
Borderless sizable window?
Posted: Tue Feb 24, 2015 5:16 am
by Poshu
Hello,
I'm trying to get a borderless window to be sizable, and I can't seem to find any solution to achieve that, I thought I could try to redraw the nonclient area when a #WM_NCPAINT message came in, but I had no success, here is my tests so far...
Code: Select all
Procedure NouvelleProc(hWnd.i, Msg.l, wParam.i, lParam.i)
Protected OriginProc.i, HDC, Rect.Rect, brush, Pen
OriginProc= GetProp_(hWnd, "OriginProc")
Select Msg
Case #WM_NCPAINT
SendMessage_(hWnd, #WM_NCACTIVATE, 1, 0)
hdc=GetDCEx_(hwnd,wParam,#DCX_WINDOW|#DCX_CACHE|#DCX_INTERSECTRGN|#DCX_LOCKWINDOWUPDATE)
GetWindowRect_(hWnd,Rect)
brush = CreateSolidBrush_(RGB(0,180,180))
SelectObject_(HDC,brush)
Rectangle_(hdc,0,0,rect\right - Rect\left,Rect\bottom - Rect\top)
DeleteObject_(Pen)
DeleteObject_(brush)
ReleaseDC_(hWnd,HDC)
RedrawWindow_(hWnd,Rect,wParam,#RDW_UPDATENOW)
ProcedureReturn 0
Case #WM_NCACTIVATE
wParam=1
Case #WM_NCDESTROY
SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, OriginProc)
RemoveProp_(hWnd, "OriginProc")
EndSelect
ProcedureReturn CallWindowProc_(OriginProc, hWnd, Msg, wParam, lParam)
EndProcedure
If OpenWindow (0,0,0,322,275, "get off, you ugly border" , #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_Invisible )
StickyWindow(0,1)
OriginProc = SetWindowLongPtr_(WindowID(0), #GWLP_WNDPROC, @NouvelleProc())
SetProp_(WindowID(0), "OriginProc", OriginProc)
HideWindow(0,#False)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit=1
EndSelect
Until Quit=1
EndIf
Anyone knows a trick to achieve sizable borderless or at least ownerdrawn border?
Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 5:52 am
by RASHAD
Hi
- Escape to quit
- Left Mouse Down to move
# 1:
Code: Select all
If OpenWindow (0,0,0,322,275, "get off, you ugly border" , #PB_Window_BorderLess| #WS_SIZEBOX |#PB_Window_ScreenCentered )
StickyWindow(0,1)
Repeat
Select WaitWindowEvent()
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndSelect
Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = 32768
EndIf
# 2:
Code: Select all
If OpenWindow (0,0,0,300,250, "get off, you ugly border" , #PB_Window_ScreenCentered|#PB_Window_SizeGadget )
StickyWindow(0,1)
SetWindowLongPtr_(WindowID(0),#GWL_STYLE,GetWindowLongPtr_(WindowID(0),#GWL_STYLE)&~ #WS_CAPTION)
ResizeWindow(0,GetSystemMetrics_(#SM_CXSCREEN)>>1 - 322>>1,GetSystemMetrics_(#SM_CYSCREEN)>>1 - 275>>1,322,275)
Repeat
Select WaitWindowEvent()
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndSelect
Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = 32768
EndIf
Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 7:26 am
by Poshu
Sadly, both examples still show the ugly border of death (I'd like to make sure that whoever designed that at microsoft will die a painful death) :
I'd like to get that kind of stuff :

Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 8:31 am
by Bisonte
I think you have to declare some areas to size the window....
I mean something like this :
Code: Select all
[1][2][1]
[3] [3]
[1][2][1]
1 size all directions
2 size up-down
3 size left-right
in the Callback you have to check, where the #WM_LBUTTONDOWN is pressed....
Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 9:51 am
by Poshu
Ok, I'll handle resizing myself then... Thanks ^^
Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 12:53 pm
by Thade
Adding my old dirty (I like Flags) Workaround to Rashads Solution I come up with this:
Code: Select all
If OpenWindow (0,0,0,300,250, "get off, you ugly border" , #PB_Window_ScreenCentered|#PB_Window_BorderLess )
StickyWindow(0,1)
SetWindowLongPtr_(WindowID(0),#GWL_STYLE,GetWindowLongPtr_(WindowID(0),#GWL_STYLE)&~ #WS_CAPTION)
ResizeWindow(0,GetSystemMetrics_(#SM_CXSCREEN)>>1 - 322>>1,GetSystemMetrics_(#SM_CYSCREEN)>>1 - 275>>1,322,275)
Repeat
Select WaitWindowEvent()
Case #WM_LBUTTONDOWN
WindowResizeFlag=1
WinX=WindowMouseX(0)
WinY=WindowMouseY(0)
OldWindowMouseX=WinX
OldWindowMouseY=WinY
If WinX <= WindowWidth(0)-15 And WinY <= WindowHeight(0)-15
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
WindowResizeFlag=0
EndIf
Case #WM_LBUTTONUP
WindowResizeFlag=0
EndSelect
If WindowResizeFlag=1
WinX=WindowMouseX(0)
WinY=WindowMouseY(0)
If WinX > WindowWidth(0)-15 And WinY > WindowHeight(0)-15
ResizeWindow(0, #PB_Ignore, #PB_Ignore, WindowWidth(0)+WinX-OldWindowMouseX, WindowHeight(0)+WinY-OldWindowMouseY) ;WinX-OldWindowMouseX
EndIf
EndIf
OldWindowMouseX=WindowMouseX(0)
OldWindowMouseY=WindowMouseY(0)
Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = 32768
EndIf
Another solution I used in the past was drawing (and redrawing) a CanvasGadget into the bottom right corner and watching mouse activity there (using the same flag system)
Btw: The Steam Window seems to be a modified html? (With rightclick you can open the code window) Something like that?
http://wpfwindow.codeplex.com/
Re: Borderless sizable window?
Posted: Tue Feb 24, 2015 1:51 pm
by RASHAD
Hi
- You can do it as an OwnerDrawn window
Or
Code: Select all
Procedure IsMouseOver(hWnd)
GetWindowRect_(hWnd,r.RECT)
GetCursorPos_(p.POINT)
Result = PtInRect_(r,p\y << 32 + p\x)
ProcedureReturn Result
EndProcedure
Procedure WndProc(hwnd, uMsg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_NCACTIVATE
Result = 1
Case #WM_SIZE,#WM_MOVE
ResizeWindow(1,WindowX(0)+2,WindowY(0)+2,WindowWidth(0)+10,WindowHeight(0)+10)
ResizeGadget(0,10,WindowHeight(0)-60,60,20)
ResizeGadget(1,10,WindowHeight(0)-30,60,20)
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow (0,0,0,400,300, "get off, you ugly border" , #PB_Window_BorderLess| #WS_SIZEBOX |#PB_Window_ScreenCentered )
OpenWindow (1,0,0,410,310, "" , #PB_Window_BorderLess| #PB_Window_ScreenCentered,WindowID(0))
SetWindowColor(1,#Gray)
ButtonGadget(0,10,240,60,20,"Test 1")
ButtonGadget(1,10,270,60,20,"Test 2")
SetWindowCallback(@WndProc())
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Debug "Gadget # 0"
Case 1
Debug "Gadget # 1"
EndSelect
Case #WM_LBUTTONDOWN
If IsMouseOver(GadgetID(0)) = 0 And IsMouseOver(GadgetID(1)) = 0
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndIf
EndSelect
Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = 32768
EndIf
Re: Borderless sizable window?
Posted: Wed Feb 25, 2015 2:48 am
by netmaestro
I'll toss one into the ring, you can drag it around and close via rightclick menu:
Code: Select all
Structure NCCALCSIZE_PARAMS2
rgrc.RECT[3]
*lppos.WINDOWPOS
EndStructure
Global gFrameW = GetSystemMetrics_(#SM_CXSIZEFRAME), gCaptionH = GetSystemMetrics_(#SM_CYSIZEFRAME)
Procedure winproc(hwnd, msg, wParam, lParam)
Select msg
Case #WM_NCCALCSIZE
*np.NCCALCSIZE_PARAMS2 = lparam
SetRect_(*np\rgrc[0],
*np\lppos\x+gFrameW,
*np\lppos\y+gCaptionH,
*np\lppos\x+*np\lppos\cx-gFrameW,
*np\lppos\y+*np\lppos\cy-gCaptionH)
ProcedureReturn #WVR_VALIDRECTS | #WVR_REDRAW
Case #WM_NCPAINT, #WM_NCACTIVATE
If msg = #WM_NCACTIVATE And wparam = #False
ProcedureReturn #True
EndIf
GetWindowRect_(hwnd, wr.RECT)
hdcDest = GetWindowDC_(hwnd)
hdcSrc = CreateCompatibleDC_(hdc)
hrgn = CreateRectRgn_(0,0,wr\right-wr\left, wr\bottom-wr\top)
hrgn2 = CreateRectRgn_(gFrameW,gCaptionH,wr\right-wr\left-gFrameW,wr\bottom-wr\top-gCaptionH)
CombineRgn_(hrgn, hrgn, hrgn2, #RGN_XOR)
SelectClipRgn_(hdcDest, hrgn)
imgtmp = CreateImage(#PB_Any, wr\right-wr\left,wr\bottom-wr\top,24,GetSysColor_(#COLOR_BTNFACE))
SelectObject_(hdcSrc, ImageID(imgtmp))
BitBlt_(hdcDest,0,0,wr\right-wr\left, wr\bottom-wr\top,hdcSrc,0,0,#SRCCOPY)
FreeImage(imgtmp)
DeleteDC_(hdcSrc)
ReleaseDC_(hwnd, hdcDest)
DeleteObject_(hrgn)
DeleteObject_(hrgn2)
ProcedureReturn #False
Case #WM_LBUTTONDOWN
SendMessage_(hwnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #WM_RBUTTONUP
DisplayPopupMenu(0, WindowID(0))
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,512,512,"",#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
TextGadget(0,0,0,200,20,"Right-click for menu")
CreatePopupMenu(0)
MenuItem(9, "Exit")
SetWindowLongPtr_(WindowID(0), #GWL_STYLE,GetWindowLongPtr_(WindowID(0), #GWL_STYLE) &~ #WS_SYSMENU)
SetWindowCallback(@winproc(), 0)
SetWindowPos_(WindowID(0),0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)
;=============SECOND WINDOW ========================
OpenWindow(1,0,0,100,100,"ok", #PB_Window_SystemMenu)
Repeat
ev=WaitWindowEvent()
Select ev
Case #PB_Event_Menu
Select EventMenu()
Case 9
End
EndSelect
EndSelect
Until ev=#PB_Event_CloseWindow
It's basically just ownerdrawing the window frame with the window color (so you can't tell it's really the frame). It's like a trick.
[edit] Revised for less lines of code
[edit] Fixed a couple of bugs too
Re: Borderless sizable window?
Posted: Wed Feb 25, 2015 4:22 am
by Poshu
netmaestro wrote:I'll toss one into the ring, you can drag it around and close via rightclick menu:
It's basically just ownerdrawing the window frame with the window color (so you can't tell it's really the frame). It's like a trick.
I knew it was doable with WM_NCPAINT!
Well, I used Bisonte approach in the end.
Re: Borderless sizable window?
Posted: Wed Feb 25, 2015 10:41 am
by Tess
@netmaestro
I'd like to use your code but if i add a second window, the second one can't to be closed or redim. Any idea ?
(Obviously, if i comment this line : SetProp_(WindowID(0), "oldproc", SetWindowLongPtr_(WindowID(0), #GWLP_WNDPROC, @WinProc())), the second window can to be closed or redim)
Thanx.
Code: Select all
Structure NCCALCSIZE_PARAMS2
rgrc.RECT[3]
*lppos.WINDOWPOS
EndStructure
Global gFrameWidth = GetSystemMetrics_(#SM_CXSIZEFRAME), gCaptionHeight = GetSystemMetrics_(#SM_CYSIZEFRAME)
Procedure winproc(hwnd, msg, wParam, lParam)
oldproc = GetProp_(hwnd, "oldproc")
result = oldproc
Select msg
Case #WM_NCDESTROY
RemoveProp_(hwnd, "oldproc")
Case #WM_NCCALCSIZE
*np.NCCALCSIZE_PARAMS2 = lparam
SetRect_(*np\rgrc[0],*np\lppos\x+gFrameWidth,*np\lppos\y+gCaptionHeight,*np\lppos\x+*np\lppos\cx-gFrameWidth,*np\lppos\y+*np\lppos\cy-gFrameWidth)
ProcedureReturn #WVR_VALIDRECTS | #WVR_REDRAW
Case #WM_NCPAINT, #WM_NCACTIVATE
GetWindowRect_(hwnd, wr.RECT)
hdcDest = GetWindowDC_(hwnd)
hdcSrc = CreateCompatibleDC_(hdc)
hrgn = CreateRectRgn_(0,0,wr\right-wr\left, wr\bottom-wr\top)
hrgn2 = CreateRectRgn_(gFrameWidth,gCaptionHeight,wr\right-wr\left-gFrameWidth,wr\bottom-wr\top-gCaptionHeight)
CombineRgn_(hrgn, hrgn, hrgn2, #RGN_XOR)
SelectClipRgn_(hdcDest, hrgn)
imgtmp = CreateImage(#PB_Any, wr\right-wr\left,wr\bottom-wr\top,24,GetSysColor_(#COLOR_BTNFACE))
SelectObject_(hdcSrc, ImageID(imgtmp))
BitBlt_(hdcDest,0,0,wr\right-wr\left, wr\bottom-wr\top,hdcSrc,0,0,#SRCCOPY)
FreeImage(imgtmp)
DeleteDC_(hdcSrc)
ReleaseDC_(hwnd, hdcDest)
DeleteObject_(hrgn)
DeleteObject_(hrgn2)
ProcedureReturn 0
Case #WM_LBUTTONDOWN
SendMessage_(hwnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndSelect
ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure
OpenWindow(0,0,0,512,512,"",#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
TextGadget(0,0,0,200,20,"Right-click for menu")
CreatePopupMenu(0)
MenuItem(9, "Exit")
SetWindowLongPtr_(WindowID(0), #GWL_STYLE,GetWindowLongPtr_(WindowID(0), #GWL_STYLE) &~ #WS_SYSMENU)
SetProp_(WindowID(0), "oldproc", SetWindowLongPtr_(WindowID(0), #GWLP_WNDPROC, @WinProc()))
SetWindowPos_(WindowID(0),0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)
;=============SECOND WINDOW ========================
OpenWindow(1,0,0,100,100,"ok")
; This window can't to be closed or redim
Repeat
ev=WaitWindowEvent()
Select ev
Case #WM_RBUTTONUP
DisplayPopupMenu(0, WindowID(0))
Case #PB_Event_Menu
Select EventMenu()
Case 9
End
EndSelect
EndSelect
Until ev=#PB_Event_CloseWindow
Re: Borderless sizable window?
Posted: Wed Feb 25, 2015 4:49 pm
by netmaestro
Sorry, I was a bit sloppy, gobbling up #WM_NCACTIVATE every time instead of letting it continue when it needs to. The code should play nice with a second window now.
Re: Borderless sizable window?
Posted: Sun Dec 06, 2015 10:16 am
by Poshu
I came here hopping I would have posted my own code (stupid, stupid past-self!) and I tried the code @netmaestro posted but...
On Windows 10
While I'm in no way a windows api expert, I can't find any reason in the code for the window top corners to be rounded; and any normal window I open are perfectly square. Any idea here?
Re: Borderless sizable window?
Posted: Sun Dec 06, 2015 11:36 am
by TI-994A
Poshu wrote:While I'm in no way a windows api expert, I can't find any reason in the code for the window top corners to be rounded; and any normal window I open are perfectly square. Any idea here?
No expert myself, but for some reason, adding the
#PB_Window3D_Borderless flag seems to square up the corners on Windows 8 and 10:
Code: Select all
OpenWindow(0, 0, 0, 512, 512, "", #PB_Window_SizeGadget |
#PB_Window_ScreenCentered |
#PB_Window3D_Borderless)
TextGadget(0,0,0,200,20,"Right-click for menu")
CreatePopupMenu(0)
MenuItem(9, "Exit")
SetWindowCallback(@winproc(), 0)
SetWindowPos_(WindowID(0),0,0,0,0,0,#SWP_NOMOVE |
#SWP_NOSIZE |
#SWP_NOZORDER |
#SWP_FRAMECHANGED)
While that's not an officially supported flag for conventional windows,
yours is hardly a conventional window.

Re: Borderless sizable window?
Posted: Sun Dec 06, 2015 1:27 pm
by Poshu
It does... but... what... why? WHY??????
And also... How did you find that? Have you tried like every random constant ever xD?
Re: Borderless sizable window?
Posted: Sun Dec 06, 2015 1:47 pm
by chi
The correct way to disable round corner:
Code: Select all
SetWindowTheme_(WindowID(0), #Null, "")