Borderless sizable window?

Windows specific forum
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Borderless sizable window?

Post 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?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4996
Joined: Sun Apr 12, 2009 6:27 am

Re: Borderless sizable window?

Post 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
Egypt my love
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Borderless sizable window?

Post 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) :
Image

I'd like to get that kind of stuff :
Image
Image
Last edited by Poshu on Tue Feb 24, 2015 10:35 am, edited 3 times in total.
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Borderless sizable window?

Post 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....
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Borderless sizable window?

Post by Poshu »

Ok, I'll handle resizing myself then... Thanks ^^
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

Re: Borderless sizable window?

Post 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/
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4996
Joined: Sun Apr 12, 2009 6:27 am

Re: Borderless sizable window?

Post 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
Egypt my love
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Borderless sizable window?

Post 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
Last edited by netmaestro on Wed Feb 25, 2015 5:10 pm, edited 6 times in total.
BERESHEIT
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Borderless sizable window?

Post 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.
Tess
New User
New User
Posts: 6
Joined: Thu Sep 25, 2014 8:59 am

Re: Borderless sizable window?

Post 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

User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Borderless sizable window?

Post 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.
BERESHEIT
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Borderless sizable window?

Post 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...

Image
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?
User avatar
TI-994A
Addict
Addict
Posts: 2754
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Borderless sizable window?

Post 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. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Borderless sizable window?

Post by Poshu »

It does... but... what... why? WHY??????

And also... How did you find that? Have you tried like every random constant ever xD?
User avatar
chi
Addict
Addict
Posts: 1087
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

Re: Borderless sizable window?

Post by chi »

The correct way to disable round corner:

Code: Select all

SetWindowTheme_(WindowID(0), #Null, "")
Et cetera is my worst enemy
Post Reply