Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Windows Development
  4. GDI drawing

GDI drawing

Scheduled Pinned Locked Moved Windows Development
graphicsquestiontutorial
5 Posts 2 Posters 35 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    David Crow
    wrote on last edited by
    #1

    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

    L 1 Reply Last reply
    0
    • D David Crow

      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

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      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.

      D 1 Reply Last reply
      0
      • L Lost User

        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.

        D Offline
        D Offline
        David Crow
        wrote on last edited by
        #3

        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

        L 2 Replies Last reply
        0
        • D David Crow

          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

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Sixty years ago my brain might have been able to handle that. :laugh:

          1 Reply Last reply
          0
          • D David Crow

            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

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            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);

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups