Moving GDI+ objects question
-
How can i move gdi+ objects drawn on window with a mouse? Such objects like: elipse, rectangle. For example, i have an elipse, created with
DrawEllipse()
, then it filled withGraphicsPath
which contains some background color. So for example i have painted a "blue ball" on main application window. Now i am trying to figure out, how can i move this ball within window area with a mouse. I can think of such scenario: 1. OnWM_LBUTTONDOWN
i am checking if mouse pointer is inside the ball and setting flag to true, if it is 2. And now onWM_MOUSEMOVE
, if flag is sat to true, what should i do next? Should i for example, erase this ball and paint it in new position regarding mouse pointer? Or there is a method somewhere to, like, "grab" this ball and literally move it to new position? I'm just learning GDI+ so this question may look lame, however... Thanks011011010110000101100011011010000110100101101110 0110010101110011
-
How can i move gdi+ objects drawn on window with a mouse? Such objects like: elipse, rectangle. For example, i have an elipse, created with
DrawEllipse()
, then it filled withGraphicsPath
which contains some background color. So for example i have painted a "blue ball" on main application window. Now i am trying to figure out, how can i move this ball within window area with a mouse. I can think of such scenario: 1. OnWM_LBUTTONDOWN
i am checking if mouse pointer is inside the ball and setting flag to true, if it is 2. And now onWM_MOUSEMOVE
, if flag is sat to true, what should i do next? Should i for example, erase this ball and paint it in new position regarding mouse pointer? Or there is a method somewhere to, like, "grab" this ball and literally move it to new position? I'm just learning GDI+ so this question may look lame, however... Thanks011011010110000101100011011010000110100101101110 0110010101110011
1. Store your object in vector form, so you can repaint them whenever needed. 2. On left button down, you do hit-testing to figure out which object is selected if any. 3. On mouse move, adjust the coordinates in your vector data, and repaint the screen using double buffering to avoid flicker.
-
How can i move gdi+ objects drawn on window with a mouse? Such objects like: elipse, rectangle. For example, i have an elipse, created with
DrawEllipse()
, then it filled withGraphicsPath
which contains some background color. So for example i have painted a "blue ball" on main application window. Now i am trying to figure out, how can i move this ball within window area with a mouse. I can think of such scenario: 1. OnWM_LBUTTONDOWN
i am checking if mouse pointer is inside the ball and setting flag to true, if it is 2. And now onWM_MOUSEMOVE
, if flag is sat to true, what should i do next? Should i for example, erase this ball and paint it in new position regarding mouse pointer? Or there is a method somewhere to, like, "grab" this ball and literally move it to new position? I'm just learning GDI+ so this question may look lame, however... Thanks011011010110000101100011011010000110100101101110 0110010101110011
The general solution is to just invalidate the window[^] or better yet, the old ball rectangle and the new ball rectangle and then draw it again in the WM_PAINT which is called automatically when you invalidate the area. 1 minor issue with this is that it will do what is called "flickering" where it flashes. To fix this mute the WM_ERASEBKGND message and use a memory DC. Search codeproject or google for "memory DC" or "flicker free drawing" to see how this is done in code.
-
The general solution is to just invalidate the window[^] or better yet, the old ball rectangle and the new ball rectangle and then draw it again in the WM_PAINT which is called automatically when you invalidate the area. 1 minor issue with this is that it will do what is called "flickering" where it flashes. To fix this mute the WM_ERASEBKGND message and use a memory DC. Search codeproject or google for "memory DC" or "flicker free drawing" to see how this is done in code.
Thanks guys :) Looks like invalidating / redrawing window is the only way. This "ball" is actually a part of custom control i am writing (has its own window) - it is already double buffered.
case WM_PAINT: // custom control window paint handler
{
// some checks for need of repainting
Gdiplus::Graphics graphics(hdc);
Gdiplus::Bitmap *bmp = new Gdiplus::Bitmap(CtrlRect.right, CtrlRect.bottom);
Gdiplus::Graphics *temp = Gdiplus::Graphics::FromImage(bmp);
temp->SetSmoothingMode(Gdiplus::SmoothingMode::SmoothingModeAntiAlias);
// .. drawing goes here
// .. paint "ball" with new mouse coords
Gdiplus::CachedBitmap *cbmp = new Gdiplus::CachedBitmap(bmp, &graphics);
delete bmp;
delete temp;
graphics.DrawCachedBitmap(cbmp, 0, 0);
// done
}Just thought it could be done a way smoother - without redrawing. Anyway, thanks :)
011011010110000101100011011010000110100101101110 0110010101110011
-
Thanks guys :) Looks like invalidating / redrawing window is the only way. This "ball" is actually a part of custom control i am writing (has its own window) - it is already double buffered.
case WM_PAINT: // custom control window paint handler
{
// some checks for need of repainting
Gdiplus::Graphics graphics(hdc);
Gdiplus::Bitmap *bmp = new Gdiplus::Bitmap(CtrlRect.right, CtrlRect.bottom);
Gdiplus::Graphics *temp = Gdiplus::Graphics::FromImage(bmp);
temp->SetSmoothingMode(Gdiplus::SmoothingMode::SmoothingModeAntiAlias);
// .. drawing goes here
// .. paint "ball" with new mouse coords
Gdiplus::CachedBitmap *cbmp = new Gdiplus::CachedBitmap(bmp, &graphics);
delete bmp;
delete temp;
graphics.DrawCachedBitmap(cbmp, 0, 0);
// done
}Just thought it could be done a way smoother - without redrawing. Anyway, thanks :)
011011010110000101100011011010000110100101101110 0110010101110011
Well, I know that scrollbars work by moving the screen data, rather than redrawing, in things like ListBox's and web browser controls. Presumably this behaviour could be implemented into your solution too, but for something so simple, it would not be worth the complexity that I imagine it might take.
-
Well, I know that scrollbars work by moving the screen data, rather than redrawing, in things like ListBox's and web browser controls. Presumably this behaviour could be implemented into your solution too, but for something so simple, it would not be worth the complexity that I imagine it might take.
-
1. Store your object in vector form, so you can repaint them whenever needed. 2. On left button down, you do hit-testing to figure out which object is selected if any. 3. On mouse move, adjust the coordinates in your vector data, and repaint the screen using double buffering to avoid flicker.
-
Storing things in vector sounds interesting - never thought about such approach, thanks :)
011011010110000101100011011010000110100101101110 0110010101110011
-
I was talking about a vector representation of the graphics, not about storing them in a vector type container, although that could also perform well. Just to avoid misinterpretations.