Home > database >  C , Win32API, WinAPI Tutorial problem with wide chars
C , Win32API, WinAPI Tutorial problem with wide chars

Time:06-08

I have a type casting problem.

I mean that:

FILE *file;

Is of type char but I need it to be of type wchar_t.

How do I do that?

When I compile the program with the following line:

file = fopen(path,L"rb");

CodeBlocks throws me an error:

error: cannot convert 'char_t*' to 'const char*'

The whole code:

#include <windows.h>
#include <stdio.h>

#define OPEN_FILE_BUTTON 1

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

void AddControls(HWND);

HWND hMainWindow, hEdit;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow)
{
    WNDCLASSW wc = {0};

    wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hInstance = hInst;
    wc.lpszClassName = L"myWindowClass";
    wc.lpfnWndProc = WindowProcedure;

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

    hMainWindow = CreateWindowW(L"myWindowClass", L"My Window Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500,
                 NULL, NULL, NULL, NULL);

    MSG msg = {0};

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

    return 0;
}

void display_file(wchar_t* path)
{
    FILE *file;
    file = fopen(path,L"rb");
    fseek(file, 0, SEEK_END);
    int _size = ftell(file);
    rewind(file);
    wchar_t *data = new wchar_t(_size 2);
    fread(data, _size, 1, file);
    data[_size] = '\0';

    SetWindowText(hEdit, data);
}

void open_file(HWND hWnd)
{
    OPENFILENAMEW ofn;

    wchar_t file_name[100];

    ZeroMemory(&ofn,sizeof(OPENFILENAMEW));

    ofn.lStructSize = sizeof(OPENFILENAMEW);
    ofn.hwndOwner = hWnd;
    ofn.lpstrFile = file_name;
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = 100;
    ofn.lpstrFilter = L"All files\0*.*\0Source Files\0*.cpp\0Text Files\0*.txt\0";
    ofn.nFilterIndex = 1;

    GetOpenFileNameW(&ofn);

    void display_file(ofn.lpstrFile);
}


LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch(msg)
    {
    case WM_COMMAND:
        {
            switch(wp)
            {
            case OPEN_FILE_BUTTON:
                open_file(hWnd);
                break;
            }
        }
        break;
    case WM_CREATE:
        AddControls(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd, msg, wp, lp);
    }
}

void AddControls(HWND hWnd)
{
    CreateWindowW(L"Button", L"Open File", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 10, 10, 150, 36, hWnd, (HMENU)OPEN_FILE_BUTTON, NULL, NULL);
    hEdit = CreateWindowW(L"Edit", L"Open File", WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOVSCROLL | WS_BORDER, 10, 50, 400, 300, hWnd, NULL, NULL, NULL);
}

The code is from a Youtube tutorial:

Windows GUI Programming with C/C ( Win32 API ) | Part -8 | Open File Dialog

From "The Pentamollis Project".

https://www.youtube.com/watch?v=7K6HCeog09c&list=PLWzp0Bbyy_3i750dsUj7yq4JrPOIUR_NK&index=8

The problem is that I wanted to write the wide character version.

Thanks for helpful answers.

No thanks for unhelpful answers.

:)

CodePudding user response:

file = fopen(path,L"rb");

The wchar_t equivalent of fopen is _wfopen.

Note that you still use FILE* with _wfopen:

FILE *_wfopen(
   const wchar_t *filename,
   const wchar_t *mode
);

So, consider using the following code instead:

file = _wfopen(path, L"rb");

CodePudding user response:

So a couple of problems.

  1. Your path is a wide string so you can use the (non-standard) _wfopen instead of fopen

  2. You allocation is incorrect (in a couple of ways, see (3) as well)

    wchar_t *data = new wchar_t(_size 2);

This allocates a single character, to allocate multiple charactres you need square brackets

wchar_t *data = new wchar_t[_size 2];
  1. Wide chars (on Windows) are two bytes big, so you need to be careful with your size calculations. At the moment you are mixing characters and bytes.

    fseek(file, 0, SEEK_END); int _size = ftell(file);

This gets the size in bytes, so divide by the size of a character.

size /= sizeof(wchar_t);

Now allocate the correct number of characters (and use [])

wchar_t *data = new wchar_t[_size 1];

Now read the characters, but this

fread(data, _size, 1, file);

reads _size bytes, we want to read _size characters, so instead

fread(data, _size, sizeof(wchar_t), file);

All completely untested code.

  • Related