GDI drawing
-
In playing around with some basic GDI stuff, I had the need to draw an object in the middle of the main window and then when a button is clicked, draw that object progressively closer to some corner (in my code below, the object moves to the lower right corner, but ultimately I'd like it to move to any corner). So my question is: how to calculate those new X/Y coordinates with each button click? The initial X/Y coordinates are calculated in response to
WM_SIZE
like:case WM_SIZE:
nScreenWidth = LOWORD(lParam);
nScreenHeight = HIWORD(lParam);// the window is not being resized right now, so these two variables aren't being recalculated. nX = (nScreenWidth - nObjectWidth) / 2; nY = (nScreenHeight - nObjectHeight) / 2; break;
When the button is clicked, new X/Y coordinates are "calculated" like:
case WM_COMMAND:
if (LOWORD(wParam) == ID_BUTTON)
{
nX += 20;
nY += 10;
InvalidateRect(hWnd, NULL, TRUE);
}
break;The object is drawn in response to
WM_PAINT
like:case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);// draw object at nX, nY EndPaint(hWnd, &ps); } break;
You can count on one hand how many GDI projects I've done in the past (and have fingers left over) so I'm walking in somewhat uncharted territory for me. As a visual aide, if you envision a straight line drawn from the middle of the screen to one of its corners, each pixel of that line is on an X/Y coordinate. What would that calculation look like? Thank you. DC
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
In playing around with some basic GDI stuff, I had the need to draw an object in the middle of the main window and then when a button is clicked, draw that object progressively closer to some corner (in my code below, the object moves to the lower right corner, but ultimately I'd like it to move to any corner). So my question is: how to calculate those new X/Y coordinates with each button click? The initial X/Y coordinates are calculated in response to
WM_SIZE
like:case WM_SIZE:
nScreenWidth = LOWORD(lParam);
nScreenHeight = HIWORD(lParam);// the window is not being resized right now, so these two variables aren't being recalculated. nX = (nScreenWidth - nObjectWidth) / 2; nY = (nScreenHeight - nObjectHeight) / 2; break;
When the button is clicked, new X/Y coordinates are "calculated" like:
case WM_COMMAND:
if (LOWORD(wParam) == ID_BUTTON)
{
nX += 20;
nY += 10;
InvalidateRect(hWnd, NULL, TRUE);
}
break;The object is drawn in response to
WM_PAINT
like:case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);// draw object at nX, nY EndPaint(hWnd, &ps); } break;
You can count on one hand how many GDI projects I've done in the past (and have fingers left over) so I'm walking in somewhat uncharted territory for me. As a visual aide, if you envision a straight line drawn from the middle of the screen to one of its corners, each pixel of that line is on an X/Y coordinate. What would that calculation look like? Thank you. DC
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
David Crow wrote:
What would that calculation look like?
I don't think it is a straightforward calculation as you would need to move more pixels in the horizontal direction than the vertical (assuming landscape view). If you use GDI+ it is slightly easier as you can use float values for the points and Windows does the smoothing. But I am not 100% clear as to the actual problem. And incidentally, as far as handling messages and repainting, your code all looks correct.
-
David Crow wrote:
What would that calculation look like?
I don't think it is a straightforward calculation as you would need to move more pixels in the horizontal direction than the vertical (assuming landscape view). If you use GDI+ it is slightly easier as you can use float values for the points and Windows does the smoothing. But I am not 100% clear as to the actual problem. And incidentally, as far as handling messages and repainting, your code all looks correct.
I started reading about Bresenham's line drawing algorithm last night but haven't had time yet to put anything in place.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
I started reading about Bresenham's line drawing algorithm last night but haven't had time yet to put anything in place.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
I started reading about Bresenham's line drawing algorithm last night but haven't had time yet to put anything in place.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
Here is a very simple method of moving the box: You need to start by calculating the value of the slope ratio between horizontal and vertical size of the Window's client area. You need this as a floating point value as it will be used to calculate positions further on. Declare a static float value named
slopeRatio
, and add the following code to either the initialisation (e.g. WM_CREATE), or whenever the Window is resized (WM_SIZE).// get the slope of the client area diagonal
RECT rcClient;
GetClientRect(hWnd, &rcClient);
float horiz = (float)rcClient.right; // Horizontal width in pixels
float vert = (float)rcClient.bottom; // Vertical height in pixels
slopeRatio = horiz / vert;Then when you need to calculate the new X and Y positions of your drawing (after the button press) do the following:
// currentX and currentY are declared elsewhere
currentX += 30; // or whatever value you wish to move it
tempY = (float)currentX / slopeRatio;
currentY = (int)tempY;
InvalidateRect(hWnd, nullptr, TRUE);