Painting on an imagegadget with the mouse using Plot()
Painting on an imagegadget with the mouse using Plot()
Im trying to paint on an imagegadget (by painting to the image) using the plot command with the mouse. My problem is that even if I put this command in the Callback, or the eventloop of my program when I move the mouse too quickly it misses bits. This suggests to me that the program is not picking up the mouse moving as fast as it is, how can I do this?
The basic function is if LeftMouseDown them a variable is set to true, if that is true it draws.. Then if LeftMouseUp its set to false again.
Any ideas?
The basic function is if LeftMouseDown them a variable is set to true, if that is true it draws.. Then if LeftMouseUp its set to false again.
Any ideas?
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
You may try this:
[edit]
Some important information:
- You need to call SetCapture_() in order to still recieve the #WM_MOUSEMOVE message when moving the mouse out of the client area respectivley if it gets negative.
- You may wounder why SetCapture_() is called constantly instead just once for #WM_LBUTTONDOWN. I tested this, it doesn't work. It needs to be called constantly while moving the mouse.
- Only the Y-Coordinate recieved from #WM_MOUSEMOVE can get negative, not X-Coordinate. If it gets smaller then NULL it becomes a value of $FFFF. So I use GetCursorPos_() / ScreenToClient_() to avoid this.
Code: Select all
Global lpPrevFunc
Procedure StaticProc(hWnd,uMsg,wParam,lParam)
Static MTX,MTY
Select uMsg
Case #WM_LBUTTONDOWN
MX = lParam & $FFFF : MY = lParam >> 16
MTX = MX : MTY = MY
StartDrawing(ImageOutput(0))
Plot(MX,MY,#White)
StopDrawing()
Case #WM_MOUSEMOVE
If wParam & #MK_LBUTTON
GetCursorPos_(cpt.POINT)
ScreenToClient_(hWnd,cpt)
MX = cpt\x : MY = cpt\y
StartDrawing(ImageOutput(0))
LineXY(MTX,MTY,MX,MY,#White)
StopDrawing()
MTX = MX : MTY = MY
SetGadgetState(0,ImageID(0))
SetCapture_(hWnd)
EndIf
Case #WM_LBUTTONUP
ReleaseCapture_()
EndSelect
ProcedureReturn CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
EndProcedure
CreateImage(0,300,220)
StartDrawing(ImageOutput(0))
Box(0,0,310,230,#Gray)
StopDrawing()
OpenWindow(0,0,0,320,240,"PurePaint",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ImageGadget(0,10,10,0,0,ImageID(0),0)
lpPrevFunc = SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@StaticProc())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Some important information:
- You need to call SetCapture_() in order to still recieve the #WM_MOUSEMOVE message when moving the mouse out of the client area respectivley if it gets negative.
- You may wounder why SetCapture_() is called constantly instead just once for #WM_LBUTTONDOWN. I tested this, it doesn't work. It needs to be called constantly while moving the mouse.
- Only the Y-Coordinate recieved from #WM_MOUSEMOVE can get negative, not X-Coordinate. If it gets smaller then NULL it becomes a value of $FFFF. So I use GetCursorPos_() / ScreenToClient_() to avoid this.
Last edited by Fluid Byte on Fri Apr 11, 2008 6:54 pm, edited 1 time in total.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
Oops!
Sorry mate, just replace WindowEvent() with WaitWindowEvent().

Sorry mate, just replace WindowEvent() with WaitWindowEvent().

Last edited by Fluid Byte on Tue Apr 21, 2009 12:07 am, edited 1 time in total.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
It is because of your blanket call to 'CallWindowProc_()' etc. You should really capture the mouse once only in this kind of situation :Fluid Byte wrote:- You may wounder why SetCapture_() is called constantly instead just once for #WM_LBUTTONDOWN. I tested this, it doesn't work. It needs to be called constantly while moving the mouse.
Code: Select all
Global lpPrevFunc
Procedure StaticProc(hWnd,uMsg,wParam,lParam)
Static MTX,MTY
Select uMsg
Case #WM_LBUTTONDOWN
MX = lParam & $FFFF : MY = lParam >> 16
MTX = MX : MTY = MY
StartDrawing(ImageOutput(0))
Plot(MX,MY,#White)
StopDrawing()
result = CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
SetCapture_(hWnd)
Case #WM_MOUSEMOVE
If wParam & #MK_LBUTTON
GetCursorPos_(cpt.POINT)
ScreenToClient_(hWnd,cpt)
MX = cpt\x : MY = cpt\y
StartDrawing(ImageOutput(0))
LineXY(MTX,MTY,MX,MY,#White)
StopDrawing()
MTX = MX : MTY = MY
SetGadgetState(0,ImageID(0))
Else
result = CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
EndIf
Case #WM_LBUTTONUP
ReleaseCapture_()
result = CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
Default
result = CallWindowProc_(lpPrevFunc,hWnd,uMsg,wParam,lParam)
EndSelect
ProcedureReturn result
EndProcedure
CreateImage(0,300,220)
StartDrawing(ImageOutput(0))
Box(0,0,310,230,#Gray)
StopDrawing()
OpenWindow(0,0,0,320,240,"PurePaint",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ImageGadget(0,10,10,0,0,ImageID(0),0)
lpPrevFunc = SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@StaticProc())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
I may look like a mule, but I'm not a complete ass.
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
Yeah, I always forget to return from procedure. Had a similar issue a while ago where an OD ListView gadget still was showing the focus rect because I didn't returned from the #WM_DRAWITEM message. Keept me busy for at least for two hours.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?