Search code examples
c++builder

C++ Builder 10.3 can not assign to const wchar_t* from const char[18]


I have a simple code for directories handling, and here is a part of it. The problem is, that in older version of builder(I guess it is 6) it was working perfectly, now it throws [bcc32c Error] Unit1.cpp(32): assigning to 'PCZZWSTR' (aka 'const wchar_t *') from incompatible type 'const char [18]'.

void __fastcall TForm1::Button2Click(TObject *Sender)
{
SHFILEOPSTRUCT fos;
String dirDest;
fos.hwnd = Handle;
//operacja kopiowania
fos.wFunc = FO_COPY;
//plik źródłowy
fos.pFrom = "C:\\Melon\\AGA\\Bazy";
}

The problem is with line fos.pFrom = "C:\\Melon\\AGA\\Bazy";. I tried assigning "C:\\Melon\\AGA\\Bazy" to const wchar_t* using linkig, but it thrown me that it can not be linked. Does somebody have a clue how to fix it?


Solution

  • You are using the TCHAR-based version of SHFILEOPSTRUCT, so its string fields will be based on either wchar_t or char depending on whether UNICODE is defined or not, respectively.

    In C++Builder 6 (where String was an alias for AnsiString), UNICODE was not defined by default. In C++Builder 2009 onward (where String is an alias for UnicodeString), UNICODE is defined by default, but can be turned off if needed for legacy projects.

    Since you are using a TCHAR-based struct, you should use the TCHAR-based TEXT() macro when defining string literals for it, eg:

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        SHFILEOPSTRUCT fos;
        fos.hwnd = Handle;
        //operacja kopiowania
        fos.wFunc = FO_COPY;
        //plik źródłowy
        fos.pFrom = TEXT("C:\\Melon\\AGA\\Bazy\0"); // don't forget the extra null terminator!
        fos.pTo = TEXT("...\0");
        ...
        SHFileOperation(&fos);
    }
    

    That will work in all C++Builder versions.

    On the other hand, if you are trying to use a String variable to define strings for the struct, that will work only if UNICODE is undefined in pre-2009 versions, and defined in post-2009 versions, eg:

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        String dirSrc("C:\\Melon\\AGA\\Bazy\0", 18); // don't forget the extra null terminator!
        String disDest(...);
        SHFILEOPSTRUCT fos;
        fos.hwnd = Handle;
        //operacja kopiowania
        fos.wFunc = FO_COPY;
        //plik źródłowy
        fos.pFrom = dirSrc.c_str();
        fos.pTo = dirDest.c_str();
        ...
        SHFileOperation(&fos);
    }
    

    If you don't want to rely on the UNICODE define, then you should use the ANSI or Unicode version of SHFILEOPSTRUCT explicitly, depending on whether you are working with ANSI (char) or Unicode (wchar_t) strings, eg:

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        SHFILEOPSTRUCTA fos;
        fos.hwnd = Handle;
        //operacja kopiowania
        fos.wFunc = FO_COPY;
        //plik źródłowy
        fos.pFrom = "C:\\Melon\\AGA\\Bazy\0"; // don't forget the extra null terminator!
        fos.pTo = "...\0";
        ...
        SHFileOperationA(&fos);
    }
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        SHFILEOPSTRUCTW fos;
        fos.hwnd = Handle;
        //operacja kopiowania
        fos.wFunc = FO_COPY;
        //plik źródłowy
        fos.pFrom = L"C:\\Melon\\AGA\\Bazy\0"; // don't forget the extra null terminator!
        fos.pTo = L"...\0";
        ...
        SHFileOperationW(&fos);
    }