Moving a borderless window ?
Moving a borderless window ?
Hi,
I'm not really sure whether I have to use the Drag&Drop library or not to move a #PB_Window_BorderLess window. It seems that it's only made for dragging files, images and texts inside or outside a window or a gadget. But I'm searching for an event that recognize that the left click is pressed and hold, then I'll use ResizeWindow() to move my window at DesktopMouseX(), DesktopMouseY(). An ideal solution would be to have a specific area that accepts this kind of event.
So, if you can help, you'll receive all my gratitude ...
I'm not really sure whether I have to use the Drag&Drop library or not to move a #PB_Window_BorderLess window. It seems that it's only made for dragging files, images and texts inside or outside a window or a gadget. But I'm searching for an event that recognize that the left click is pressed and hold, then I'll use ResizeWindow() to move my window at DesktopMouseX(), DesktopMouseY(). An ideal solution would be to have a specific area that accepts this kind of event.
So, if you can help, you'll receive all my gratitude ...
Re: Moving a borderless window ?
Code: Select all
If OpenWindow(0, 0, 0, 800, 600, "Moveable window", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,100,25,"Exit")
CocoaMessage(0, WindowID(0), "setMovableByWindowBackground:", #YES) ; make window moveable by mouse
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow : End
Case #PB_Event_Gadget
If EventGadget()=0 And EventType()=#PB_EventType_LeftClick
End
EndIf
EndSelect
ForEver
EndIf
Re: Moving a borderless window ?
For the specific area, you could use an Canvasgadget().Joubarbe wrote:But I'm searching for an event that recognize that the left click is pressed and hold, then I'll use ResizeWindow() to move my window at DesktopMouseX(), DesktopMouseY(). An ideal solution would be to have a specific area that accepts this kind of event.
Code: Select all
Procedure Exit()
End
EndProcedure
Procedure LeftMouseDown()
Shared MouseDown, OffsetX, OffsetY
MouseDown = #True
offsetX = WindowMouseX(0)
OffsetY = WindowMouseY(0)
EndProcedure
Procedure LeftMouseUp()
Shared MouseDown
MouseDown = #False
EndProcedure
Procedure MouseMove()
Shared MouseDown, OffsetX, OffsetY
If MouseDown And GetGadgetAttribute(1,#PB_Canvas_Buttons)&#PB_Canvas_LeftButton
ResizeWindow(0,DesktopMouseX()-OffsetX,DesktopMouseY()-OffsetY,#PB_Ignore,#PB_Ignore)
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 800, 600, "Moveable window", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,100,25,"Exit")
BindEvent(#PB_Event_Gadget,@Exit(),0,0,#PB_EventType_LeftClick)
CanvasGadget(1,120,10,200,200)
BindEvent(#PB_Event_Gadget,@LeftMouseDown(),0,1,#PB_EventType_LeftButtonDown)
BindEvent(#PB_Event_Gadget,@LeftMouseUp() ,0,1,#PB_EventType_LeftButtonUp)
BindEvent(#PB_Event_Gadget,@MouseMove() ,0,1,#PB_EventType_MouseMove)
If StartDrawing(CanvasOutput(1))
Box(0,0,OutputWidth(),OutputHeight(),RGB(0,0,128))
StopDrawing()
EndIf
Repeat:WaitWindowEvent():ForEver
EndIf
Re: Moving a borderless window ?
You win the achievement #AllMyGratitude. You can't share it with friends.
(Thanks!)
(Thanks!)
Re: Moving a borderless window ?
Hi Danilo; great code, as always. I've noticed that there doesn't seem to be any OSX examples on the forum that demonstrate such moving by dragging only designated areas of the window. This example illustrates how to handle such moves for both Windows and OSX:The mechanics of the mouse events itself is quite short, and the rest is just the demonstration code.
Code: Select all
;==================================================
;
; Moving a window by clicking on the background
; or on any designated part of it
;
; for Windows and OSX
;
; by TI-994A - 26th October 2013
;
;==================================================
EnableExplicit
#NSMouseMoved = 5
Enumeration
#MainWindow
#Button1
#Button2
EndEnumeration
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Structure RECT
left.i
top.i
right.i
bottom.i
EndStructure
CompilerEndIf
Define appQuit, xDraw, useHotspot, hotSpot.RECT, stateText.s
With hotSpot
\left = 0
\right = 400
\top = 30
\bottom = 70
EndWith
Procedure inHotSpot(*hotSpot.RECT)
Define result
With *hotSpot
If WindowMouseX(#MainWindow) > \left And
WindowMouseX(#MainWindow) < \right And
WindowMouseY(#MainWindow) > \top And
WindowMouseY(#MainWindow) < \bottom
result = 1
EndIf
EndWith
ProcedureReturn result
EndProcedure
Macro drawTitle()
StartDrawing(WindowOutput(#MainWindow))
Box(hotSpot\left, hotSpot\top, hotSpot\right - hotSpot\left,
hotSpot\bottom - hotSpot\top, RGB(0, 0, 150))
xDraw = (400 - TextWidth(stateText)) / 2
DrawText(xDraw, 40, stateText, RGB(255, 255, 255), RGB(0, 0, 150))
StopDrawing()
EndMacro
Macro moveMode()
If useHotspot
useHotspot = 0
SetGadgetText(#Button1, "change to specific area")
stateText = "click anywhere on this window to move it"
drawTitle()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
CocoaMessage(0, WindowID(#MainWindow), "setMovableByWindowBackground:", #YES)
CompilerEndIf
Else
useHotspot = 1
SetGadgetText(#Button1, "change to full window")
stateText = "click anywhere on this bar to move the window"
drawTitle()
EndIf
EndMacro
OpenWindow(#MainWindow, 0, 0, 400, 300, "Move Borderless Window",
#PB_Window_BorderLess | #PB_Window_ScreenCentered)
ButtonGadget(#Button1, 10, 260, 180, 30, "change to specific area")
ButtonGadget(#Button2, 210, 260, 180, 30, "q u i t")
SetWindowColor(#MainWindow, RGB(150, 150, 250))
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Define cocoaEvent, cocoaEventType
Define sharedApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
CocoaMessage(0, WindowID(#MainWindow), "setMovableByWindowBackground:", #YES)
CocoaMessage(0, WindowID(#MainWindow), "setAcceptsMouseMovedEvents:", #YES)
MessageRequester("Borderless Window", "moving a window without a title bar")
CompilerEndIf
stateText = "click anywhere on this window to move it"
drawTitle()
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #Button1
moveMode()
Case #Button2
appQuit = 1
EndSelect
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Case #WM_PAINT
drawTitle()
Case #WM_LBUTTONDOWN
If (useHotspot And inHotSpot(@hotSpot)) Or Not useHotspot
SendMessage_(WindowID(#MainWindow), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
EndIf
CompilerEndIf
EndSelect
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
cocoaEvent = CocoaMessage(0, sharedApp, "currentEvent")
If cocoaEvent
cocoaEventType = CocoaMessage(0, cocoaEvent, "type")
If cocoaEventType = #NSMouseMoved And useHotspot
If inHotSpot(@hotSpot)
CocoaMessage(0, WindowID(#MainWindow),
"setMovableByWindowBackground:", #YES)
Else
CocoaMessage(0, WindowID(#MainWindow),
"setMovableByWindowBackground:", #NO)
EndIf
EndIf
EndIf
CompilerEndIf
Until appQuit
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
Re: Moving a borderless window ?
Thanks TI-994A, nice code.
- BasicallyPure
- Enthusiast
- Posts: 536
- Joined: Thu Mar 24, 2011 12:40 am
- Location: Iowa, USA
Re: Moving a borderless window ?
I have been trying to do this with a different variation.
I would like to be able to drag the window only if the user clicks on the window background.
Any clicks on gadgets should be ignored.
Is there some clever API trick that will detect a click only on the window background?
This code almost works but not totally.
Right click to exit.
BP
edit: thanks to Danilo's help it now works as desired.
I would like to be able to drag the window only if the user clicks on the window background.
Any clicks on gadgets should be ignored.
Is there some clever API trick that will detect a click only on the window background?
This code almost works but not totally.
Right click to exit.
BP
edit: thanks to Danilo's help it now works as desired.
Code: Select all
EnableExplicit
#MainWin = 0
#PopUpMenu = 0
#Canvas = 0
#StrGad = 1
#ButtonGad = 2
#MenuChoice_OnTop = 0
#MenuChoice_Quit = 1
Declare INIT_GUI()
Declare EVENT_LOOP()
Declare WinCallback(hWnd, msg, wParam, lParam)
If INIT_GUI()
EVENT_LOOP()
EndIf
End
; procedures
Procedure EVENT_LOOP()
Protected.i TopState, Quit
Repeat
Select WaitWindowEvent()
Case #PB_Event_RightClick
DisplayPopupMenu(#PopUpMenu, WindowID(#MainWin))
Case #PB_Event_Menu
Select EventMenu()
Case #MenuChoice_OnTop : TopState ! 1
StickyWindow(#MainWin, TopState)
SetMenuItemState(#PopUpMenu, #MenuChoice_OnTop, TopState)
Case #MenuChoice_Quit : Quit = #True
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #Canvas
;Debug EventType()
Case #StrGad
;Debug EventType()
Case #ButtonGad
;Debug EventType()
EndSelect
Case #PB_Event_CloseWindow : Quit = #True
EndSelect
Until Quit
EndProcedure
Procedure INIT_GUI()
; returns window handle on success or 0 if fail.
Protected flags.i = #PB_Window_ScreenCentered | #PB_Window_BorderLess
Protected Result.i = OpenWindow(#MainWin, 0, 0, 344, 54, "Drag Borderless Window", flags)
If Result
SetWindowCallback(@WinCallback())
If CreatePopupMenu(#PopUpMenu)
MenuItem(#MenuChoice_OnTop, "Always on top")
MenuItem(#MenuChoice_Quit,"Quit")
Else : Result = 0
EndIf
If CanvasGadget(#Canvas,80,10,150,35)
StartDrawing(CanvasOutput(#Canvas))
Box(0,0,150,35,$650015)
DrawText(10,10,"Canvas",$FFFFFF,$650015)
StopDrawing()
Else : Result = 0
EndIf
If StringGadget(#StrGad,15,15,50,25,"string") And
ButtonGadget(#ButtonGad,250,10,70,30,"Button")
Else : Result = 0
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure WinCallback(hWnd, msg, wParam, lParam)
If msg = #WM_LBUTTONDOWN
SendMessage_(hWnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
ProcedureReturn 0
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Last edited by BasicallyPure on Sun Oct 27, 2013 4:05 am, edited 1 time in total.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Until you know everything you know nothing, all you have is what you believe.
Re: Moving a borderless window ?
Just use a window callback and remove the WinAPI mouse messages from your event loop.BasicallyPure wrote:I have been trying to do this with a different variation.
I would like to be able to drag the window only if the user clicks on the window background.
Any clicks on gadgets should be ignored.
Is there some clever API trick that will detect a click only on the window background?
Code: Select all
Procedure WinCallback(hWnd, msg, wParam, lParam)
If msg = #WM_LBUTTONDOWN
SendMessage_(hWnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
ProcedureReturn 0
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
SetWindowCallback(@WinCallback())
- BasicallyPure
- Enthusiast
- Posts: 536
- Joined: Thu Mar 24, 2011 12:40 am
- Location: Iowa, USA
Re: Moving a borderless window ?
Thanks Danilo, that's exactly what I wanted.
I have updated my code above.
I see that you used the same SendMessage_ that TI-994A used in his example.
I don't understand why it works but I cannot deny that it does.
BP
I have updated my code above.
I see that you used the same SendMessage_ that TI-994A used in his example.
Code: Select all
SendMessage_(WindowID(#MainWindow), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
BP
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Until you know everything you know nothing, all you have is what you believe.
Re: Moving a borderless window ?
Check out 10 years old CodeArchive: CodeArchiv_v393/Windows/FX/Move_borderless_Window.pbBasicallyPure wrote:I see that you used the same SendMessage_ that TI-994A used in his example.
It is recommended to do it in a callback now, but many of the old PB tricks in the CodeArchive still work,
at least with slightly adjustments. Check out the (old & new) CodeArchive at http://purearea.net
It tells Windows that the left mouse button is down on the non-client area of the window, specifically on the title bar (caption),BasicallyPure wrote:I don't understand why it works but I cannot deny that it does.Code: Select all
SendMessage_(WindowID(#MainWindow), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
so Windows switches to a special "move window" mode.
- Michael Vogel
- Addict
- Posts: 2666
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Moving a borderless window ?
Would it also be possible to move the window by clicking on a CanvasGadget?
Code: Select all
Enumeration
#MainWindow
#MenuQuit
EndEnumeration
WinID=OpenWindow(#MainWindow,0,0,500,500,"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
SetWindowColor(#MainWindow,#Red)
CanvasGadget(0,0,0,500,500); <------
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Escape,#MenuQuit)
StickyWindow(#MainWindow,1)
HideWindow(#MainWindow,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
If EventGadget()=#MenuQuit
Break
EndIf
Case #WM_LBUTTONDOWN
Debug "down"
SendMessage_(WinID,#WM_NCLBUTTONDOWN,#HTCAPTION,0)
Debug "ok"
EndSelect
ForEver
Re: Moving a borderless window ?
Sure:Michael Vogel wrote:Would it also be possible to move the window by clicking on a CanvasGadget?
Code: Select all
Enumeration
#MainWindow
#Canvas
EndEnumeration
wFlags = #PB_Window_ScreenCentered | #PB_Window_BorderLess
OpenWindow(#MainWindow, #PB_Any, #PB_Any, 500, 500, "", wFlags)
CanvasGadget(#Canvas, 5, 5, 490, 490)
SetWindowColor(#MainWindow, #Red)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #Canvas
Select EventType()
Case #PB_EventType_LeftButtonDown
DisableGadget(#Canvas, 1)
SendMessage_(WindowID(#MainWindow), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
DisableGadget(#Canvas, 0)
EndSelect
EndSelect
EndSelect
ForEver
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
Re: Moving a borderless window ?
Hi MV
With CanvasGadget() or any control else
See what Danilo did with moving by area
Or :
With CanvasGadget() or any control else
See what Danilo did with moving by area
Or :
Code: Select all
WinID=OpenWindow(#MainWindow,0,0,500,500,"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
SetWindowColor(#MainWindow,#Red)
CanvasGadget(0,0,0,500,500); <------
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Escape,#MenuQuit)
StickyWindow(#MainWindow,1)
HideWindow(#MainWindow,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
If EventGadget()=#MenuQuit
Break
EndIf
Case #WM_MOUSEMOVE
GetCursorPos_(m.POINT)
ScreenToClient_(WindowID(#MainWindow),m)
If Down = 1
ResizeWindow(#MainWindow,WindowX(#MainWindow)+m\x-p\x,WindowY(#MainWindow)+m\y-p\y,#PB_Ignore,#PB_Ignore)
EndIf
Case #WM_LBUTTONDOWN
GetCursorPos_(p.POINT)
ScreenToClient_(WindowID(#MainWindow),p)
Down = 1
Case #WM_LBUTTONUP
Down = 0
EndSelect
ForEver
Egypt my love
- Michael Vogel
- Addict
- Posts: 2666
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Moving a borderless window ?
Thanks to you both, you are brilliant!
But...
... how to keep #PB_EventType_LeftClick events working? These seems to be impossible in both cases. I tried to add a SetActiveGadget(#Canvas) line after enabling the gadget in TI-99s code, but with no success.
And I tried to modify Rashads code to check if the button down and up events have been done at the same cursor position, but in all cases "down" is set to 0 after releasing the mouse button...
But...
... how to keep #PB_EventType_LeftClick events working? These seems to be impossible in both cases. I tried to add a SetActiveGadget(#Canvas) line after enabling the gadget in TI-99s code, but with no success.
And I tried to modify Rashads code to check if the button down and up events have been done at the same cursor position, but in all cases "down" is set to 0 after releasing the mouse button...
Code: Select all
Case #WM_MOUSEMOVE
;Case #PB_EventType_MouseMove
GetCursorPos_(m.POINT)
ScreenToClient_(WinApps,m)
If Down=1
ResizeWindow(#WinApps,WindowX(#WinApps)+m\x-p\x,WindowY(#WinApps)+m\y-p\y,#PB_Ignore,#PB_Ignore)
Debug "M"
EndIf
Case #WM_LBUTTONDOWN
;Case #PB_EventType_LeftButtonDown
Debug "*"
GetCursorPos_(p.POINT)
ScreenToClient_(WinApps,p)
Down=1
Debug "D"
Case #WM_LBUTTONUP
;Case #PB_EventType_LeftButtonUp
Debug "U"
If m\x=p\x And m\y=p\y
Debug "0"
Down=0
Else
Debug "+"
Down=2
EndIf
:
:
Case #PB_EventType_LeftClick
If Down=0
:
Re: Moving a borderless window ?
Ctrl down to move around
Ctrl up to Normal case
Remember it does not matter if the CanvasGadget() is the Z-Order object or not
Ctrl up to Normal case
Remember it does not matter if the CanvasGadget() is the Z-Order object or not
Code: Select all
Enumeration
#MainWindow
#MenuQuit
EndEnumeration
Define p.POINT,m.POINT
WinID=OpenWindow(#MainWindow,0,0,500,500,"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
SetWindowColor(#MainWindow,#Red)
CanvasGadget(0,0,0,500,500); <------
AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Escape,#MenuQuit)
StickyWindow(#MainWindow,1)
HideWindow(#MainWindow,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
If EventGadget()=#MenuQuit
Break
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case 0
If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
If GetAsyncKeyState_(#VK_CONTROL) & 32768 = 0
StartDrawing(CanvasOutput(0))
x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
Circle(x, y, 10, RGB(Random(255), Random(255), Random(255)))
StopDrawing()
EndIf
EndIf
EndSelect
Case #WM_MOUSEMOVE
GetCursorPos_(m.POINT)
ScreenToClient_(WindowID(#MainWindow),m)
If Down = 1
ResizeWindow(#MainWindow,WindowX(#MainWindow)+m\x-p\x,WindowY(#MainWindow)+m\y-p\y,#PB_Ignore,#PB_Ignore)
EndIf
Case #WM_LBUTTONDOWN
If GetAsyncKeyState_(#VK_CONTROL) & 32768 = 32768
GetCursorPos_(p.POINT)
ScreenToClient_(WindowID(#MainWindow),p)
Down = 1
Else
Down = 0
EndIf
EndSelect
ForEver
Egypt my love