Reputation: 13
With a small change, the code under WM_MOUSEMOVE in the link below can draw a 10 pixel thick red ellipse by dragging the mouse. The first Ellipse function erases the previous ellipse.
https://learn.microsoft.com/en-us/windows/win32/gdi/using-filled-shapes
case WM_MOUSEMOVE:
{
if(wParam && MK_LBUTTON) {
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
HGDIOBJ obj_pen = SelectObject(hdc, CreatePen(PS_SOLID, 10, RGB(255,0,0)));
// If a previous target rectangle exists, erase it by drawing another rectangle on top.
if(!IsRectEmpty(&rcTarget)) {
Ellipse(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom);
}
if((pt.x < (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, pt.x, HIWORD(lParam), LOWORD(lParam), pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), HIWORD(lParam), pt.x, pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y < (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), pt.y, pt.x, HIWORD(lParam));
}
else {
SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam), HIWORD(lParam));
}
// Draw the new target rectangle.
Ellipse(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom);
SelectObject(hdc, obj_pen);
ReleaseDC(hwnd, hdc);
}
return 0;
}
I want to do the same operation with GDI+. Since I couldn't find the equivalent of the SetROP2 function in GDI+, I have tried the first DrawEllipse function to erase the previous ellipse using background color as pen color. But I couldn't get the result I expected:
case WM_MOUSEMOVE:
{
if(wParam && MK_LBUTTON) {
hdc = GetDC(hwnd);
Gdiplus::Graphics graphics(hdc);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
// If a previous target rectangle exists, erase it by drawing another rectangle on top.
if(!IsRectEmpty(&rcTarget)) {
Gdiplus::Pen pen(Gdiplus::Color(255, 236, 236, 236), 10); // Background color
graphics.DrawEllipse(&pen, (int) rcTarget.left, (int) rcTarget.top,
(int) rcTarget.right-(int)rcTarget.left, (int)rcTarget.bottom-(int)rcTarget.top);
}
if((pt.x < (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, pt.x, HIWORD(lParam), LOWORD(lParam), pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), HIWORD(lParam), pt.x, pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y < (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), pt.y, pt.x, HIWORD(lParam));
}
else {
SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam), HIWORD(lParam));
}
// Draw the new target rectangle.
Gdiplus::Pen pen(Gdiplus::Color(255, 255, 0, 0), 10); // Pen color
graphics.DrawEllipse(&pen, (int) rcTarget.left, (int) rcTarget.top,
(int) rcTarget.right-(int)rcTarget.left, (int)rcTarget.bottom-(int)rcTarget.top);
ReleaseDC(hwnd, hdc);
}
return 0;
}
The program image is below:
What is the best way to accomplish this operation?
@Jeaninez - MSFT @Simon Mourier
Now the code works fine for drawing a single ellipse or independent ellipses. However, when ellipses are drawn on top of each other, the ellipse area underneath is also erased. How can I solve this problem?
case WM_MOUSEMOVE:
{
if(wParam && MK_LBUTTON) {
hdc = GetDC(hwnd);
Gdiplus::Graphics graphics(hdc);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
// If a previous target rectangle exists, erase it by drawing another rectangle on top.
if(!IsRectEmpty(&rcTarget)) {
Gdiplus::Pen pen(Gdiplus::Color(255, 236, 236, 236), 12); // Background color
graphics.DrawEllipse(&pen, (int) rcTarget.left, (int) rcTarget.top,
(int) rcTarget.right-(int)rcTarget.left, (int)rcTarget.bottom-(int)rcTarget.top);
}
if((pt.x < (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, pt.x, HIWORD(lParam), LOWORD(lParam), pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), HIWORD(lParam), pt.x, pt.y);
}
else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y < (LONG) HIWORD(lParam))) {
SetRect(&rcTarget, LOWORD(lParam), pt.y, pt.x, HIWORD(lParam));
}
else {
SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam), HIWORD(lParam));
}
// Draw the new target rectangle.
Gdiplus::Pen pen2(Gdiplus::Color(255, 255, 0, 0), 10); // Pen color
graphics.DrawEllipse(&pen2, (int) rcTarget.left, (int) rcTarget.top,
(int) rcTarget.right-(int)rcTarget.left, (int)rcTarget.bottom-(int)rcTarget.top);
ReleaseDC(hwnd, hdc);
}
return 0;
}
Upvotes: 0
Views: 187
Reputation: 4040
I suggest you could try to set the width of the background color pen larger then the width of target color pen (10).
For example:
Set the width to 9:
//Pen pen(Color(255, 236, 236, 236), 10); // Background color
Pen pen(Color(255, 255, 255, 255), 9); // My background color is white
Set the width to 11:
//Pen pen(Color(255, 236, 236, 236), 10); // Background color
Pen pen(Color(255, 255, 255, 255), 11); // My background color is white
Upvotes: -2