Menu

Win32 GDI example

2004-07-30
2012-09-26
  • Edmund Tudor

    Edmund Tudor - 2004-07-30

    Since this subject has come up several times lately, I've thrown together a quick example of drawing with GDI calls.
    It's based on the Dev GUI app template, I removed all of the normal comments from it, and added the GDI code and comments, so anywhere there are comments is where the changes were made.

    It should compile as a C++ GUI app.
    I commented the whole thing to preserve the indentation for the forum (hopefully) so after you cut and past, just do a 'select all' and 'ctrl-alt-comma' to remove the first column of //'s

    Compile, run, double click on the window, it should draw a rectangle.. pretty basic, but it shows the technique of creating a 'canvas' to buffer your graphics. Once you've got that down it's easy to add various drawing commands to draw lines, circles, text, bitmaps, etc..

    Hope it's helpful.

    //#include <windows.h>
    //
    //LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    //
    //char szClassName[ ] = "WindowsApp";
    //
    //int WINAPI WinMain (HINSTANCE hThisInstance,
    //                    HINSTANCE hPrevInstance,
    //                    LPSTR lpszArgument,
    //                    int nFunsterStil)
    //{
    //  HWND hwnd;
    //  MSG messages;
    //  WNDCLASSEX wincl;
    //
    //  wincl.hInstance = hThisInstance;
    //  wincl.lpszClassName = szClassName;
    //  wincl.lpfnWndProc = WindowProcedure;
    //  wincl.style = CS_DBLCLKS;
    //  wincl.cbSize = sizeof (WNDCLASSEX);
    //
    //  wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    //  wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    //  wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    //  wincl.lpszMenuName = NULL;
    //  wincl.cbClsExtra = 0;
    //  wincl.cbWndExtra = 0;
    //  wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    //
    //  if (!RegisterClassEx (&wincl))
    //    return 0;
    //
    //  hwnd = CreateWindowEx (
    //         0,
    //         szClassName,
    //         "Double Click Me!",
    //         WS_OVERLAPPEDWINDOW,
    //         CW_USEDEFAULT,
    //         CW_USEDEFAULT,
    //         544,
    //         375,
    //         HWND_DESKTOP,
    //         NULL,
    //         hThisInstance,
    //         NULL
    //         );
    //
    //  ShowWindow (hwnd, nFunsterStil);
    //
    //  while (GetMessage (&messages, NULL, 0, 0))
    //  {
    //    TranslateMessage(&messages);
    //    DispatchMessage(&messages);
    //  }
    //  return messages.wParam;
    //}
    //
    //LRESULT CALLBACK
    //WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    //{
    //  static  HDC           memdc;    // virtual device context handle
    //  static  HBITMAP       hbit;     // virtual bitmap handle
    //
    //  switch (message)
    //  {
    //    case WM_CREATE:
    //    {
    //      /*  In WM_CREATE we set up the virtual 'canvas' that we will draw on.
    //          It will consist of a device context and bitmap that are compatible
    //          with the window dc. We will create a brush to paint the background
    //          of the 'canvas'
    //      */
    //
    //      // handle to save current brush
    //      HGDIOBJ     oldBrush;
    //
    //      // get screen coordinates
    //      int         maxX    = GetSystemMetrics(SM_CXSCREEN);
    //      int         maxY    = GetSystemMetrics(SM_CYSCREEN);
    //
    //      // get handle to window dc
    //      HDC         hdc     = GetDC(hwnd);
    //
    //      // create virtual dc and bitmap
    //      memdc   = CreateCompatibleDC(hdc);
    //      hbit    = CreateCompatibleBitmap(hdc, maxX, maxY);
    //
    //      // select bitmap into dc
    //      SelectObject(memdc, hbit);
    //
    //      // save old brush and select new brush
    //      oldBrush = SelectObject(memdc, CreateSolidBrush(RGB(255, 255, 240)));
    //
    //      // paint background with brush, delete brush and release dc
    //      PatBlt(memdc, 0, 0, maxX, maxY, PATCOPY);
    //      DeleteObject(SelectObject(memdc, oldBrush));
    //      ReleaseDC(hwnd, hdc);
    //
    //      break;
    //    }
    //
    //    case WM_PAINT:
    //    {
    //      /*  In WM_PAINT we update the screen by bitblt'ing the virtual canvas to
    //          the window.
    //      */
    //
    //      PAINTSTRUCT ps; // struct to hold screen coordinates
    //      HDC         hdc = BeginPaint(hwnd, &ps); // get window dc and coords.
    //
    //      BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, //copy memdc to hdc
    //        ps.rcPaint.right-ps.rcPaint.left,
    //        ps.rcPaint.bottom-ps.rcPaint.top,
    //        memdc,
    //        ps.rcPaint.left, ps.rcPaint.top,
    //        SRCCOPY);
    //
    //      EndPaint(hwnd, &ps); // finished paint
    //      break;
    //    }
    //
    //    case WM_LBUTTONDBLCLK:
    //    {
    //      /*  On double click left button we will save the state of memdc,
    //          create a pen and a brush, and draw a rectangle. We will call
    //          InvalidateRect to force Windows to send a WM_PAINT, redrawing
    //          our window with the updated canvas. Then we will restore the
    //          state of memdc, and delete the pen and brush we created.
    //      */
    //
    //      // save the current dc state
    //      int     oldDC     = SaveDC(memdc);
    //
    //      // create pen and brush
    //      HPEN    hpRed   = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
    //      HBRUSH  hbBlue  = CreateSolidBrush(RGB(220, 220, 255));
    //
    //      // select pen and brush into memdc
    //      SelectObject(memdc, hpRed);
    //      SelectObject(memdc, hbBlue);
    //
    //      // draw rectangle, uses hpRed pen for border, hbBlue brush for filling
    //      Rectangle(memdc, 50, 50, 400, 200);
    //
    //      // force repaint
    //      InvalidateRect(hwnd, NULL, TRUE);
    //
    //      // clean up, restore dc, delete pen and brush
    //      RestoreDC(memdc, oldDC);
    //      DeleteObject(hpRed);
    //      DeleteObject(hbBlue);
    //
    //      break;
    //    }
    //
    //    case WM_DESTROY:
    //      PostQuitMessage (0);
    //      break;
    //    default:
    //      return DefWindowProc (hwnd, message, wParam, lParam);
    //  }
    //
    //  return 0;
    //}

     
    • Edmund Tudor

      Edmund Tudor - 2004-07-30

      Ok, crap this forum sucks for posting code!!!!!!

      You'd think someone could've had a little foresight... "hmm.. we're going to host programming forums, lets use forum software that removes all formatting!!!"

      Oh well... c'est la vie

       
      • Nobody/Anonymous

        Yeah, sourceforge suppresses leading spaces.

        However, the spaces are not lost. Simply select to view your the source for the page (view -> source under internet explorer). Cut and paste the code and voila, the leading spaces are there.

        Alternatively, get a good editor that can reformat code and cut and paste into it (I use emacs).

        rr

         
    • aditsu

      aditsu - 2004-07-31

      see my post near the end of the forum FAQ thread

      Adrian

       
    • Nobody/Anonymous

      so what do you suppose would happen if we just put
      <pre>
         in our messages
             would they display right then?
      </pre>

      I shall find out in a minute....

       
      • Nobody/Anonymous

        duh.. I should have read what it says right below the message input box.. lol!!!

        So..  any opinions on the example? Does it look like a good starting place for newbies?

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.