1

Getting errors when trying to compile sample code:

MSDN Example: The Open Dialog Box

Why?

#include <windows.h>
#include <shobjidl.h> 

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
        COINIT_DISABLE_OLE1DDE);
    if (SUCCEEDED(hr))
    {
        IFileOpenDialog *pFileOpen;

        // Create the FileOpenDialog object.
        hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
            IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

        if (SUCCEEDED(hr))
        {
            // Show the Open dialog box.
            hr = pFileOpen->Show(NULL);

            // Get the file name from the dialog box.
            if (SUCCEEDED(hr))
            {
                IShellItem *pItem;
                hr = pFileOpen->GetResult(&pItem);
                if (SUCCEEDED(hr))
                {
                    PWSTR pszFilePath;
                    hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

                    // Display the file name to the user.
                    if (SUCCEEDED(hr))
                    {
                        MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
                        CoTaskMemFree(pszFilePath);
                    }
                    pItem->Release();
                }
            }
            pFileOpen->Release();
        }
        CoUninitialize();
    }
    return 0;
}

Error C2664 'int MessageBoxA(HWND,LPCSTR,LPCSTR,UINT)': cannot convert argument 2 from 'PWSTR' to 'LPCSTR' MSDNTut_3-OpenFileDialogBox ...\msdntut_3-openfiledialogbox\msdntut_3-openfiledialogbox\source.cpp 34

Error (active) E0167 argument of type "const wchar_t *" is incompatible with parameter of type "LPCSTR" MSDNTut_3-OpenFileDialogBox ...\MSDNTut_3-OpenFileDialogBox\MSDNTut_3-OpenFileDialogBox\Source.cpp 34

Error (active) E0167 argument of type "PWSTR" is incompatible with parameter of type "LPCSTR" MSDNTut_3-OpenFileDialogBox ...\MSDNTut_3-OpenFileDialogBox\MSDNTut_3-OpenFileDialogBox\Source.cpp 34

Microsoft Visual Studio Community 2017 Version 15.7.1 VisualStudio.15.Release/15.7.1+27703.2000 Microsoft .NET Framework Version 4.7.02556

Installed Version: Community

I fixed it by adding

#ifndef UNICODE
#define UNICODE
#endif

to the top.. I would still like an explanation on why that was necessary, please. ;)

Another fix is to Set the "Character Set" to "Use Unicode Character Set"

Project-> (Project Name) Properties->General->Project Defaults->Character Set

JwGaming
  • 79
  • 6

1 Answers1

0

I fixed it by adding

#ifndef UNICODE
#define UNICODE
#endif

to the top.. I would still like an explanation on why that was necessary, please. ;)

MessageBox is not actually a function, it is a macro:

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

So, depending on whether UNICODE is defined, MessageBox() maps to either MessageBoxW() (Unicode) or MessageBoxA() (ANSI). Your project is not defining UNICODE, so MessageBoxA() gets used, and PWSTR (pointer to wide string) is not compatible with LPCSTR (pointer to narrow string).

You could have used PSTR instead, or enabled UNICODE support, as you did.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
  • Thanks for answering and editing my Question. I was having a hard time getting the format right and it looks much better. I didn't know that (about the macro). I will keep that in mind for the future. I have just been adding the Unicode support by habit from the first module of the MSDN. – JwGaming May 25 '18 at 22:12
  • @JwGaming MS is using quite a few macros for these purposes, but you can always check it by `right click on the name->Peek Definition` – Killzone Kid May 25 '18 at 22:19
  • "*You could have used `PSTR` instead*" - that would have required more coding, as `IShellItem::GetDisplayName()` outputs only `PWSTR` data, so to use `MessageBox(A)` with `PSTR`, you would have to convert the data using `WideCharToMultiByte()` or equivalent. – Remy Lebeau May 26 '18 at 00:53
  • @RemyLebeau > solution would be to change MessageBox() to MessageBoxW() < I also like this solution you proposed. – JwGaming May 26 '18 at 19:33