drwaing a box while dragging mouse
-
localmotion34
- Enthusiast

- Posts: 665
- Joined: Fri Sep 12, 2003 10:40 pm
- Location: Tallahassee, Florida
drwaing a box while dragging mouse
how do you get a box drawn after you press and hold the left mouse button down, and then drag the mouse. what i mean is like in visual designer when you click and drag a gadget, a box is drawn that follows the mouse, and then the gadget is repositioned to the new coordinates of the box. how do you do that?
Code: Select all
!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Thats the base:
And here a modified version, a Photoshop clone. 
Code: Select all
;
; by Danilo, 24.11.2003 - german forum
;
Procedure OnMouseSelection(x,y,width,height)
Debug "-----"
Debug "Selected:"
Debug "X : "+Str(x)
Debug "Y : "+Str(y)
Debug "Width : "+Str(width)
Debug "Height: "+Str(height)
EndProcedure
Procedure DrawMouseSelector(hWnd)
Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
Shared WindowProc_MouseSelectRect.RECT
If WindowProc_MouseSelectStartX > WindowProc_MouseSelectLastX
WindowProc_MouseSelectRect\left = WindowProc_MouseSelectLastX
WindowProc_MouseSelectRect\right = WindowProc_MouseSelectStartX
Else
WindowProc_MouseSelectRect\left = WindowProc_MouseSelectStartX
WindowProc_MouseSelectRect\right = WindowProc_MouseSelectLastX
EndIf
If WindowProc_MouseSelectStartY > WindowProc_MouseSelectLastY
WindowProc_MouseSelectRect\top = WindowProc_MouseSelectLastY
WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectStartY
Else
WindowProc_MouseSelectRect\top = WindowProc_MouseSelectStartY
WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectLastY
EndIf
hDC = GetDC_(hWnd)
DrawFocusRect_(hDC,@WindowProc_MouseSelectRect)
ReleaseDC_(hWnd,hDC)
;UpdateWindow_(hWnd) ; Win9x fix?
EndProcedure
Procedure WindowProc(hWnd,Msg,wParam,lParam)
Shared WindowProc_MouseSelect
Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
Shared WindowProc_MouseSelectRect.RECT
Select Msg
Case #WM_LBUTTONDOWN
WindowProc_MouseSelect = 1
WindowProc_MouseSelectStartX = lParam&$FFFF
WindowProc_MouseSelectStartY = (lParam>>16)&$FFFF
GetClientRect_(hWnd,winrect.RECT)
MapWindowPoints_(hWnd,0,winrect,2)
ClipCursor_(winrect)
Case #WM_LBUTTONUP
If WindowProc_MouseSelect > 1
DrawMouseSelector(hWnd)
If WindowProc_MouseSelectRect\left <> WindowProc_MouseSelectRect\right And WindowProc_MouseSelectRect\top <> WindowProc_MouseSelectRect\bottom
OnMouseSelection(WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\top,WindowProc_MouseSelectRect\right-WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\bottom-WindowProc_MouseSelectRect\top)
SetCapture_(0)
EndIf
EndIf
ClipCursor_(0)
WindowProc_MouseSelect = 0
Case #WM_MOUSEMOVE
If WindowProc_MouseSelect > 0 And wParam & #MK_LBUTTON
If WindowProc_MouseSelect > 1
DrawMouseSelector(hWnd)
Else
WindowProc_MouseSelect + 1
EndIf
WindowProc_MouseSelectLastX = lParam&$FFFF
WindowProc_MouseSelectLastY = (lParam>>16)&$FFFF
DrawMouseSelector(hWnd)
SetCapture_(hWnd)
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector")
SetWindowCallback(@WindowProc())
HideWindow(0,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
EndSelect
ForEverCode: Select all
;
; by Danilo, 24.11.2003 - german forum
;
; - modified to a full blown paint program,
; by Danilo - 09.06.2004, english forum ;)
;
Procedure OnMouseSelection(x,y,width,height)
Shared Current_ActiveColor
;Debug "-----"
;Debug "Selected:"
;Debug "X : "+Str(x)
;Debug "Y : "+Str(y)
;Debug "Width : "+Str(width)
;Debug "Height: "+Str(height)
UseImage(1)
If StartDrawing(ImageOutput())
Box(x,y,width,height,Current_ActiveColor)
StopDrawing()
EndIf
SetGadgetState(1,ImageID()) ; update ImageGadget
EndProcedure
Procedure DrawMouseSelector(hWnd)
Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
Shared WindowProc_MouseSelectRect.RECT
If WindowProc_MouseSelectStartX > WindowProc_MouseSelectLastX
WindowProc_MouseSelectRect\left = WindowProc_MouseSelectLastX
WindowProc_MouseSelectRect\right = WindowProc_MouseSelectStartX
Else
WindowProc_MouseSelectRect\left = WindowProc_MouseSelectStartX
WindowProc_MouseSelectRect\right = WindowProc_MouseSelectLastX
EndIf
If WindowProc_MouseSelectStartY > WindowProc_MouseSelectLastY
WindowProc_MouseSelectRect\top = WindowProc_MouseSelectLastY
WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectStartY
Else
WindowProc_MouseSelectRect\top = WindowProc_MouseSelectStartY
WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectLastY
EndIf
hDC = GetDC_(hWnd)
DrawFocusRect_(hDC,@WindowProc_MouseSelectRect)
ReleaseDC_(hWnd,hDC)
;UpdateWindow_(hWnd) ; Win9x fix?
EndProcedure
Procedure WindowProc(hWnd,Msg,wParam,lParam)
Shared WindowProc_MouseSelect
Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
Shared WindowProc_MouseSelectRect.RECT
Select Msg
Case #WM_LBUTTONDOWN
MouseX = lParam&$FFFF
MouseY = (lParam>>16)&$FFFF
If MouseX =< 600 And MouseY <= 480
WindowProc_MouseSelect = 1
WindowProc_MouseSelectStartX = MouseX
WindowProc_MouseSelectStartY = MouseY
GetClientRect_(GadgetID(1),winrect.RECT)
MapWindowPoints_(hWnd,0,winrect,2)
ClipCursor_(winrect)
EndIf
Case #WM_LBUTTONUP
If WindowProc_MouseSelect > 1
DrawMouseSelector(hWnd)
If WindowProc_MouseSelectRect\left <> WindowProc_MouseSelectRect\right And WindowProc_MouseSelectRect\top <> WindowProc_MouseSelectRect\bottom
OnMouseSelection(WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\top,WindowProc_MouseSelectRect\right-WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\bottom-WindowProc_MouseSelectRect\top)
SetCapture_(0)
EndIf
EndIf
ClipCursor_(0)
WindowProc_MouseSelect = 0
Case #WM_MOUSEMOVE
If WindowProc_MouseSelect > 0 And wParam & #MK_LBUTTON
If WindowProc_MouseSelect > 1
DrawMouseSelector(hWnd)
Else
WindowProc_MouseSelect + 1
EndIf
WindowProc_MouseSelectLastX = lParam&$FFFF
WindowProc_MouseSelectLastY = (lParam>>16)&$FFFF
DrawMouseSelector(hWnd)
SetCapture_(hWnd)
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,640,500,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector (modified)")
SetWindowCallback(@WindowProc())
CreateGadgetList(WindowID())
ImageGadget(1,0,0,600,480,CreateImage(1,600,480))
RandomSeed(666)
For a = 0 To 20
CreateImage(a+2,40,24)
StartDrawing(ImageOutput())
col = Random($FFFFFF)
Box(0,0,40,24,col)
If a = 0 : Current_ActiveColor = col : EndIf
StopDrawing()
ButtonImageGadget(a+2,600,a*24,40,24,ImageID())
Next a
CreateImage(25,40,18)
If StartDrawing(ImageOutput())
Box(1,1,38,16,Current_ActiveColor)
StopDrawing()
EndIf
TextGadget(24,10,485,100,15,"Active color:")
ImageGadget(25,120,482,40,18,ImageID())
HideWindow(0,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
gadget = EventGadgetID()
If gadget >= 2 And gadget <= 22
UseImage(gadget) ; get new color
If StartDrawing(ImageOutput())
Current_ActiveColor = Point(5,5)
StopDrawing()
EndIf
UseImage(25) ; update current color gadget
If StartDrawing(ImageOutput())
Box(1,1,38,16,Current_ActiveColor)
StopDrawing()
EndIf
SetGadgetState(25,ImageID())
EndIf
EndSelect
ForEver-
localmotion34
- Enthusiast

- Posts: 665
- Joined: Fri Sep 12, 2003 10:40 pm
- Location: Tallahassee, Florida
what i was asking for is this: open visual designer and draw a button gadget on the window. now move the mouse over the buttongadget. press the left button down and a rectange is drawn around the buttongadget. keep holding the left button down and drag the mouse. the rectangle follows the mouse around the window. release the button and the button gadget moves to where the rectange was when the mouse button was released. thats what i need to know how to do.
Code: Select all
!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
-
localmotion34
- Enthusiast

- Posts: 665
- Joined: Fri Sep 12, 2003 10:40 pm
- Location: Tallahassee, Florida
any idea at all? i mean how did they do it for visual designer? click on a gadget, a box is drawn, drag the mouse and the drawn box follows. release the mouse, and the gadget moves to where the box is when the mouse was released. someone has to know.
Code: Select all
!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
although often not seen as the 'right' way, you can draw directly on a window, so...
1. click on the gadget -> grab the click, retrieve the coordinates of that gadget
2. draw in xor mode a box
3. when the mouse moves, draw the box again (erasing it) and draw it again at the new mouse pos (showing it again)
4. when mouse button released draw the box one more time (erasing it again) then move the gadget to the new spot
i think that's all...
1. click on the gadget -> grab the click, retrieve the coordinates of that gadget
2. draw in xor mode a box
3. when the mouse moves, draw the box again (erasing it) and draw it again at the new mouse pos (showing it again)
4. when mouse button released draw the box one more time (erasing it again) then move the gadget to the new spot
i think that's all...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB - upgrade incoming...)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Are you requesting that we should write your code, or did youlocalmotion34 wrote:someone has to know.
try yourself ??
If you tried yourself, its an good idea to show your current code.
Look how my above selector-examples work, look what messages
i catch, look in PSDK/MSDN what WM_MOUSEMOVE, WM_LBUTTONDOWN,
WM_LBUTTONUP etc. do, read a book about WinAPI, ...
...and look at this small'n dirty example:
Code: Select all
;
; simple gadget mover example
;
; by Danilo, 10.06.2004 - english forum
; (coded for lazy localmotion34)
;
Structure MouseBtnMover
WndProc.l
hGadget.l
Gadget.l
EndStructure
NewList oldCallbacks.MouseBtnMover()
Global MouseBtnDown , hMouseBtnDown
Global MouseBtnDownX , MouseBtnDownY
Global MouseMoveCursor, rect.RECT
Global MoveMode
Procedure DrawSelectorBox()
If StartDrawing(WindowOutput())
DrawingMode(2|4)
Box(rect\left-1,rect\Top-1,rect\right+2,rect\bottom+2)
Box(rect\left-2,rect\Top-2,rect\right+4,rect\bottom+4)
StopDrawing()
EndIf
EndProcedure
Procedure SetCurrentRect(hWnd)
GetWindowRect_(hWnd,@rect)
MapWindowPoints_(0,WindowID(0),@rect,2)
rect\right - rect\left
rect\bottom - rect\top
EndProcedure
Procedure _MoveCallback(hWnd,Msg,wParam,lParam)
If MoveMode
SetCursor_(MouseMoveCursor)
If Msg = #WM_LBUTTONDOWN Or Msg = #WM_LBUTTONDBLCLK
MouseBtnDownX = lParam&$FFFF
MouseBtnDownY = (lParam>>16)&$FFFF
MouseBtnDown = #TRUE
hMouseBtnDown = hWnd
SetCurrentRect(hWnd)
DrawSelectorBox()
GetClientRect_(WindowID(0),ClipRect.RECT)
MapWindowPoints_(WindowID(0),0,@ClipRect,2)
ClipCursor_(@ClipRect)
SetCapture_(hWnd)
ProcedureReturn 0
ElseIf Msg = #WM_LBUTTONUP
MouseBtnDown = #FALSE
DrawSelectorBox()
ForEach oldCallbacks()
If oldCallbacks()\hGadget = hWnd
ResizeGadget(oldCallbacks()\Gadget,rect\left,rect\top,-1,-1)
EndIf
Next
;MoveWindow_(hWnd,rect\left,rect\top,rect\right,rect\bottom,1)
SetCapture_(0)
ClipCursor_(0)
;InvalidateRect_(WindowID(0),0,1)
;UpdateWindow_(WindowID(0))
ProcedureReturn 0
ElseIf Msg = #WM_MOUSEMOVE
If MouseBtnDown
MouseOffsetX.w = lParam&$FFFF - MouseBtnDownX
MouseOffsetY.w = (lParam>>16)&$FFFF - MouseBtnDownY
DrawSelectorBox()
rect\left + MouseOffsetX
rect\top + MouseOffsetY
MouseBtnDownX + MouseOffsetX
MouseBtnDownY + MouseOffsetY
DrawSelectorBox()
EndIf
ProcedureReturn 0
EndIf
EndIf
ForEach oldCallbacks()
If oldCallbacks()\hGadget = hWnd
ProcedureReturn CallWindowProc_(oldCallbacks()\WndProc,Hwnd,Msg,wParam,lParam)
EndIf
Next
EndProcedure
Procedure SetMoveCallback(gadget)
AddElement(oldCallbacks())
oldCallbacks()\WndProc = SetWindowLong_(GadgetID(gadget),#GWL_WNDPROC,@_MoveCallback())
oldCallbacks()\hGadget = GadgetID(gadget)
oldCallbacks()\Gadget = gadget
EndProcedure
MouseMoveCursor = LoadCursor_(0,#IDC_SIZEALL)
OpenWindow(0,150,150,500,500,#PB_Window_SystemMenu|#PB_Window_Invisible|#PB_Window_SizeGadget,"move button")
CreateGadgetList(WindowID())
CheckBoxGadget(0,10,5,100,15,"Move Mode")
ButtonGadget(1, 10,25,100,30,"Button 1")
ButtonGadget(2,120,25,100,30,"Button 2")
ListViewGadget(3,10,65,100,150)
For a = 1 To 10 : AddGadgetItem(3,-1,"ListView Item "+Str(a)) : Next a
ComboBoxGadget(4,120,65,100,200)
For a = 1 To 10 : AddGadgetItem(4,-1,"ComboBox Item "+Str(a)) : Next a
StringGadget(5,120,95,100,20,"StringGadget")
ExplorerTreeGadget(6,10,225,210,200,"c:")
ProgressBarGadget(7,120,130,100,20,0,100)
SetGadgetState(7,30)
TrackBarGadget(8,120,165,100,20,0,100)
SpinGadget(9,120,195,100,20,0,100)
SetGadgetText(9,"SpinGadget")
For a = 1 To 9 ; Add MoveCallback to all gadgets (except gadget 0)
SetMoveCallback(a)
Next a
HideWindow(0,0)
Repeat
Select WaitWindowEvent()
Case #PB_EVENT_CLOSEWINDOW
Break
Case #PB_EventGadget
Select EventGadgetID()
Case 0 ; Move Mode
MoveMode = GetGadgetState(0)
EndSelect
EndSelect
ForEver
You have to *understand* the main thing here:
how to handle mouse events (WM_MOUSEMOVE,WM_LBUTTONDOWN/UP,...)
with WinAPI in a callback.
If you understood how it works, why it works and what this messages
do... you can code such things and much more yourself.
And finally an old example of moving an image gadget with the mousecursor:
Code: Select all
;
; by Danilo, 23.10.2003 - german forum
;
#IMAGE = 1
Procedure WindowProc(hWnd,Msg,wParam,lParam)
Shared WindowProc_ImageInMove
Select Msg
Case #WM_LBUTTONDOWN
WindowProc_ImageInMove = 1
Case #WM_LBUTTONUP
WindowProc_ImageInMove = 0
Case #WM_MOUSEMOVE
If ChildWindowFromPoint_(hWnd,lParam & $FFFF,(lParam>>16) & $FFFF) = GadgetID(#IMAGE) And wParam&#MK_LBUTTON And WindowProc_ImageInMove
ResizeGadget(#IMAGE,(lParam & $FFFF)-GadgetWidth(#IMAGE)/2,((lParam>>16)&$FFFF)-GadgetHeight(#IMAGE)/2,-1,-1)
UpdateWindow_(hWnd) ; Win9x fix
Else
WindowProc_ImageInMove = 0
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"image")
SetWindowCallback(@WindowProc())
CreateGadgetList(WindowID())
If CreateImage(#IMAGE,100,100)=0
MessageRequester("ERROR","Cant create image",#MB_ICONERROR)
End
EndIf
StartDrawing(ImageOutput())
f.f = $FF / ImageHeight()
For a = 0 To ImageHeight()
Line(0,a,ImageWidth(),0,RGB($FF,f*a,$00))
Next a
StopDrawing()
ImageGadget(#IMAGE,0,0,0,0,UseImage(#IMAGE))
HideWindow(0,0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
EndSelect
ForEverHi,
In the code of above (From Danilo)
if I change the line ComboBoxGadget(4,120,65,100,200) to ComboBoxGadget(4,120,65,100,200,#PB_ComboBox_Editable), I can't drag (move) this gadget.
Can someone help me? Thank you
In the code of above (From Danilo)
Code: Select all
;
; simple gadget mover example
;
; by Danilo, 10.06.2004 - english forum
; (coded for lazy localmotion34)
;
Structure MouseBtnMover
WndProc.l
hGadget.l
Gadget.l
EndStructure
NewList oldCallbacks.MouseBtnMover()
.
.
.Can someone help me? Thank you
PB 6.21 beta, PureVision User

