First, let's look at writing code to make simple HTTP requests such as requesting an HTML page from an Internet server. To do this the following calls should be made:
InternetOpen need only be called once, typically when the application is started or the first HTTP request is made. The handle returned by InternetOpen should eventually be closed, for example when the application terminates. The Windows CE Internet functions are declared in wininet.h and wininet.lib, so you will need to include and add these files to your project. Initializing the Internet Function Library InternetOpenBefore calling the Internet functions you should initialize the library by calling InternetOpen (Table 8.1) and store the handle returned. InternetClose-Handle should be called when your application has finished with the library. When initializing the library you will supply an agent name that is used by the server to identify your application, and information about whether a direct connection is to be made to the server or if a proxy server is to be used. Proxy servers are described later in this chapter.
The following code fragment shows a simple call to InternetOpen using a direct connection (that is, with no proxy server). HINTERNET hHttpOpen = NULL; hHttpOpen = InternetOpen(_T("Example Agent:"), INTERNET_OPEN_TYPE_DIRECT, NULL, // no proxy NULL, // no bypass addresses 0); // no flags When you have finished using the Internet functions, the handle returned by InternetOpen should be closed by calling InternetCloseHandle (Table 8.2) This might be, for example, when the application terminates. if(hHttpOpen != NULL) InternetCloseHandle(hHttpOpen);
Making the HTTP Request InternetOpenUrlOnce the Internet function library has been initialized, calls can be made to InternetOpenUrl to request resources. The function, at a minimum, should be passed the open handle returned from InternetOpen and the URL of the resource to be opened. hHttpRequest = InternetOpenUrl(hHttpOpen, szURL, NULL, 0, 0, 0); InternetOpenUrl extracts the protocol, server name, and resource path from the supplied URL. Windows CE does not support most of the flags supported by Windows NT/98/2000. This includes all the options for managing the resource cache.
Retrieving the Data InternetReadFileOnce a request has successfully been made, InternetReadFile (Table 8.4) can be used to retrieve the data. This function is typically called repeatedly, reading the data a chunk at a time, until the number of bytes read is zero. Notice that lpBuffer is a LPVOID pointer the data retrieved from the server can be text or binary. In most cases text is returned as ANSI characters rather than Unicode. Therefore, in Windows CE text retrieved from InternetReadFile is converted to Unicode. The following code fragment shows how to read the returned data in chunks. Note that the text returned from InternetReadFile is not NULL-terminated.
#define CHUNKSIZE 500 char charBuffer[CHUNKSIZE + 1]; TCHAR szBuffer[CHUNKSIZE + 1]; DWORD dwRead; do { // read from Internet HTTP server if(!InternetReadFile(hHttpRequest, charBuffer, CHUNKSIZE, &dwRead)) { cout _T("Could not read data") GetLastError(); break; } // convert to Unicode and display charBuffer[dwRead] = '\0'; mbstowcs(szBuffer, charBuffer, dwRead); szBuffer[dwRead] = '\0'; cout szBuffer; } while(dwRead > 0); Tidying Up InternetCloseHandleThe function InternetCloseHandle must be called for all handles returned from calling Internet functions. Do not call CloseHandle, because Internet handles are not kernel objects. Remember that you can call InternetOpenUrl multiple times to retrieve resources from a server using the handle returned from InternetConnect without closing it each time. This improves performance. if(hHttpRequest != NULL) InternetCloseHandle(hHttpRequest); if(hHttpOpen != NULL) InternetCloseHandle(hHttpOpen); Listing 8.1 shows the entire code used to prompt the user for a URL and display the HTML code returned from the server. Listing 8.1 Making an HTTP request using a sessionvoid Listing8_1() { HINTERNET hHttpOpen = NULL; HINTERNET hHttpRequest = NULL; TCHAR szURL[MAX_PATH + 1]; TCHAR szBuffer[CHUNKSIZE + 1]; DWORD dwRead; char charBuffer[CHUNKSIZE + 1]; if(!GetTextResponse( _T("Simple Request: Enter URL to Display: "), szURL, MAX_PATH)) return; hHttpOpen = InternetOpen(_T("Example Agent"), INTERNET_OPEN_TYPE_DIRECT, NULL, // no proxy NULL, // no bypass addresses 0); // no flags hHttpRequest = InternetOpenUrl(hHttpOpen, szURL, NULL, 0, 0, 0); do { // read from Internet HTTP server if(!InternetReadFile(hHttpRequest, charBuffer, CHUNKSIZE, &dwRead)) { cout _T("Could not read data") GetLastError(); goto cleanUp; } // convert to Unicode and display charBuffer[dwRead] = '\0'; mbstowcs(szBuffer, charBuffer, dwRead); szBuffer[dwRead] = '\0'; cout szBuffer; } while(dwRead > 0); cleanUp: if(hHttpRequest != NULL) InternetCloseHandle(hHttpRequest); if(hHttpOpen != NULL) InternetCloseHandle(hHttpOpen); }
|