Search code examples
c++winapiwindow

Simple Microsoft example of a C++ window does not compile


I've read the Microsoft page on how to create a simple window in C++. Here is the code:

#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {
  // Register the window class.
  const wchar_t CLASS_NAME[]  = L"Sample Window Class";

  WNDCLASS wc = { };

  wc.lpfnWndProc   = WindowProc;
  wc.hInstance     = hInstance;
  wc.lpszClassName = CLASS_NAME;

  RegisterClass(&wc);

  // Create the window.

  HWND hwnd = CreateWindowEx(
    0,                              // Optional window styles.
    CLASS_NAME,                     // Window class
    L"Learn to Program Windows",    // Window text
    WS_OVERLAPPEDWINDOW,            // Window style

    // Size and position
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

    NULL,       // Parent window    
    NULL,       // Menu
    hInstance,  // Instance handle
    NULL        // Additional application data
  );

  if (hwnd == NULL) {
    return 0;
  }

  ShowWindow(hwnd, nCmdShow);

  // Run the message loop.

  MSG msg = {};
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg) {
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;

    case WM_PAINT: {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);

      FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW + 1));


      EndPaint(hwnd, &ps);
    }
    return 0;
  }

  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

The above code does not compile. It is highly unlikely that Microsoft has posted broken code, so I am quite sure I've gone wrong somewhere. I copied the code into a file (window.cpp), and compiled using MinGW:

$ g++ window.cpp -o window.exe

It returns an error:

C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function 'main':
C:/crossdev/src/mingw-w64-v4-git/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to 'WinMain'
collect2.exe: error: ld returned 1 exit status

Why though? I am compiling any other C++ program in the same way. Why doesn't this one compile?


Solution

  • In MinGW-64 default settings, the compiler is looking for main or WinMain. It doesn't recognize wWinMain as an entry point.

    Add -municode option so the compiler will expect wWinMain

    g++ window.cpp -municode -o window.exe
    

    (also add -mwindows option if you don't want a console window)


    In MinGW-32, only main and WinMain are expected entry points by default. Use the following:

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
    

    Note LPSTR parameter in WinMain, it has to be LPSTR even when UNICODE is defined. Use GetCommandLineW() if you want the Unicode command line argument.


    In Visual Studio, simply use wWinMain for Unicode.