Google Answers Logo
View Question
 
Q: LPCWSTR conversion problems ( No Answer,   5 Comments )
Question  
Subject: LPCWSTR conversion problems
Category: Computers > Programming
Asked by: timtitus-ga
List Price: $50.00
Posted: 19 Jun 2006 12:43 PDT
Expires: 19 Jul 2006 12:43 PDT
Question ID: 739419
Using Microsoft visual studio v6.0, I want to call the function
WinHTTPConnect, and it requires an LPCWSTR (LongPointer Constant Wide
STRing) as its second operand.

I can get this to work if I hard-code the hostname like such:

WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0);

The problem is that I need this to be a variable (not a constant). 
Here is the variable that I want to use:

char Hostname[100];
sprintf(Hostname, "www.microsoft.com");

The problem is twofold:
1) How do I convert the Hostname to a wide character string?
2) How do I have the function accept a variable (not a constant)?

Thanks!
Answer  
There is no answer at this time.

Comments  
Subject: Re: LPCWSTR conversion problems
From: storm_-ga on 21 Jun 2006 01:39 PDT
 
Timtitus,

there are 2 ways to do this:

1. Using ATL (USES_CONVERSION and A2W)

#include <crtdbg.h>
#include <atlconv.h>

USES_CONVERSION;

char Hostname[100];
sprintf(Hostname, "www.microsoft.com");
WinHttpConnect(hSession, A2W(Hostname), INTERNET_DEFAULT_HTTPS_PORT, 0);

2. Using own wrapper and WideCharToMultiByte API

class CWide2Ansi
{
public:
	CWide2Ansi(LPCWSTR lpwszString);
	~CWide2Ansi();
	operator LPCSTR() const;

protected:

private:
	CWide2Ansi();
	LPSTR m_lpaszString;
};

// Default constructor
CWide2Ansi::CWide2Ansi():
	m_lpaszString(NULL)
{
}

// Constructs object and convert lpwszString to multibyte
CWide2Ansi::CWide2Ansi(LPCWSTR lpwszString):
	m_lpaszString(NULL)
{
	int nLen = ::lstrlenW(lpwszString) + 1;
	m_lpaszString = new CHAR[nLen];
	if (m_lpaszString == NULL)
	{
		return;
	}

	memset(m_lpaszString, 0, nLen * sizeof(CHAR));

	if (!::WideCharToMultiByte(CP_ACP, 0, lpwszString, nLen,
		m_lpaszString, nLen, NULL, NULL) == 0)
	{
		// Conversation failed
		return;
	}
}

// Destructor
CWide2Ansi::~CWide2Ansi()
{
	if (m_lpaszString != NULL)
	{
		delete [] m_lpaszString;
	}
}

// Returns converted string
CWide2Ansi::operator LPCSTR() const
{
	return m_lpaszString;
}


Sample:

char Hostname[100];
sprintf(Hostname, "www.microsoft.com");
WinHttpConnect(hSession, CWide2Ansi(Hostname), INTERNET_DEFAULT_HTTPS_PORT, 0);

This wrapper tested in the VC 6.0 and VC 7.1

Good luck.
Subject: Re: LPCWSTR conversion problems
From: storm_-ga on 21 Jun 2006 03:29 PDT
 
Sorry, I've made a mistake in the previous comment, you need use
CAnsi2Wide instead of CWide2Ansi own wrapper.

This is right:

// Declaration

// class CAnsi2Wide - implements ANSI to Unicode string conversion
class CAnsi2Wide
{
public:
	CAnsi2Wide(LPCSTR lpaszString);
	~CAnsi2Wide();
	operator LPCWSTR() const;

protected:

private:
	CAnsi2Wide();
	LPWSTR m_lpwszString;
};


// Implementation


// Default constructor
CAnsi2Wide::CAnsi2Wide():
	m_lpwszString(NULL)
{
}

// Constructs object and convert lpaszString to Unicode
CAnsi2Wide::CAnsi2Wide(LPCSTR lpaszString):
	m_lpwszString(NULL)
{
	int nLen = ::lstrlenA(lpaszString) + 1;
	m_lpwszString = new WCHAR[nLen];
	if (m_lpwszString == NULL)
	{
		return;
	}

	memset(m_lpwszString, 0, nLen * sizeof(WCHAR));

	if (::MultiByteToWideChar(CP_ACP, 0, lpaszString, nLen, m_lpwszString, nLen) == 0)
	{
		// Conversation failed
		return;
	}
}

// Destructor
CAnsi2Wide::~CAnsi2Wide()
{
	if (m_lpwszString != NULL)
	{
		delete [] m_lpwszString;
	}
}

// Returns converted string
CAnsi2Wide::operator LPCWSTR() const
{
	return m_lpwszString;
}


Usage sample:

char Hostname[100];
sprintf(Hostname, "www.microsoft.com");
WinHttpConnect(hSession, CAnsi2Wide(Hostname), INTERNET_DEFAULT_HTTPS_PORT, 0);

All questions are welcome.
Subject: Re: LPCWSTR conversion problems
From: retrotom-ga on 30 Jun 2006 11:55 PDT
 
There is actually a much easier way to deal with this. VC++ comes with
the function 'mbstowcs()' which converts a multi-byte char pointer to
a wide char string. So to get the kind of functionality you desire
just add this function to you code:

LPCWSTR MultiCharToUniChar(char* mbString)
{
	int len = strlen(mbString) + 1;
	wchar_t *ucString = new wchar_t[len];
	mbstowcs(ucString, mbString, len);
	return (LPCWSTR)ucString;
}

This way, all you need to do is call:

WinHttpConnect( hSession, MultiCharToUniChar("www.microsoft.com"),
INTERNET_DEFAULT_HTTPS_PORT, 0);

Or 

WinHttpConnect( hSession, MultiCharToUniChar(HostName),
INTERNET_DEFAULT_HTTPS_PORT, 0);

And of course, you can rename the function so that it's shorter and
easier to use. This actually a common problem, but it's not as
involved as the previous comment makes it out to be. You don't have to
create a whole class for conversions.
Subject: Re: LPCWSTR conversion problems
From: storm_-ga on 04 Jul 2006 00:51 PDT
 
The main purpose of the classs is automatic resource releasing in
destructor and it works correctly. Your example has memory leak:
pointer returned from MultiCharToUniChar must be deleted.

This is right:

LPCWSTR lpszwBuffer = MultiCharToUniChar("www.microsoft.com");
if (lpszwBuffer != NULL)
{
   WinHttpConnect( hSession, lpszwBuffer, INTERNET_DEFAULT_HTTPS_PORT, 0);
   delete[] lpszwBuffer;
}

Moreover CRT functions aren't the best way of conversion. They are
depricated and aren't recomended for use. It is better to use
MultiByteToWideChar Win API directly or wrappers for this function
(CA2W from ATL 7.0 or A2W from ATL 3.0).

See "ATL and MFC String Conversion Macros"
http://msdn2.microsoft.com/en-us/library/87zae4a3.aspx for differences
between the older string conversion macros (ATL 3.0) and the new
string conversion classes (ATL 7.0)
Subject: Re: LPCWSTR conversion problems
From: soonts-ga on 18 Jul 2006 14:38 PDT
 
// There's an easier solution man :-)
// RTFM "printf Type Field Characters" about "%S" (upper-case S):

// When used with printf functions, specifies a wide-character string;
// when used with wprintf functions, specifies a single-byte?character string.
// Characters are printed up to the first null character
// or until the precision value is reached.

HRESULT MyHttpConnect(HINTERNET hSession, const char* strServer,
HINTERNET *pResult)
{
    *pResult = NULL;
    if(!strServer || !strServer[0]) return E_INVALIDARG;

    wchar_t *strTemp = (wchar_t *)(_alloca(strlen(strServer) * 2 + 2)));
    swprintf(strTemp, "%S", strServer);

    *pResult = WinHttpConnect(hSession, strTemp, INTERNET_DEFAULT_HTTPS_PORT, 0);
    return (*pResult) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
}

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy