1

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?

Wais Kamal
  • 5,858
  • 2
  • 17
  • 36
  • 1
    `wWinMain` should be `WinMain` – drescherjm Dec 08 '18 at 16:51
  • Do you really want to name your executable `-window.exe` ? – drescherjm Dec 08 '18 at 16:53
  • Possibly relevant: https://stackoverflow.com/questions/1792275/difference-between-winmain-and-wwinmain –  Dec 08 '18 at 16:59
  • @drescherjm [`wWinMain`](https://learn.microsoft.com/en-us/windows/desktop/learnwin32/winmain--the-application-entry-point) is correct for Unicode programs. – zett42 Dec 08 '18 at 17:12
  • The error is `undefined reference to 'WinMain'` however. – drescherjm Dec 08 '18 at 17:18
  • i think that you need define `-municode` command switch. must be not `lib64_libmingw32_a-crt0_c.o` but `lib64_libmingw32_a-crt0_w.o` lib referenced. for example - https://sourceforge.net/p/mingw-w64/mailman/message/25651370/ – RbMm Dec 08 '18 at 21:34
  • [*you should use the `-municode` option*](https://stackoverflow.com/a/11706847/6401656) – RbMm Dec 08 '18 at 21:49
  • 3
    Is there a reason not to use Visual Studio? Windows programming not only needs compiling, but also debugging, profiling, [...] – Michael Chourdakis Dec 08 '18 at 23:13
  • Possible duplicate of [wWinmain, Unicode, and Mingw](https://stackoverflow.com/q/3571250/608639). Also see the related question [undefined reference to `WinMain@16'](https://stackoverflow.com/q/5259714/608639). – jww Dec 09 '18 at 04:19
  • Regarding Michael's comment and the Microsoft compiler, you can get the toolchain *without* Visual Studio. Also see [download microsoft build tools](https://www.google.com/search?q=download+microsoft+build+tools). – jww Dec 09 '18 at 04:48
  • @drescherjm no, that's a typo. Sorry for that. – Wais Kamal Dec 09 '18 at 07:56

2 Answers2

7

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.
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • i think that this is not visual studio specific - for [example](https://sourceforge.net/p/mingw-w64/mailman/message/25651370/) - possible **-municode** switch need use. anyway support for [`wWinMain`](https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/crt0_w.c) exist in mingw too – RbMm Dec 08 '18 at 21:37
  • @RbMm you are right. I didn't know MinGW-64 has that option. – Barmak Shemirani Dec 08 '18 at 23:24
  • how i understand latest builds must have this - https://stackoverflow.com/questions/3571250/wwinmain-unicode-and-mingw/11706847#11706847 – RbMm Dec 08 '18 at 23:29
0

The main function needs to be called WinMain. You have a function called wWinMain. I assume that is a typo, either by you or in the example code.

Incidentally, the error is from the linker, not the compiler. It's saying you don't have WinMain defined anywhere.

Edited to add: I was mostly wrong (thanks for the other contributors for setting me right). The linker was in this case looking for WinMain rather than wWinMain. I assume to be correct the advice given on how to change this; I'm not familiar enough with the particular toolchain to comment.

  • 2
    [`wWinMain`](https://learn.microsoft.com/en-us/windows/desktop/learnwin32/winmain--the-application-entry-point) is correct for Unicode programs. – zett42 Dec 08 '18 at 17:13
  • this is not typo - https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/crt0_w.c#L10 based on [`WPRFLAG`](https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/crtexe.c#L325) called [`wmain`](https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/crt0_w.c#L16) or [`main`](https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/crt0_c.c#L14) – RbMm Dec 08 '18 at 21:26