Home > OS >  How to enable unicode when compiling using cl.exe from Visual Studio Build Tools?
How to enable unicode when compiling using cl.exe from Visual Studio Build Tools?

Time:02-10

I'm trying to have unicode characters in WIN32 (winapi, no console) program compiled using cl.exe from Visual Studio Build Tools. I've defined UNICODE and _UNICODE in my program source and also using cmd option, but I still don't get unicode characters. Here is my compilation command line: cl C:\path_to_source\preventShutdown.c kernel32.lib user32.lib /DUNICODE /D_UNICODE /O2 /link /NODEFAULTLIB /ENTRY:wWinMain and my source code:

/*
cl C:\path_to_source\preventShutdown.c kernel32.lib user32.lib /DUNICODE /D_UNICODE /O2 /link /NODEFAULTLIB /ENTRY:wWinMain
*/
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd)
{
LPCTSTR windowClassName=TEXT("windowClass"),windowName=TEXT("Zatrzymaj wyłączenie");
WNDCLASS windowClass={0};
windowClass.hInstance=hInstance;
windowClass.hIcon=NULL;
windowClass.hCursor=LoadCursor(NULL,IDC_ARROW);
windowClass.hbrBackground=(HBRUSH)(COLOR_WINDOW 1);
windowClass.lpszMenuName=NULL;
windowClass.lpszClassName=windowClassName;
windowClass.lpfnWndProc=&WindowProc;
if(!RegisterClass(&windowClass))return -1;
HWND hWnd=NULL;
if(!(hWnd=CreateWindow(windowClassName,windowName,WS_OVERLAPPEDWINDOW|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,NULL,NULL)))return -2;
MSG msg={0};
int bRet=0;
while((bRet=GetMessage(&msg,NULL,0,0))!=0)
{
 if(-1==bRet)return -3;
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}
ExitProcess((UINT)msg.wParam);
return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_QUERYENDSESSION:
ShutdownBlockReasonCreate(hWnd,TEXT("Rozpoczęto przez użytkownika"));
break;
case WM_ENDSESSION:
return 0;
break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
break;
}
return 0;
}

- where path_to_source is real path to source code.

CodePudding user response:

Like @Hans Passant stated it the comment, problem was that compiler doesn't recognize my source file as unicode. Saving a file with BOM or adding /source-charset:utf-8 option makes it work correctly. I prefer the second option: cl /source-charset:utf-8 C:\path_to_source\preventShutdown.c kernel32.lib user32.lib /DUNICODE /D_UNICODE /O2 /link /NODEFAULTLIB /ENTRY:wWinMain

CodePudding user response:

If you really want to use Unicode stuff, then just use Unicode stuff directly (WCHAR strings, W-based APIs, etc). Stay away from all that TCHAR stuff based on UNICODE/_UNICODE altogether, this is not the 1990's anymore. There is no need to rely on TCHAR anymore (unless you need to support Win9x/ME).

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
    LPCWSTR windowClassName = L"windowClass", windowName = L"Zatrzymaj wyłączenie";
    WNDCLASSW windowClass = {0};
    windowClass.hInstance = hInstance;
    windowClass.hIcon = NULL;
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW 1);
    windowClass.lpszMenuName = NULL;
    windowClass.lpszClassName = windowClassName;
    windowClass.lpfnWndProc = &WindowProc;

    if (!RegisterClassW(&windowClass)) return -1;

    HWND hWnd = CreateWindowW(windowClassName, windowName, WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
    if (!hWnd) return -2;

    MSG msg = {0};
    while (GetMessageW(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_QUERYENDSESSION:
            ShutdownBlockReasonCreate(hWnd, L"Rozpoczęto przez użytkownika");
            break;
        case WM_ENDSESSION:
            break;
        default:
            return DefWindowProcW(hWnd, msg, wParam, lParam);
    }
    return 0;
}
  • Related