利用Win32的網(wǎng)絡(luò)函數(shù)建一個(gè)網(wǎng)絡(luò)瀏覽器
發(fā)布時(shí)間:2008-01-21 閱讀數(shù): 次 來源:網(wǎng)樂原科技
摘要
這篇技術(shù)性文章討論了如何利用Microsoft Win32網(wǎng)絡(luò)函數(shù)創(chuàng)建一個(gè)網(wǎng)絡(luò)瀏覽器。這篇文章的宗旨是讓讀者了解一些Win32網(wǎng)絡(luò)函數(shù)的作用、能力和使用范圍,而不是為這些功能給出一個(gè)詳細(xì)的文檔。這篇文章所配合的SurfBear樣本應(yīng)用程序使用Win32網(wǎng)絡(luò)函數(shù)從網(wǎng)絡(luò)服務(wù)器上讀取HTML文件,并把它們顯示成原始的、沒有經(jīng)過格式化的文本。
介紹
不通過網(wǎng)絡(luò),你就無法了解我的一個(gè)朋友。計(jì)算機(jī)雜志已經(jīng)在internet上設(shè)置了電子期刊,而本地的報(bào)紙也已經(jīng)把整個(gè)段落都放到了網(wǎng)絡(luò)上。事實(shí)上,許多報(bào)紙都在聯(lián)機(jī)。每個(gè)人都有一個(gè)主頁,甚至一些無家可歸的人都有一個(gè)主頁。雖然有許多關(guān)于網(wǎng)絡(luò)的消息難免言過其實(shí),但網(wǎng)絡(luò)正在變成計(jì)算機(jī)整體的一部分已經(jīng)是無庸置疑的了。
Microsoft 已經(jīng)介紹了Microsoft Win32網(wǎng)絡(luò)函數(shù)來協(xié)助開發(fā)者把網(wǎng)絡(luò)變成他們的應(yīng)用程序的整體部分。這些新的功能簡化了使用FTP(文件傳輸協(xié)議)、和HTTP(超文本傳輸協(xié)議)訪問網(wǎng)絡(luò)。使用Win32網(wǎng)絡(luò)函數(shù)的開發(fā)者不需要對(duì)TCP/IP或Windows 配件。對(duì)于一些最普通的操作,開發(fā)者不需要知道他們正在使用的某個(gè)協(xié)議的細(xì)節(jié)。
最終,Win32網(wǎng)絡(luò)函數(shù)將成為Win32應(yīng)用程序接口的一部分并且與基于Windows的不同的平臺(tái)一起發(fā)布。最初,Win32網(wǎng)絡(luò)函數(shù)將安裝在一個(gè)叫做WININET.DLL的再分布式動(dòng)態(tài)鏈接庫里。(來自Microsoft網(wǎng)絡(luò)軟件開發(fā)工具包,其網(wǎng)址是:http://www.microsoft.com/inter/sdle/)。這屬于網(wǎng)絡(luò)開發(fā)工具包的一部分。
這篇文章說明了如何使用Win32網(wǎng)絡(luò)函數(shù)去創(chuàng)建一個(gè)簡單的網(wǎng)絡(luò)瀏覽器。它沒有具體詳細(xì)的討論這些功能的細(xì)節(jié),但對(duì)他們的用法和操作給出了一個(gè)演示。請(qǐng)參考網(wǎng)址是http://www.microsoft.com/intdev/sdk/docs/wininet的Microsoft Win32網(wǎng)絡(luò)函數(shù)的主題,可以了解到全部的細(xì)節(jié)。
這篇文章是配合SurfBear樣本應(yīng)用程序而創(chuàng)作的。SurfBear是一個(gè)HTML文件。覆蓋了這個(gè)過程種特定的網(wǎng)絡(luò)部分,但它沒有涉及與這個(gè)過程有關(guān)的用戶接口問題或HTML文件的顯示或操作問題。
注意:這篇文章是基于WININET.DLL一個(gè)相當(dāng)早的版本。很可能其中的參數(shù)名、標(biāo)識(shí)名和函數(shù)名發(fā)生了改變。但是函數(shù)的范圍和意圖應(yīng)該還是和這篇文章中描述的是一致的。
網(wǎng)絡(luò)函數(shù)
最好的探討Win32網(wǎng)絡(luò)函數(shù)的方法是直接進(jìn)入代碼。下面的代碼是樣本的代碼,為了方便閱讀,錯(cuò)誤處理部分已經(jīng)被刪除掉了。
HINTERNET hNet = ::InternetOpen("MSDN SurfBear",
PRE_CONFIG_INTERNET_ACCESS,
NULL,
INTERNET_INVALID_PORT_NUMBER,
0) ;
HINTERNET hUrlFile = ::InternetOpenUrl(hNet,
"http://www.microsoft.com",
NULL,
0,
INTERNET_FLAG_RELOAD,
0) ;
char buffer[10*1024] ;
DWORD dwBytesRead = 0;
BOOL bRead = ::InternetReadFile(hUrlFile,
buffer,
sizeof(buffer),
&dwBytesRead);
::InternetCloseHandle(hUrlFile) ;
::InternetCloseHandle(hNet) ;
上面列舉的代碼包括四個(gè)網(wǎng)絡(luò)函數(shù):InternetOpen、InternetOpenOrl、InternetReadFile和InternetCloseHandle。下面我們依次對(duì)這些函數(shù)進(jìn)行分析。
InternetOpen
InternetOpen初始化WININET.DLL。它在其他的Win32網(wǎng)絡(luò)函數(shù)之前被調(diào)用。
HINTERNET hNet = ::InternetOpen(
"MSDN SurfBear", // 1 LPCTSTR lpszCallerName
PRE_CONFIG_INTERNET_ACCESS, // 2 DWORD dwAccessType
"", // 3 LPCTSTR lpszProxyName
INTERNET_INVALID_PORT_NUMBER, // 4 INTERNET_PORT nProxyPort
0 // 5 DWORD dwFlags
) ;
InternetOpen返回一個(gè)類型為HINTERNET的句柄。其他的Win32網(wǎng)絡(luò)函數(shù)把這個(gè)句柄當(dāng)作一個(gè)參數(shù)?,F(xiàn)在你不能把一個(gè)HINTERNET句柄用在類似于ReadFile之類的其他Win32函數(shù)中。但是隨著Microsoft Windows和Microsoft Windows NT網(wǎng)絡(luò)支持的成熟,這一點(diǎn)在將來不是不可能實(shí)現(xiàn)的。
當(dāng)你已經(jīng)結(jié)束使用Wein32網(wǎng)絡(luò)函數(shù)時(shí),你應(yīng)該調(diào)用InternetCloseHandle釋放InternetOpen分配的資源。使用Microsoft基礎(chǔ)類(MFC)的應(yīng)用程序?qū)奈募臉?gòu)造程序里象征性地調(diào)用InternetOpen。絕大多數(shù)應(yīng)用程序都將在每一進(jìn)程里調(diào)用InternetOpen。
InternetOpen 的第一個(gè)參數(shù)lpszCallerName指定正在使用網(wǎng)絡(luò)函數(shù)的應(yīng)用程序。當(dāng)HTTP協(xié)議使用時(shí),這個(gè)名字將變成用戶代理。
第二個(gè)參數(shù)dwAccessType指定訪問類型。在上面的例子里,PRE_CONFIG_INTERNET_ACCESS訪問類型指示W(wǎng)in32網(wǎng)絡(luò)函數(shù)使用登記信息去發(fā)現(xiàn)一個(gè)服務(wù)器。使用PRE_CONFIG_INTERNET_ACCESS需要正確設(shè)定登記信息。這里我耍了一個(gè)小花招并讓網(wǎng)絡(luò)開發(fā)者替我登記注冊(cè)。如果你不想欺騙,你需要按圖1所示設(shè)定登記信息。
在登記注冊(cè)中,把AccessType設(shè)置為1,則意味著“直接入網(wǎng)”,把AccessType 設(shè)置為2,意味著“使用網(wǎng)關(guān)”。把DisableServiceLocation設(shè)置為1,將讓它使用一個(gè)已經(jīng)命名的服務(wù)器;否則將找到一個(gè)使用注冊(cè)信息和名字決議(RNR)應(yīng)用程序接口的服務(wù)器,它是Windows接口的一部分。
其他的訪問類型包括以下幾種:
LOCAL_INTERNET_ACCESS只連接到當(dāng)?shù)豂nternet網(wǎng)站。例如,如果我使用SurfBear標(biāo)志,我就只能訪問Microsoft整體的Internet網(wǎng)站。
CERN_PROXY_INTERNET_ACCESS使用一個(gè)CERN代理去訪問web。CERN代理是一個(gè)充當(dāng)網(wǎng)關(guān)的web服務(wù)器并且能向要使用代理的服務(wù)器發(fā)送HTTP請(qǐng)求。
GATEWAY_INTERNET_ACCESS允許連接到World Wide Web。我可以用這個(gè)訪問類型去訪問web上的任何站點(diǎn)。
GATEWAY_PROXY_INTERNET_ACCESS和CERN_PROXY_ACCESS訪問類型要求第三個(gè)參數(shù)給InternetOpen:服務(wù)器名(lpszProxyName)。PRE_CONFIG_INTERNET_ACCESS不要求服務(wù)器名,因?yàn)樗梢詾榉?wù)器搜索寄存信息。
NProxyPort參數(shù)用在CERN_PROXY_INTERNET_ACCESS中用來指定使用的端口數(shù)。使用INTERNET_INVALID_PORT_NUMBER相當(dāng)于提供卻省的端口數(shù)。
最后一個(gè)參數(shù)棗dwFlags,設(shè)置額外的選擇。你可以使用 INTERNET_FLAG_ASYNC標(biāo)志去指示使用返回句句柄的將來的Internet函數(shù)將為回調(diào)函數(shù)發(fā)送狀態(tài)信息,使用InternetSetStatusCallback進(jìn)行此項(xiàng)設(shè)置。
InternetOpenUrl
一旦你把Win32網(wǎng)絡(luò)函數(shù)初始化了,你就可以使用其他網(wǎng)絡(luò)函數(shù)。下一個(gè)要調(diào)用的Internet 函數(shù)是InternetOpenUrl。這個(gè)函數(shù)連接到一個(gè)網(wǎng)絡(luò)服務(wù)器上并且最被從服務(wù)器上讀取數(shù)據(jù)。InternetOpenUrl能對(duì)FTP,Gopher或HTTP協(xié)議起作用。在這篇文章中,我們只涉及HTTP協(xié)議。
HINTERNET hUrlFile = ::InternetOpenUrl(
hNet, // 1 HINTERNET hInternetSession
"http://www.microsoft.com", // 2 LPCTSTR lpszUrl
NULL, // 3 LPCTSTR lpszHeaders
0, // 4 DWORD dwHeadersLength
INTERNET_FLAG_RELOAD, // 5 DWORD dwFlags
0 // 6 DWORD dwContext
) ;
InternetOpenUrl也返回一個(gè)HINTERNET,它被傳遞給在這個(gè)URL(統(tǒng)一資源定位)上操作的函數(shù)。你應(yīng)該使用InternetClose來關(guān)閉這個(gè)句柄的處理。
InternetOpenUrl的第一個(gè)參數(shù)hInternetSession是從InternetOpen返回的句柄。第二個(gè)參數(shù)lpszUrl是我們需要的資源的URL(統(tǒng)一資源定位)。在上面的例子中,我們想得到一個(gè)Microsoft的web主頁。下面兩個(gè)參數(shù)lpszHeaders和HeaderLength用來向服務(wù)器傳送額外的信息。使用這些參數(shù)要求具有正在使用的特定協(xié)議的知識(shí)。
DwFlag是一個(gè)可以用幾種方式修改InternetOpenUrl行為的標(biāo)志,InternetOpenUrl的行為包括關(guān)閉、隱藏,使原始數(shù)據(jù)可用和用存在的連接取代開辟一個(gè)新的連接。
最后一個(gè)參數(shù)dwContext是一個(gè) DWORD上下文值。如果有一個(gè)值已經(jīng)被指定,它將被送到狀態(tài)回調(diào)函數(shù)。如果這個(gè)值是0,信息將不會(huì)被送到狀態(tài)回調(diào)函數(shù)。
InternetReadFile
你打開一個(gè)文件后,就要讀它,所以下一個(gè)函數(shù)是InternetReadFile是符合邏輯的:
char buffer[10*1024] ;
DWORD dwBytesRead = 0;
BOOL bRead = ::InternetReadFile(
hUrlFile, // 1 HINTERNET hFile
buffer, // 2 LPVOID lpBuffer
sizeof(buffer), // 3 DWORD dwNumberOfBytesToRead
&dwBytesRead // 4 LPDWORD lpdwNumberOfBytesRead
);
buffer[dwBytesRead] = 0 ;
pEditCtrl->SetWindowText(buffer) ;
InternetReadFile接收InternetOpenUrl返回的句柄。它也對(duì)其他Win32網(wǎng)絡(luò)函數(shù),例如FtpOpenFile,FopherOpenFile和HttpOpenRequest返回的句柄有影響。
剩下的InternetReadFile的三個(gè)參數(shù)也非常的明白直接。Inbuffer是指向保留數(shù)據(jù)的緩沖區(qū)的一個(gè)無返回值指針,dwNumberOfByteToRead以字節(jié)為單位指定緩沖區(qū)的尺寸。最后一個(gè)參數(shù),lpdwNumberOfBytesRead是一個(gè)指向包含讀入緩沖區(qū)字節(jié)數(shù)的變量的指針。如果返回值是TRUE,而且lpdwNumberOfBytesRead指向0,則文件已經(jīng)讀到了文件的末尾。這個(gè)行為與Win32 Re3adFile的函數(shù)的行為是一致的。一個(gè)真正的web瀏覽器將在InternetReadFile上循環(huán) ,不停地從Internet上讀入數(shù)據(jù)塊。
為了顯示緩沖區(qū),向緩沖區(qū)添加一個(gè)0并把它送到編輯器控制。
這樣,InternetOpen、InternetOpenUrl和InternetReadFile一起創(chuàng)建了Internet瀏覽器的基礎(chǔ)。他們使從Internet上讀取文件就象從你的本地硬盤驅(qū)動(dòng)器上讀取文件一樣容易。
HTTP函數(shù)
在一些例子中,InternetOpenUrl太普通了,所以你可能需要其他的Win32網(wǎng)絡(luò)函數(shù)。InternetOpenUrl相當(dāng)與不同的FTP,GOPHER和HTTP函數(shù)的封皮。當(dāng)使用HTTP時(shí),InternetOpenUrl調(diào)用InternetConnect,HttpOpenRequest以及HttpSendRequest,比如說我們想要在下載一個(gè)HTML頁之前得到它的尺寸以便于我們?cè)诰彌_區(qū)中為其分配適當(dāng)?shù)某叽?,HttpQueryInfo將得到web頁的大小。
警告:不是所有web 頁都支持得到頁尺寸。(例如:www.toystory.com和www.movielink.com不支持這個(gè)功能)另外,TCP/IP能傳遞的數(shù)據(jù)也比要求的要少。所以,你的應(yīng)用程序應(yīng)該處理著兩種情況并且圍繞InternetReadFile循環(huán)直到結(jié)果為TRUE同時(shí)*lpdwNumberOfBytesRead為0。
使用HttpOpenRequest,HttpSendRequest和HttpQueryInfo去打開文件http://www.microsoft.com/msdn/msdninfo的代碼顯示如下,錯(cuò)誤檢測已經(jīng)被刪除。
// Open Internet session.
HINTERNET hSession = ::InternetOpen("MSDN SurfBear",
PRE_CONFIG_INTERNET_ACCESS,
NULL,
INTERNET_INVALID_PORT_NUMBER,
0) ;
// Connect to www.microsoft.com.
HINTERNET hConnect = ::InternetConnect(hSession,
"www.microsoft.com",
INTERNET_INVALID_PORT_NUMBER,
"",
"",
INTERNET_SERVICE_HTTP,
0,
0) ;
// Request the file /MSDN/MSDNINFO/ from the server.
HINTERNET hHttpFile = ::HttpOpenRequest(hConnect,
"GET",
"/MSDN/MSDNINFO/",
HTTP_VERSION,
NULL,
0,
INTERNET_FLAG_DONT_CACHE,
0) ;
// Send the request.
BOOL bSendRequest = ::HttpSendRequest(hHttpFile, NULL, 0, 0, 0);
// Get the length of the file.
char bufQuery[32] ;
DWORD dwLengthBufQuery = sizeof(bufQuery);
BOOL bQuery = ::HttpQueryInfo(hHttpFile,
HTTP_QUERY_CONTENT_LENGTH,
bufQuery,
&dwLengthBufQuery) ;
// Convert length from ASCII string to a DWORD.
DWORD dwFileSize = (DWORD)atol(bufQuery) ;
// Allocate a buffer for the file.
char* buffer = new char[dwFileSize+1] ;
// Read the file into the buffer.
DWORD dwBytesRead ;
BOOL bRead = ::InternetReadFile(hHttpFile,
buffer,
dwFileSize+1,
&dwBytesRead);
// Put a zero on the end of the buffer.
buffer[dwBytesRead] = 0 ;
// Close all of the Internet handles.
::InternetCloseHandle(hHttpFile);
::InternetCloseHandle(hConnect) ;
::InternetCloseHandle(hSession) ;
// Display the file in an edit control.
pEditCtrl->SetWindowText(buffer) ;
InternetConnect
InternetConnet函數(shù)連接到一個(gè)HTTP,F(xiàn)TP或Gopher服務(wù)器:
HINTERNET hConnect = ::InternetConnect(
hSession, //1 HINTERNET hInternetSession
"www.microsoft.com", //2 LPCTSTR lpszServerName
INTERNET_INVALID_PORT_NUMBER, //3 INTERNET_PORT nServerPort
"", //4 LPCTSTR lpszUsername
"", //5 LPCTSTR lpszPassword
INTERNET_SERVICE_HTTP, //6 DWORD dwService
0, //7 DWORD dwFlags
O //8 DWORD dwContext
) ;
第六個(gè)參數(shù)dwService決定服務(wù)類型(HTTP,F(xiàn)TP或Gopher)。在上面的例子中,InternetConnect連接到一個(gè)HTTP服務(wù)器上,因?yàn)閐wService被設(shè)置成INTERNET_SERVICE_HTTP。第二個(gè)參數(shù)(設(shè)置成www.microsoft.com)提供了服務(wù)器的地址。注意,HTTP地址必須為服務(wù)器名作語法分析,InternetOpenUrl為我們作語法分析。第一個(gè)參數(shù)hInternetSession是從InternetOpen返回的句柄。第四個(gè)、第五個(gè)參數(shù)提供一個(gè)用戶姓名和密碼 。這七個(gè)參數(shù)沒有控制任何標(biāo)志影響HTTP操作。最后一個(gè)參數(shù)為狀態(tài)回調(diào)函數(shù)提供前后關(guān)系的信息。
HttpOpenRequest
一旦和服務(wù)器的連接已經(jīng)建立,我們打開了想要的文件。HttpOpenRequest和HttpSenRequest一起工作打開文件。HttpOpenRequest去創(chuàng)建一個(gè)請(qǐng)求句柄并且把參數(shù)存儲(chǔ)在句柄中。HttpOpenRequest把請(qǐng)求參數(shù)送到HTTP服務(wù)器。
HINTERNET hHttpFile = ::HttpOpenRequest(
hConnect, // 1 HINTERNET hHttpSession
"GET", // 2 LPCTSTR lpszVerb
"/MSDN/MSDNINFO/", // 3 LPCTSTR lpszObjectName
HTTP_VERSION, // 4 LPCTSTR lpszVersion
NULL, // 5 LPCTSTR lpszReferer
0, // 6 LPCTSTR FAR * lplpszAcceptTypes
INTERNET_FLAG_DONT_CACHE, // 7 DWORD dwFlags
0 // 8 DWORD dwContext
) ;
到現(xiàn)在為止,網(wǎng)絡(luò)函數(shù)的許多參數(shù)看起來都類似。HttpOpenResult的第一個(gè)參數(shù)是由InternetConnet返回的 HINTERNET。HttpOpenRequest的第七和第八個(gè)參數(shù)執(zhí)行與InternetConnect中有相同名字的參數(shù)一樣的功能。
第二個(gè)參數(shù)(“GET”)指定我們想要得到由第三個(gè)參數(shù)(“/MSDN/MSDNINFO/”)命名的對(duì)象。HTTP版已經(jīng)傳遞第四個(gè)參數(shù);現(xiàn)在,它肯定是HTTP棗VERSION。因?yàn)椤癎ET”是最流行的動(dòng)詞類型,HttpOpenRequest將為這個(gè)參數(shù)接收一個(gè)空指針。
第五個(gè)參數(shù)lpszReferer是一個(gè)網(wǎng)點(diǎn)的地址。在這個(gè)網(wǎng)點(diǎn)上我們發(fā)現(xiàn)了我們現(xiàn)在想要看見的URL(統(tǒng)一資源定位)。換而言之,如果你在www.home.com上而且單擊了跳到www.microsoft.com的一個(gè)連接,第五個(gè)參數(shù)就是www.home.com。因?yàn)樗鼓阒赶蛄四繕?biāo)URL(統(tǒng)一資源定位)。這個(gè)值可以為空。第六個(gè)參數(shù)執(zhí)行一個(gè)我們的程序接收的文件類型列表。把空值傳遞給HttpOpenRequest即通知了服務(wù)器只有文本文件可以被接收。
HttpSendRequest
除了傳送請(qǐng)求外,HttpSendRequest允許你傳送額外的HTTP標(biāo)題給服務(wù)器。關(guān)于HTTP標(biāo)題的信息可以在http://www.w3.org/ 上的最新的說明上找到。在這個(gè)例子中,HttpSendRequest的所有參數(shù)都被傳遞為缺省值。
BOOL bSendRequest = ::HttpSendRequest(
hHttpFile, // 1 HINTERNET hHttpRequest
NULL, // 2 LPCTSTR lpszHeaders
0, // 3 DWORD dwHeadersLength
0, // 4 LPVOID lpOptional
0 // 5 DWORD dwOptionalLength
);
HttpQueryInfo
為了得到關(guān)于文件的信息,在調(diào)用HttpSendRequest后使用HttpQueryInfo函數(shù):
BOOL bQuery = ::HttpQueryInfo(
hHttpFile, // 1 HINTERNET hHttpRequest
HTTP_QUERY_CONTENT_LENGTH, // 2 DWORD dwInfoLevel
bufQuery, // 3 LPVOID lpvBuffer
&dwLengthBufQuery // 4 LPDWORD lpdwBufferLength
) ;
查詢的結(jié)構(gòu)是字符串或lpvBuffer中的字符串列表。HTTP_QUERY_CONTENT_LENGTH查詢得到文件的長度。你可以使用HttpQueryInfo查詢大范圍的信息。要獲知詳細(xì)情形可查閱網(wǎng)點(diǎn)http://www.microsoft.com/intdev/sdk/docs/wininet上的Microsoft Win32網(wǎng)絡(luò)函數(shù)專題。
SurfBear樣本應(yīng)用程序
SurBear樣本應(yīng)用程序使用Win32網(wǎng)絡(luò)函數(shù)從Internet上得到文件并且在編輯器上顯示原始的HTML格式。SurfBear使用HttpOpenRequest和HttpSendRequest取代InternetOpenUrl,純粹是為了演示的需要。
圖2 SurfBear 屏幕
SurfBear是一個(gè)MFC4.0版本的對(duì)話應(yīng)用程序。它所有與Internet有關(guān)的功能都在InternetThread.h和InternetThread.cpp文件中。
從internet上讀取文件要花費(fèi)相當(dāng)數(shù)量的時(shí)間,所以從一個(gè)工作線程調(diào)用網(wǎng)絡(luò)函數(shù)是一個(gè)明智的主意。通過這種方式,當(dāng)系統(tǒng)在等待得到數(shù)據(jù)時(shí),應(yīng)用程序的窗口能被改變尺寸和移動(dòng)。
圖3顯示了SurfBear的控制流。
當(dāng)用戶按下GOTO按鈕時(shí),CsurfBearDlg::OnBtnGoto調(diào)用CinternetThread:GetWebPoge,傳遞想要的web頁的HTTP地址。GetWebPage把HTTP地址語法分析成服務(wù)器和對(duì)象名,存儲(chǔ)在CinternetThread的成員變量中。GetWebPage然后調(diào)用AfxBeginThread,它產(chǎn)生一個(gè)運(yùn)行靜態(tài)成員函數(shù)的線程GetWebPage WorkerThread。如果網(wǎng)絡(luò)函數(shù)沒有被初始化,GetWebPageWorkerThread調(diào)用InternetOpen,然后它嘗試讀取想要的web頁。當(dāng)GetWebPageWorkerThread結(jié)束時(shí),它發(fā)送一個(gè)用戶定義的WM_READFILECOMPLETED消息給SurfBear對(duì)話框。OnReadFileCompleted處理這個(gè)消息并且把一個(gè)web頁復(fù)制到編輯器控制里。
總結(jié)
Win32網(wǎng)絡(luò)函數(shù)使從FTP,Gopher和HTTP服務(wù)器上讀取信息就想從你的硬盤驅(qū)動(dòng)器上讀取信息一樣容易。僅僅使用4個(gè)函數(shù)棗InternetOpen,InternetOpenUrl,InternetReadFile和InternetCloseHandle和很少的HTTP知識(shí),你就可以寫一個(gè)簡單的網(wǎng)絡(luò)瀏覽器。
把這個(gè)簡單的瀏覽器變成一個(gè)工業(yè)性質(zhì)的瀏覽器將要花費(fèi)很多工作,包括 一些對(duì)HTTP的了解,對(duì)如何顯示HTML文件的了解和以及使用多線程方式的能力。Win32網(wǎng)絡(luò)函數(shù)將開發(fā)者從與TCP/IP,Windows Sockets和HTTP編程有關(guān)的大多數(shù)煩悶工作中解脫出來