draw and select object
-
hi i need help about drawing shape and object with gdi+ and then select each object by mouse and can change some properties ? thx
What part of the process do you need help with? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
What part of the process do you need help with? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
how can i select a drawn object when mouse click on it? for example i draw a circle and then a rectangel. now i want to click on circle to select it and move it by mouse .
It's up to you to keep track of where you draw the objects. With that saved info, you can perform "hit-testing", where you take the cursor position and determine which drawn object the cursor is on. To drag an object, the typical method is (in pseudocode): On WM_LBUTTONDOWN if mousecursor on an object (hit-test) capture mouse (SetCapture()) save base cursor position On WM_MOUSEMOVE if mouse captured if cursor position different than base cursor position erase object at current its location draw object at its new location (use delta from base cursor position) set base cursor position to the current cursor position On WM_LBUTTONUP if mouse captured release mouse capture (ReleaseCapture()) MArk
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
It's up to you to keep track of where you draw the objects. With that saved info, you can perform "hit-testing", where you take the cursor position and determine which drawn object the cursor is on. To drag an object, the typical method is (in pseudocode): On WM_LBUTTONDOWN if mousecursor on an object (hit-test) capture mouse (SetCapture()) save base cursor position On WM_MOUSEMOVE if mouse captured if cursor position different than base cursor position erase object at current its location draw object at its new location (use delta from base cursor position) set base cursor position to the current cursor position On WM_LBUTTONUP if mouse captured release mouse capture (ReleaseCapture()) MArk
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
It's up to you to keep track of where you draw the objects. With that saved info, you can perform "hit-testing", where you take the cursor position and determine which drawn object the cursor is on. To drag an object, the typical method is (in pseudocode): On WM_LBUTTONDOWN if mousecursor on an object (hit-test) capture mouse (SetCapture()) save base cursor position On WM_MOUSEMOVE if mouse captured if cursor position different than base cursor position erase object at current its location draw object at its new location (use delta from base cursor position) set base cursor position to the current cursor position On WM_LBUTTONUP if mouse captured release mouse capture (ReleaseCapture()) MArk
Mark Salsbery Microsoft MVP - Visual C++ :java:
Mark Salsbery wrote:
To drag an object, the typical method is (in pseudocode): On WM_LBUTTONDOWN if mousecursor on an object (hit-test) capture mouse (SetCapture()) save base cursor position On WM_MOUSEMOVE if mouse captured if cursor position different than base cursor position erase object at current its location draw object at its new location (use delta from base cursor position) set base cursor position to the current cursor position On WM_LBUTTONUP if mouse captured release mouse capture (ReleaseCapture())
You only need SetCapture() to detect the mouse outside the client area of the application. You don't want to erase the entire object with each mouse move detection - only the part that's actually moved. If the mouse moves one pixel most of the object hasn't moved at all. If you erase the entire object each time there will be screen flashes. Well, maybe that's what you meant by "use delta from base cursor position". Nevermind.
-
Mark Salsbery wrote:
To drag an object, the typical method is (in pseudocode): On WM_LBUTTONDOWN if mousecursor on an object (hit-test) capture mouse (SetCapture()) save base cursor position On WM_MOUSEMOVE if mouse captured if cursor position different than base cursor position erase object at current its location draw object at its new location (use delta from base cursor position) set base cursor position to the current cursor position On WM_LBUTTONUP if mouse captured release mouse capture (ReleaseCapture())
You only need SetCapture() to detect the mouse outside the client area of the application. You don't want to erase the entire object with each mouse move detection - only the part that's actually moved. If the mouse moves one pixel most of the object hasn't moved at all. If you erase the entire object each time there will be screen flashes. Well, maybe that's what you meant by "use delta from base cursor position". Nevermind.
Heh thanks :) I'm trying to give him the basics without writing the whole thing. I know the drawing issue is going to come up soon :) Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
You need some way to decide if the cursor is on an object. The simplest way is to use the bounding rectangle. The problem with this is hollow, overlapped objects. You can use the PtInRect() API to test for a rectangle. A little more complicated is to use regions. You can use the PtInRegion() API to test for a rectangle. You can make it as complicated as it needs to be. There's lots of articles about hit testing. Here's one example: Win32: Hit Testing Lines and Curves[^] Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
hi i need help about drawing shape and object with gdi+ and then select each object by mouse and can change some properties ? thx
here is another approach the first thing you need to do is make a stack which supports all the graphics you are using: MyGraphicsStack; MyGraphicsStack.add( line, rect, color, ... ); <- user draws a line MyGraphicsStack.add( circle, rect, color, ..., fill ); <- user draws .. . . (or better, make objects and inherit from the same base class) Now when the user clicks, you create a white temporary bitmap with the same dimensions as the user is drawing on. the next thing is drawing your stack ( in the correct order ) on this temporary bitmap. For each item you are drawing, ignore the color in the GraphicsStack but use instead: (COLORREF)index_Of_Current_Object_In_MyStack. (index casting to a color) for filled objects: use this color for the fill/and the border color. Then transform your mouse coordinates where the user clicked, to bitmap coordinates. And for this coordination obtain the bitmap pixel color. When you cast the pixel color back it will be the index of the object kept in your stack, ( or white in case user pressed the bitmap ) UINT nInd = (COLORREF)getpixel(..) if ( nInd < MyGraphicsStack.Size( ) ) { MyGraphicsStack[ nInd ] //<-- here it is } in this way you have always the topmost object even when objects are drawn over each other. You also distinct objects which are filled or not. ( depending on the bit depth of the bitmap you are creating you are limited in the number of items you can draw, in that case you could work with more bitmaps, for a normal 24 bits bitmap you can keep 16777216 - 1 objects 1 = bitmap itself ) remark: Because Gdi+ plus can ignore drawing objects you are drawing outside the region of the dc, you can also create a small bitmap (I think 16x16 is the minimum?) and when drawing to this bitmap correct for the offset ( the bitmap coordinates the user selected ) in this way that the centre pixel of your small bitmap is the pixel you are interested in. well have fun!