January 10, 2009

How to correctly call HttpOpenRequest() with specified accept types?

Windows API: (Wininet)

HINTERNET HttpOpenRequest(
  __in  HINTERNET hConnect,
  __in  LPCTSTR lpszVerb,
  __in  LPCTSTR lpszObjectName,
  __in  LPCTSTR lpszVersion,
  __in  LPCTSTR lpszReferer,
  __in  LPCTSTR *lplpszAcceptTypes,
  __in  DWORD dwFlags,
  __in  DWORD_PTR dwContext
);

Tips:
lplpszAcceptTypes is not a pointer to a null-terminated string, it is a pointer to a null-terminated array of strings. 

Sample Code:

// A null-terminated array of null-terminated strings
const char* lplpszAcceptTypes[] = {"text/*", NULL}; // Accept only text documents

HINTERNET  hHttpFile = HttpOpenRequestA(
  hConnect,
  "GET",
  "/TextDocument",
  HTTP_VERSION,
  NULL,
  lplpszAcceptTypes,
  INTERNET_FLAG_DONT_CACHE, 1);

Reference in MSDN:

10 comments:

Rob said...

Thanks, I really need help with this too! I'm really having a time trying to make sense of the new types.

I tried the same thing as you recommended, but still end up with this error:
"error C2664: 'HttpOpenRequestW' : cannot convert parameter 6 from 'const char *[2]' to 'LPCWSTR *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast"

How should this be cast?

Using VC++ 2008 Express w/ SP1

Todd said...

Dear Rob,

My code example is for the ansi version of HttpOpenRequest (HttpOpenRequestA).

If you want to call HttpOpenRequestW, you need to use wchar string instead of char string.

Try the following code, hope it helpful :p

const wchar_t* lplpszAcceptTypes[] = {L"text/*", NULL};

HINTERNET hHttpFile = HttpOpenRequestW(
hConnect,
L"GET",
L"/TextDocument",
HTTP_VERSION,
NULL,
lplpszAcceptTypes,
INTERNET_FLAG_DONT_CACHE, 1);

RobRedbeard said...

Thanks Todd. I'm actually an American here in mainland China right now, so I'm always interested in making my computer and applications work with UNICODE. I believe all ANSI and MB development should stop. Luckily, Microsoft reflects the same view in Visual C++.

For those who don't know, we should post up the TCHAR version that is compatible with newer versions of Visual C++. I'll also show a more expansive types list for Web 2.0 programming.

For those who are new to this, the new default text mappings for Windows programming use a _TCHAR type that allows one code base to be compiled for ANSI or Unicode depending only on a simple #DEFINE UNICODE statement. Search MSDN for "Generic Text Mappings" for Microsoft's full guide to these changes.

Here's how to do this function in newer Visual C++ environments where the default is to compile for UNICODE:

const TCHAR* lplpszAcceptTypes[] = {L"text/xml",L"application/xml",L"application/xhtml+xml",L"text/html;q=0.9",L"text/plain;q=0.8",L"image/png",L"*/*;q=0.5", NULL};

HINTERNET hRequest = HttpOpenRequest( hConnect, lpszVerb, lpszObjectName, lpszVersion,
lpszReferrer, (LPCTSTR *) lplpszAcceptTypes,
dwFlags, dwOpenRequestContext );


Thanks again for blog Todd!

RobRedbeard

Todd said...

Dear RobRedbeard, thanks for post up the TCHAR version here, but I think the code will get an error for ANSI.

For TCHAR version, we need to use _TEXT macro to identify a string as UNICODE or ANSI.

const TCHAR* lplpszAcceptTypes[] =
{
_TEXT("text/xml"),
_TEXT("application/xml"),
_TEXT("application/xhtml+xml"),
_TEXT("text/html;q=0.9"),
_TEXT("text/plain;q=0.8"),
_TEXT("image/png"),
_TEXT("*/*;q=0.5"),
NULL
};

Anyway, your explanation for TCHAR is very helpful for those who are new to this :p

RobRedbeard said...

Ah, I see, thank you for the additional help. I generally use the _T("") mapping for brevity. I've never tested that code I put up with ANSI, again, something learned.

Happy New Year and thanks again!

Rob

Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

Anonymous said...

Genial fill someone in on and this fill someone in on helped me alot in my college assignement. Thank you seeking your information.

GuangZor said...

Thank you for the sample, really helpful!

Temp said...

I have:
HINTERNET WINAPI HttpOpenRequestA(HINTERNET,LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR *,DWORD,DWORD);

Anonymous said...

Many thanks.