title: Should the main window be a global variable?
body: <p>I am trying to find a place in my code to create all of the objects that go into my window. As I see it, there are two main types of objects:</p>
  
  <ul>
  <li>the ones that require the context (<code>HDC</code>) such as rectangles, lines, and ellipses</li>
  <li>the ones that require the main window (<code>HWND</code>) such as the buttons and other objects created with the <code>CreateWindow()</code> function.</li>
  </ul>
  
  <p>The problem is that I don't know where the best place to create all these objects would be. It seems as if they need to be created in different locations, namely the context-dependent ones in <code>WM_PAINT</code> and the window-dependent ones in <code>WM_CREATE</code> or in <code>InitInstance()</code>.</p>
  
  <p>Is this correct, or should I make the window and context global variables that I can access from any function?</p>
  
  <p>Also, when I create a button, I need to keep track of its handle for when there is a <code>BN_CLICKED</code> event.</p>
  
  <pre><code>int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                       _In_opt_ HINSTANCE hPrevInstance,
                       _In_ LPWSTR    lpCmdLine,
                       _In_ int       nCmdShow)
  {
      UNREFERENCED_PARAMETER(hPrevInstance);
      UNREFERENCED_PARAMETER(lpCmdLine);
  
      // TODO: Place code here.
  
  
      // Initialize global strings
      LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
      LoadStringW(hInstance, IDC_SCHEDULERER, szWindowClass, MAX_LOADSTRING);
      MyRegisterClass(hInstance);
  
      // Perform application initialization:
      if (!InitInstance (hInstance, nCmdShow))
      {
          return false;
      }
  
      HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SCHEDULERER));
  
      MSG msg;
  
      // Main message loop:
      while (GetMessage(&amp;msg, nullptr, 0, 0))
      {
          if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg))
          {
              TranslateMessage(&amp;msg);
              DispatchMessage(&amp;msg);
          }
      }
  
      return (int) msg.wParam;
  }
  ///////////////
  //INIT INSTANCE
  ///////////////
  BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  {
     hInst = hInstance; // Store instance handle in our global variable
  
     HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
  
     if (!hWnd)
     {
        return FALSE;
     }
  
     ShowWindow(hWnd, nCmdShow);
     UpdateWindow(hWnd);
  
     return TRUE;
  }
  LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
      switch (message)
      {
      case WM_COMMAND:
          {
              int wmId = LOWORD(wParam);
              // Parse the menu selections:
              switch (wmId)
              {
              case IDM_ABOUT:
                  DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                  break;
              case IDM_EXIT:
                  DestroyWindow(hWnd);
                  break;
              case BN_CLICKED:
              {
              }
              default:
                  return DefWindowProc(hWnd, message, wParam, lParam);
              }
          }
          break;
      case WM_PAINT:
          {
              PAINTSTRUCT ps;
              HDC hdc = BeginPaint(hWnd, &amp;ps);
  
              // TODO: Add any drawing code that uses hdc here...
  
  
  
              EndPaint(hWnd, &amp;ps);
          }
          break;
      case WM_CREATE:
      {
          PushButton pb(hWnd, 100, 100, 200, 100, "Button");
          break;
      }
      case WM_DESTROY:
          PostQuitMessage(0);
          break;
      default:
          return DefWindowProc(hWnd, message, wParam, lParam);
      }
      return 0;
  }
  </code></pre>