title: win32 C++ put an image on the screen
body: <p>i am learning C++ but i am having problems with putting an image on the screen.</p>
  
  <p>i have searched the internet for help but i couldn't find any.</p>
  
  <p>i am trying to create a window and put a simple color in the client area when the WM_Paint message is called, but the program just displays a grey screen as usual. i am using code::blocks 10.05.</p>
  
  <pre><code>    #include &lt;windows.h&gt;
  #include &lt;iostream&gt;
  
  using namespace std;
  
  int winx = 500;
  int winy = 500;
  int winbpp = 24;
  
  
       static  char                    m_bibuf[ sizeof(BITMAPINFOHEADER) + 12 ];
       static  BITMAPINFO              &amp;m_bi = *(BITMAPINFO*)&amp;m_bibuf;
       static  BITMAPINFOHEADER        &amp;m_bih = m_bi.bmiHeader;
       int* buffer = new int[winx*winy*winbpp];
  
  
  
  
  
   int setbuffer()
   {
  
    for(int x = 0; x &lt; winx; x++)
                  {
                      for(int y=0; y &lt; winy; y++)
                      {
                              for(int z =0; z &lt; winbpp; z++)
                              {
                                  buffer[x*y*z] = 1;
                              }
                      }
  
                  }
  
                  return 0;
  
   }
  
  
  
  /*  Declare Windows procedure  */
  LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  
  /*  Make the class name into a global variable  */
  char szClassName[ ] = "CodeBlocksWindowsApp";
  
  int WINAPI WinMain (HINSTANCE hThisInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpszArgument,
                       int nCmdShow)
  {
      HWND hwnd;               /* This is the handle for our window */
      MSG messages;            /* Here messages to the application are saved */
      WNDCLASSEX wincl;        /* Data structure for the windowclass */
  
      /* The Window structure */
      wincl.hInstance = hThisInstance;
      wincl.lpszClassName = szClassName;
      wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
      wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
      wincl.cbSize = sizeof (WNDCLASSEX);
  
      /* Use default icon and mouse-pointer */
      wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
      wincl.lpszMenuName = NULL;                 /* No menu */
      wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
      wincl.cbWndExtra = 0;                      /* structure or the window instance */
      /* Use Windows's default colour as the background of the window */
      wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  
      /* Register the window class, and if it fails quit the program */
      if (!RegisterClassEx (&amp;wincl))
          return 0;
  
      /* The class is registered, let's create the program*/
      hwnd = CreateWindowEx (
             0,                   /* Extended possibilites for variation */
             szClassName,         /* Classname */
             " project 1 ",       /* Title Text */
             WS_OVERLAPPEDWINDOW, /* default window */
             CW_USEDEFAULT,       /* Windows decides the position */
             CW_USEDEFAULT,       /* where the window ends up on the screen */
             winx,                 /* The programs width */
             winy,                 /* and height in pixels */
             HWND_DESKTOP,        /* The window is a child-window to desktop */
             NULL,                /* No menu */
             hThisInstance,       /* Program Instance handler */
             NULL                 /* No Window Creation data */
             );
  
      /* Make the window visible on the screen */
      ShowWindow (hwnd, nCmdShow);
  
      /* Run the message loop. It will run until GetMessage() returns 0 */
      while (GetMessage (&amp;messages, NULL, 0, 0))
      {
          /* Translate virtual-key messages into character messages */
          TranslateMessage(&amp;messages);
          /* Send message to WindowProcedure */
          DispatchMessage(&amp;messages);
      }
  
      /* The program return-value is 0 - The value that PostQuitMessage() gave */
      return messages.wParam;
  }
  
  
  /*  This function is called by the Windows function DispatchMessage()  */
  
  LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
      switch (message)                  /* handle the messages */
      {
  
          case WM_CREATE:
          {
  
  
          m_bih.biWidth = winx;
          m_bih.biHeight = winy;
          m_bih.biBitCount = winbpp;
          m_bih.biSize = sizeof(m_bih);
          m_bih.biPlanes = 1;                     // DIBs are upside down
          m_bih.biCompression = BI_BITFIELDS;
          m_bih.biSizeImage = 0;
          m_bih.biXPelsPerMeter = 0;
          m_bih.biYPelsPerMeter = 0;
          m_bih.biClrUsed = 0;
          m_bih.biClrImportant = 0;
  
          setbuffer();
  
          InvalidateRect(hwnd, NULL, TRUE);
  
          } break;
  
          case WM_PAINT:
  
          {
  
  
            PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hwnd, &amp;ps);
  
            RECT client;
  
            GetClientRect(hwnd, &amp;client);
  
  
  
          StretchDIBits           (      hDC,
                                   0,                 // Destination top left hand
                                                      // corner X Position
                                   0,                 // Destination top left hand
                                                      // corner Y Position
                                   client.right,      // Destinations width
                                   client.bottom,     // Destinations height
                                   0,                 // Source top left hand
                                                      // corner's X Position
                                   0,                 // Source top left hand
                                                      // corner's Y Position
                                   winx,              // Sources width
                                   winy,               // Sources height
                                   buffer,            // Source's data
                                   &amp;m_bi,             // Bitmap Info
                                   DIB_RGB_COLORS,    // operations
                                   SRCCOPY);
  
  
            EndPaint(hwnd, &amp;ps);
  
          } break;
  
  
  
          case WM_DESTROY:
  
              delete buffer;
              PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
              break;
          default:                      /* for messages that we don't deal with */
              return DefWindowProc (hwnd, message, wParam, lParam);
      }
  
      return 0;
  }
  </code></pre>
  
  <p>the program compiles normally, but instead of displaying the contents of 'buffer' in the client area, 
  it just displays the grey color like usual.</p>
  
  <p>is 'buffer' formatted correctly?</p>
  
  <p>=updated code below=</p>
  
  <pre><code>#include &lt;windows.h&gt;
  
  int winx = 500;
  int winy = 400;
  
  int bpp = 24;
  size_t pwidth;
  
  
  int scanlinewidth = 0;
  int numscanlines = 0;
  
  bool setscanline = 1;
  bool setbitmap = 1;
  
  BITMAPINFO m_bi;
  struct BGR{ char blue; char green; char red;};
  
  BGR* buffer;
  
  
  
  void setframebuffer()
  {
      m_bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  
      m_bi.bmiHeader.biPlanes = 1;
      m_bi.bmiHeader.biBitCount = bpp;
      m_bi.bmiHeader.biCompression = BI_RGB;
      m_bi.bmiHeader.biSizeImage = 0;
      m_bi.bmiHeader.biXPelsPerMeter = 100;
      m_bi.bmiHeader.biYPelsPerMeter = 100;
      m_bi.bmiHeader.biClrUsed = 0;
      m_bi.bmiHeader.biClrImportant = 0;
  
      if (setbitmap)
      {
      m_bi.bmiHeader.biWidth = scanlinewidth;
      m_bi.bmiHeader.biHeight = numscanlines;
      setbitmap = 0;
  
  
      }
  
  
  
      if (!setbitmap)
      {
      pwidth = (scanlinewidth * 3 + 3) &amp; ~3;
      buffer = new BGR[(scanlinewidth + pwidth)*numscanlines];
  
      }
  
  
  
      for (int i = 0; i &lt; ((scanlinewidth + pwidth) * numscanlines); i++)
      {
          buffer[i].blue = 0;
          buffer[i].green = 0;
          buffer[i].red = 255;
  
      }
  
  
  }
  
  
  
  
  /*  Declare Windows procedure  */
  LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  
  /*  Make the class name into a global variable  */
  char szClassName[ ] = "CodeBlocksWindowsApp";
  
  int WINAPI WinMain (HINSTANCE hThisInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpszArgument,
                       int nCmdShow)
  {
      HWND hwnd;               /* This is the handle for our window */
      MSG messages;            /* Here messages to the application are saved */
      WNDCLASSEX wincl;        /* Data structure for the windowclass */
  
      /* The Window structure */
      wincl.hInstance = hThisInstance;
      wincl.lpszClassName = szClassName;
      wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
      wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
      wincl.cbSize = sizeof (WNDCLASSEX);
  
      /* Use default icon and mouse-pointer */
      wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
      wincl.lpszMenuName = NULL;                 /* No menu */
      wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
      wincl.cbWndExtra = 0;                      /* structure or the window instance */
      /* Use Windows's default colour as the background of the window */
      wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  
      /* Register the window class, and if it fails quit the program */
      if (!RegisterClassEx (&amp;wincl))
          return 0;
  
      /* The class is registered, let's create the program*/
      hwnd = CreateWindowEx (
             0,                   /* Extended possibilites for variation */
             szClassName,         /* Classname */
             "framebuffer project for win32",       /* Title Text */
             WS_OVERLAPPEDWINDOW, /* default window */
             CW_USEDEFAULT,       /* Windows decides the position */
             CW_USEDEFAULT,       /* where the window ends up on the screen */
             winx,                 /* The programs width */
             winy,                 /* and height in pixels */
             HWND_DESKTOP,        /* The window is a child-window to desktop */
             NULL,                /* No menu */
             hThisInstance,       /* Program Instance handler */
             NULL                 /* No Window Creation data */
             );
  
      /* Make the window visible on the screen */
      ShowWindow (hwnd, nCmdShow);
  
      /* Run the message loop. It will run until GetMessage() returns 0 */
      while (GetMessage (&amp;messages, NULL, 0, 0))
      {
          /* Translate virtual-key messages into character messages */
          TranslateMessage(&amp;messages);
          /* Send message to WindowProcedure */
          DispatchMessage(&amp;messages);
      }
  
      /* The program return-value is 0 - The value that PostQuitMessage() gave */
      return messages.wParam;
  }
  
  
  /*  This function is called by the Windows function DispatchMessage()  */
  
  LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
      DWORD result;
  
      switch (message)                  /* handle the messages */
      {
          case WM_CREATE:
          {
  
  
          InvalidateRect(hwnd,0,0);
  
          }break;
  
          case WM_PAINT:
          {
              PAINTSTRUCT ps;
              HDC hDC = BeginPaint(hwnd, &amp;ps);
              RECT client;
              GetClientRect(hwnd,&amp;client);
              if(setscanline) {
              scanlinewidth = client.right;
              numscanlines = client.bottom;
              setscanline = 0;
              }
              setframebuffer();
  
               result = StretchDIBits(hDC,
                                     0, 0,
                                     client.right, client.bottom,
                                     0, 0,
                                     scanlinewidth, numscanlines,
                                     buffer, &amp;m_bi, DIB_RGB_COLORS, SRCCOPY);
              if(result != winy)
              {
                  //Drawing failed
                  DebugBreak();
              }
              EndPaint(hwnd, &amp;ps);
  
  
  
  
          }break;
  
          case WM_KEYDOWN:{ int escpressed = GetAsyncKeyState(27); if(escpressed){PostQuitMessage(0);}}break;
  
  
          case WM_DESTROY: {
              PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
              }break;
          default:                      /* for messages that we don't deal with */
              return DefWindowProc (hwnd, message, wParam, lParam);
      }
  
      return 0;
  }
  </code></pre>
  
  <p>EDIT changed int setbuffer to setbuffer in WM_create</p>
  
  <p>EDIT #2 changed getdc to begin paint.</p>
  
  <p>EDIT #3 changed the bpp to 24 and also changed the WM_Create to set all the bitmap properties</p>
  
  <p>EDIT #4 I have found a solution thanks to your help. i didn't understand Scan Line padding before, but now i understand it perfectly. the updated code prints a solid color on the screen and you can compile it for yourself and change the color. thanks for helping me solve my problem, now i can start drawing on the screen using my own code.</p>