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", lpszPathLi nk,lpszDes c);
// AfxOleInit();
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_She llLink, NULL,
CLSCTX_INPROC_SERVER,IID_I ShellLink, (void**)&psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
// psl->/*lpVtbl->*/SetPath(( const char*)lpszPathObj);
psl->/*lpVtbl->*/SetPath(( const char*)szLinkFilename);
psl->/*lpVtbl->*/SetWorkin gDirectory ((const char*)lpszWorkObj);
psl->/*lpVtbl->*/SetDescri ption(lpsz Desc);
hres = psl/*lpVtbl->*/->QueryInte rface(IID_ IPersistFi le, (void**)&ppf);
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
hres=MultiByteToWideChar(C P_ACP, 0, szLinkFilename, -1,
(wchar_t*)wsz, MAX_PATH);
hres = ppf->Save((wchar_t*)wsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
return hres;
}
HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc,LPSTR lpszWorkObj)
{
HRESULT hres;
IShellLink* psl;
char szLinkFilename[MAX_PATH];
sprintf(szLinkFilename,"%s
// AfxOleInit();
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_She
CLSCTX_INPROC_SERVER,IID_I
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
// psl->/*lpVtbl->*/SetPath((
psl->/*lpVtbl->*/SetPath((
psl->/*lpVtbl->*/SetWorkin
psl->/*lpVtbl->*/SetDescri
hres = psl/*lpVtbl->*/->QueryInte
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
hres=MultiByteToWideChar(C
(wchar_t*)wsz, MAX_PATH);
hres = ppf->Save((wchar_t*)wsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
return hres;
}
Using a WORD array seems a bit clumsy to me. What about
if (SUCCEEDED(hres)) {
wchar_t wsz[MAX_PATH];
hres=MultiByteToWideChar(C P_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?
if (SUCCEEDED(hres)) {
wchar_t wsz[MAX_PATH];
hres=MultiByteToWideChar(C
wsz, MAX_PATH);
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
?
BTW, are you sure it isn't 'Save()' that returns an error?
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(SHGetFolderPa th(NULL, CSIDL_COMMON_PROGRAMS |CSIDL_FLAG_CREATE, NULL, 0, szStartProgPath)))
{
PathAppend(szStartProgPath , TEXT("Lab Apps"));
hres = CreateLink("N:\\RTS\\RTSMa n.exe",szS tartProgPa th,"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
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hres;
TCHAR szStartProgPath[MAX_PATH];
if(SUCCEEDED(SHGetFolderPa
{
PathAppend(szStartProgPath
hres = CreateLink("N:\\RTS\\RTSMa
}
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_
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_
ASKER
I have "Character Set" set to use Multi-Byte Character Set
ASKER
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();
}
#include <stdlib.h>
//...
if (SUCCEEDED(hres)) {
wchar_t wsz[MAX_PATH];
mbstowcs(wsz, szLinkFilename, lstrlen(szLinkFileName));
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
ASKER
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]
+ wsz 0x0012f998 "C:\Documents and Settings\All Users.WIN2K\Start Menu\Programs\Lab Apps\RTS Manager.lnk" wchar_t [260]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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", lpszPathLi nk,lpszDes c);
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_She llLink, NULL,
CLSCTX_INPROC_SERVER,IID_I ShellLink, (void**)&psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
psl->/*lpVtbl->*/SetPath(( const char*)lpszPathObj);
psl->/*lpVtbl->*/SetWorkin gDirectory ((const char*)lpszWorkObj);
psl->/*lpVtbl->*/SetDescri ption(lpsz Desc);
hres = psl/*lpVtbl->*/->QueryInte rface(IID_ IPersistFi le, (void**)&ppf);
if (SUCCEEDED(hres)) {
wchar_t wsz[MAX_PATH];
hres=MultiByteToWideChar(C P_ACP, 0, szLinkFilename, -1, wsz, MAX_PATH);
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
return hres;
}
HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc,LPSTR lpszWorkObj)
{
HRESULT hres;
IShellLink* psl;
char szLinkFilename[MAX_PATH];
sprintf(szLinkFilename,"%s
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_She
CLSCTX_INPROC_SERVER,IID_I
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
psl->/*lpVtbl->*/SetPath((
psl->/*lpVtbl->*/SetWorkin
psl->/*lpVtbl->*/SetDescri
hres = psl/*lpVtbl->*/->QueryInte
if (SUCCEEDED(hres)) {
wchar_t wsz[MAX_PATH];
hres=MultiByteToWideChar(C
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
return hres;
}
What exactly does it do wrong when you change the code, and what are you expecting.
Give as much details as possible.