Link to home
Start Free TrialLog in
Avatar of newbie-netter
newbie-netter

asked on

MultiByteToWideChar returns The Parameter is Incorrect

This worked fine until I wanted to change the behavior and not use a constant string.

HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc,LPSTR lpszWorkObj)
{
    HRESULT hres;
    IShellLink* psl;
      char szLinkFilename[MAX_PATH];

      sprintf(szLinkFilename,"%s\\%s.lnk",lpszPathLink,lpszDesc);
      
//      AfxOleInit();
      CoInitialize(NULL);
    hres = CoCreateInstance(CLSID_ShellLink, NULL,
        CLSCTX_INPROC_SERVER,IID_IShellLink, (void**)&psl);
    if (SUCCEEDED(hres)) {
        IPersistFile* ppf;
//        psl->/*lpVtbl->*/SetPath((const char*)lpszPathObj);
        psl->/*lpVtbl->*/SetPath((const char*)szLinkFilename);
        psl->/*lpVtbl->*/SetWorkingDirectory((const char*)lpszWorkObj);
        psl->/*lpVtbl->*/SetDescription(lpszDesc);
        hres = psl/*lpVtbl->*/->QueryInterface(IID_IPersistFile, (void**)&ppf);
        if (SUCCEEDED(hres)) {
            WORD wsz[MAX_PATH];
            hres=MultiByteToWideChar(CP_ACP, 0, szLinkFilename, -1,
                (wchar_t*)wsz, MAX_PATH);
            hres = ppf->Save((wchar_t*)wsz, TRUE);
            ppf->Release();
        }
        psl->Release();
    }
      CoUninitialize();
    return hres;
}
Avatar of Axter
Axter
Flag of United States of America image

Please give more details.

What exactly does it do wrong when you change the code, and what are you expecting.

Give as much details as possible.
Using a WORD array seems a bit clumsy to me. What about

        if (SUCCEEDED(hres)) {
            wchar_t wsz[MAX_PATH];
            hres=MultiByteToWideChar(CP_ACP, 0, szLinkFilename, -1,
                wsz, MAX_PATH);
            hres = ppf->Save(wsz, TRUE);
           ppf->Release();
        }

?

BTW, are you sure it isn't 'Save()' that returns an error?
Avatar of newbie-netter
newbie-netter

ASKER

The code as shown gives an error "The Parameter is Incorrect" if I call it like this:
int _tmain(int argc, _TCHAR* argv[])
 {
      HRESULT hres;
      TCHAR szStartProgPath[MAX_PATH];

      if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS |CSIDL_FLAG_CREATE, NULL, 0, szStartProgPath)))
      {
            PathAppend(szStartProgPath, TEXT("Lab Apps"));
            hres = CreateLink("N:\\RTS\\RTSMan.exe",szStartProgPath,"RTS Manager","n:\\rts" );
      }

  return hres;
}

My code is based off of the example here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_programming/shortcuts/shortcut.asp
Are you compiling that as UNICODE?
if UNICODE is enabled then the second parameter
szStartProgPath is in correct,  since its a multi-byte string, whereas the CreateLink function is expecting LPSTR.

you need to convert szStartProgPath to LPSTR string using MultiByteToWideChar before passing.

_novi_
I have "Character Set" set to use Multi-Byte Character Set
The createlink function is receiving szStarProgPath correctly during debug and it works OK until the point where it runs the MultiByteToWideChar function.  I tried the suggestion from jkr which cleans up the code a bit but I still get the error.  It is not the Save that gives the error, but the MultiByteToWideChar function.
In this case, try

#include <stdlib.h>

//...

        if (SUCCEEDED(hres)) {
            wchar_t wsz[MAX_PATH];
            mbstowcs(wsz, szLinkFilename, lstrlen(szLinkFileName));
            hres = ppf->Save(wsz, TRUE);
           ppf->Release();
        }
Ok, we are making some progress.  The return value for "Parameter is incorrect" just happens to be the number of bytes of the length of the string  (58).  So there is no error with MultiByteToWideChar.  However, the code is still not working.  I am getting an error in ppf->Save as you suspected.  I checked the value of the wsz and it is a good path.  I copied the path (see below) into Start Run and explorer opened at the correct spot.

+      wsz      0x0012f998 "C:\Documents and Settings\All Users.WIN2K\Start Menu\Programs\Lab Apps\RTS Manager.lnk"      wchar_t [260]
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That was it!  Thanks.  This is how my code ended up:

HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc,LPSTR lpszWorkObj)
{
    HRESULT hres;
    IShellLink* psl;
    char szLinkFilename[MAX_PATH];

    sprintf(szLinkFilename,"%s\\%s.lnk",lpszPathLink,lpszDesc);
      
    CoInitialize(NULL);
    hres = CoCreateInstance(CLSID_ShellLink, NULL,
        CLSCTX_INPROC_SERVER,IID_IShellLink, (void**)&psl);
    if (SUCCEEDED(hres)) {
        IPersistFile* ppf;
        psl->/*lpVtbl->*/SetPath((const char*)lpszPathObj);
        psl->/*lpVtbl->*/SetWorkingDirectory((const char*)lpszWorkObj);
        psl->/*lpVtbl->*/SetDescription(lpszDesc);
        hres = psl/*lpVtbl->*/->QueryInterface(IID_IPersistFile, (void**)&ppf);
        if (SUCCEEDED(hres)) {
            wchar_t wsz[MAX_PATH];
            hres=MultiByteToWideChar(CP_ACP, 0, szLinkFilename, -1, wsz, MAX_PATH);
            hres = ppf->Save(wsz, TRUE);
            ppf->Release();
        }
        psl->Release();
    }
    CoUninitialize();
    return hres;
}