0

Can somebody please tell me why i'm getting an error. I've been trying to figure this out for a bit now.

    LPCWSTR drive2[4] = { L"C:\\", L"D:\\", L"E:\\", L"F:\\" };
    int i;
    UINT test;

    for (i = 0; i<12; i++)        
    {                         
        test = GetDriveType(drive2[i]); //anything from here with "drive2[i]" is an error.

        switch (test)
        {                          
        case 0: ::MessageBox(Handle, drive2[i], "0 cannot be determined", MB_OK);
            break;                                                                       
        case 1: ::MessageBox(Handle, drive2[i], "1 invalid", MB_OK);
            break;                                                                                     
        case 2: ::MessageBox(Handle, drive2[i], "2 removable", MB_OK);
            break;                                                                                    
        case 3: ::MessageBox(Handle, drive2[i], "3 fixed", MB_OK);
            break;  
        default: "Unknown value!\n";                                                    

Thank you!

Andy
  • 43
  • 6

2 Answers2

1

LPCWSTR is an alias for const wchar_t*.

You are using the TCHAR version of the GetDriveType() and MessageBox() functions. TCHAR maps to wchar_t if UNICODE is defined at compile-time, otherwise it maps to char.

Your drive2 variable is an array of wchar_t pointers, so in order to pass drive2[i] as-is to GetDriveType() and MessageBox(), you have to compile your project for Unicode (ie, make the UNICODE conditional be defined at compile-time), which will make GetDriveType() map to GetDriveTypeW() and MessageBox() map to MessageBoxW() so that they accept only wide (wchar_t) strings. Otherwise, GetDriveType() will map to GetDriveTypeA() and MessageBox() will map to MessageBoxA() so they accept only narrow (char) strings.

You are passing narrow string literals to MessageBox(), which will not work when compiling for Unicode. And you can't pass wide strings to TCHAR functions if you are NOT compiling for Unicode - which sounds like the case in your situation, as the error message is complaining about passing a const wchar_t* pointer to a const char* parameter.

You need to use the TEXT() macro to make string literals be wide when UNICODE is defined, instead of being narrow.

I would also suggest using TEXT() for the string literals in your drive2 array as well, to match the TCHAR functions that you are passing the array elements to.

Also, your loop is going out of bounds of the drive2 array.

With that said, try this:

LPCTSTR drive2[4] = { TEXT("C:\\"), TEXT("D:\\"), TEXT("E:\\"), TEXT("F:\\") };
int i;
UINT test;

for (i = 0; i < 4; i++)        
{                         
    test = GetDriveType(drive2[i]);

    switch (test)
    {                          
        case 0:
            ::MessageBox(Handle, drive2[i], TEXT("0 cannot be determined"), MB_OK);
            break;                                                                       
        case 1:
            ::MessageBox(Handle, drive2[i], TEXT("1 invalid"), MB_OK);
            break;                                                                                     
        case 2:
            ::MessageBox(Handle, drive2[i], TEXT("2 removable"), MB_OK);
            break;                                                                                    
        case 3:
            ::MessageBox(Handle, drive2[i], TEXT("3 fixed"), MB_OK);
            break;  
        default:
            ::MessageBox(Handle, drive2[i], TEXT("Unknown value!"), MB_OK);
            break;  
    }
}

Otherwise, if you want to deal exclusively with wchar_t (which you should be), then use the Unicode-based function definitions directly, and use wide string literals only, don't deal with TCHAR at all:

LPCWSTR drive2[4] = { L"C:\\", L"D:\\", L"E:\\", L"F:\\" };
int i;
UINT test;

for (i = 0; i < 4; i++)        
{                         
    test = GetDriveTypeW(drive2[i]);

    switch (test)
    {                          
        case 0:
            ::MessageBoxW(Handle, drive2[i], L"0 cannot be determined", MB_OK);
            break;                                                                       
        case 1:
            ::MessageBoxW(Handle, drive2[i], L"1 invalid", MB_OK);
            break;                                                                                     
        case 2:
            ::MessageBoxW(Handle, drive2[i], L"2 removable", MB_OK);
            break;                                                                                    
        case 3:
            ::MessageBoxW(Handle, drive2[i], L"3 fixed", MB_OK);
            break;  
        default:
            ::MessageBoxW(Handle, drive2[i], L"Unknown value!", MB_OK);
            break;  
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

LPCSTR is const char*, while LPCWSTR is const wchar_t*, and they are not compatible.

Wide string declaration in C++: LPCWSTR string = L"Wide string";

Regular string: LPCSTR string = "Regular string";

If you want to use wide strings, you need to use the W version, in your case, use GetDriveTypeW.

Note that the GetDriveType is not a function, it is a MACRO that expands to GetDriveTypeA if your code is compiled in ASCII mode (default), but expands to GetDriveTypeW if the code is compiled in UNICODE mode

Michael
  • 932
  • 6
  • 15
  • You don't need to use the `W` versions explicitly if `UNICODE` is defined, and it _should_ be defined for all new projects. (Though UTF-8 support is picking up...) – chris Apr 15 '20 at 19:08
  • It is not defined by default as far as I know. You should define it in project properties or add the corresponding flag. EDIT: I just checked and the default is still Multi-byte (ASCII) – Michael Apr 15 '20 at 19:09
  • 2
    I think it is safest to explicitly use the W or A version, depending upon your intent. Then you don't have to assume anything. – rsjaffe Apr 15 '20 at 19:19