📄 ch19.htm
字号:
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += "No server found there. \r\n";</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> m_out += "-------------------------\r\n";</font></pre>
<pre><font color="#008000"> UpdateData(FALSE);</font></pre>
<pre><font color="#008000">}</font></pre>
<P>The remainder of this section presents this code again, a few lines at a time. First, establish an Internet session by constructing an instance of <font color="#008000">CInternetSession</font>. There are a number of parameters to this constructor, but
they all have default values that will be fine for this application. The parameters follow:</P>
<ul>
<li> <B><font color="#008000">LPCTSTR pstrAgent</font></B>—The name of your application. If <font color="#008000">NULL</font>, it's filled in for you using the name that you gave to AppWizard.</P>
<li> <B><font color="#008000">DWORD dwContext</font></B>—The context identifier for the operation. For synchronous sessions, this is not an important parameter.</P>
<li> <B><font color="#008000">DWORD dwAccessType</font></B>—The access type, one of <font color="#008000">INTERNET_OPEN_TYPE_PRECONFIG</font> (default), <font color="#008000">INTERNET_OPEN_TYPE_DIRECT</font>, or <font
color="#008000">INTERNET_OPEN_TYPE_PROXY</font>.</P>
<li> <B><font color="#008000">LPCTSTR pstrProxyName</font></B>—The name of your proxy, if access is <font color="#008000">INTERNET_OPEN_TYPE_PROXY</font>.</P>
<li> <B><font color="#008000">LPCTSTR pstrProxyBypass</font></B>—A list of addresses to be connected directly rather than through the proxy server, if access is <font color="#008000">INTERNET_OPEN_TYPE_PROXY</font>.</P>
<li> <B><font color="#008000">DWORD dwFlags</font></B>—Options that can be OR'ed together. The available options are <font color="#008000">INTERNET_FLAG_DONT_CACHE</font>, <font color="#008000">INTERNET_FLAG_ASYNC</font>, and <font
color="#008000">INTERNET_FLAG_OFFLINE</font>.</P>
</ul>
<p><font color="#008000">dwAccessType</font><B> </B>defaults to using the value in the Registry. Obviously, an application that insists on direct Internet access or proxy Internet access is less useful than one that allows users to configure that
information. But making users set their Internet access type outside this program may be confusing. To set your default Internet access, double-click the My Computer icon on your desktop, then on the Control Panel, and then on the Internet tool in the
Control Panel. Choose the Connection tab, shown in Figure 19.7, and complete the dialog box as appropriate for your setup:</P>
<A HREF="Ufigs07.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch19/Ufigs07.gif"><b>Fig. 19.7</b></A>
<P><I>Set your Internet connection settings once, and all applications </I><I>can retrieve them from the Registry.</I></P>
<ul>
<li> If you dial up to the Internet, select the Dial check box and fill in the parameters in the top half of the page.</P>
<li> If you connect to the Internet through a proxy server, select the Proxy check box and click the Settings button to identify your proxy addresses and ports.</P>
<li> If you are connected directly to the Internet, leave both check boxes unselected.</P>
</ul>
<P>If you want to set up an <I>asynchronous</I> (non-blocking) session, for the reasons discussed in the "Using Windows Sockets" section of <A HREF="index18.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index18.htm" target="text">Chapter 18</A>, "Sockets, MAPI, and the Internet," your
options in <font color="#008000">dwFlags</font> must include <font color="#008000">INTERNET_FLAG_ASYNC</font>. In addition, you must call the member function <font color="#008000">EnableStatusCallback()</font> to set up the callback function. When a
request is made through the session—such as the call to <font color="#008000">OpenURL()</font> that occurs later in <font color="#008000">TryURL()</font>—and the response will not be immediate, a non-blocking session returns a pseudo error code,
<font color="#008000">ERROR_IO_PENDING</font>. When the response is ready, these sessions automatically invoke the callback function.</P>
<P>For this simple application, there is no need to allow the user to do other work or interact with the user interface while waiting for the session to respond, so the session is constructed as a blocking session and all the other default parameters are
also used:</P>
<pre><font color="#008000"> CInternetSession session;</font></pre>
<P>Having constructed the session, <font color="#008000">TryURL()</font> goes on to add a line to <font color="#008000">m_out</font> that echoes the URL passed in as a parameter. The <font color="#008000">"\r\n"</font> characters are return and
newline, and they separate the lines added to <font color="#008000">m_out</font>. <font color="#008000">UpdateData(FALSE)</font> gets that onto the screen:</P>
<pre><font color="#008000"> m_out += "Trying " + URL + "\r\n";</font></pre>
<pre><font color="#008000"> UpdateData(FALSE);</font></pre>
<P>Next is a call to the session's <font color="#008000">OpenURL()</font> member function. This function returns a pointer to one of several different file types, because the URL might have been to one of four protocols:</P>
<ul>
<li> <font color="#008000">file://</font> opens a file. The function constructs a <font color="#008000">CStdioFile</font> and returns a pointer to it.</P>
<li> <font color="#008000">ftp://</font> goes to an FTP site and returns a pointer to a <font color="#008000">CInternetFile</font> object.</P>
<li> <font color="#008000">gopher://</font> goes to a Gopher site and returns a pointer to a <font color="#008000">CGopherFile</font> object.</P>
<li> <font color="#008000">http://</font> goes to a World Wide Web site and returns a pointer to a <font color="#008000">CHttpFile object</font>.</P>
</ul>
<P>Because <font color="#008000">CGopherFile</font> and <font color="#008000">CHttpFile</font> both inherit from <font color="#008000">CInternetFile</font>, and because you can be sure that <font color="#008000">TryURL()</font> will not be passed a <font
color="#008000">file://</font> URL, it is safe to cast the returned pointer to a <font color="#008000">CInternetFile</font>.</P>
<blockquote><p><img src="tip.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/tip.gif">
<P>There is some confusion in Microsoft's online documentation whenever example URLs are shown. A backslash (\) character will never appear in a URL. In any Microsoft example that includes backslashes, use forward slashes (/) instead.</P>
<p><img src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<P>If the URL would not open, <font color="#008000">file</font> will be <font color="#008000">NULL</font> or <font color="#008000">OpenURL()</font>_ will throw an exception. (For background on exceptions, see <A HREF="index26.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index26.htm" target="text">Chapter
26</A>, "Exceptions, Templates, and the Latest Additions to C++.") While in a normal application it would be a serious error if a URL didn't open, in this application you are making up URLs to see if they work or not, and it's to be expected that
some of them won't. As a result, you should catch these exceptions yourself and do just enough to prevent runtime errors. In this case, it's enough to make sure that <font color="#008000">file</font> is <font color="#008000">NULL</font> when an exception
is thrown. To delete the exception and prevent memory leaks, call <font color="#008000">CException::Delete(),</font> which is not mentioned in the online documentation but does exist and safely deletes the exception. The block of code containing the call
to <font color="#008000">OpenURL()</font>is in Listing 19.3.</P>
<P><I>Listing 19.3—QueryDlg.cpp—CQueryDlg::TryURL()</I></P>
<pre><font color="#008000"> CInternetFile* file = NULL;</font></pre>
<pre><font color="#008000"> try</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> //We know for sure this is an Internet file,</font></pre>
<pre><font color="#008000"> //so the cast is safe</font></pre>
<pre><font color="#008000"> file = (CInternetFile*) session.OpenURL(URL);</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> catch (CInternetException* pEx)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> //if anything went wrong, just set file to NULL</font></pre>
<pre><font color="#008000"> file = NULL;</font></pre>
<pre><font color="#008000"> pEx->Delete();</font></pre>
<pre><font color="#008000"> }</font></pre>
<P>If <font color="#008000">file</font> is not <font color="#008000">NULL</font>, this routine will display some of the web page that was found. It first echoes another line to <font color="#008000">m_out. T</font>hen in a <font color="#008000">for</font>
loop, the routine calls <font color="#008000">CInternetFile::ReadString()</font> to fill the <font color="#008000">CString line</font> with the characters in <font color="#008000">file</font> up to the first <font color="#008000">\r\n</font>, which are
stripped off. This code simply tacks <font color="#008000">line</font> (and another <font color="#008000">\r\n</font>) onto <font color="#008000">m_out</font>. If you would like to see more or less than the first 20 lines of the page, adjust the number in
this <font color="#008000">for</font> loop. When the first few lines have been read, <font color="#008000">TryURL()</font> closes and deletes the file. That block of code is shown in Listing 19.4.</P>
<P><I>Listing 19.4—QueryDlg.cpp—CQueryDlg::TryURL()</I></P>
<pre><font color="#008000"> if (file)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += "Connection established. \r\n";</font></pre>
<pre><font color="#008000"> CString line;</font></pre>
<pre><font color="#008000"> for (int i=0; i < 20 && file->ReadString(line); i++)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += line + "\r\n";</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> file->Close();</font></pre>
<pre><font color="#008000"> delete file;</font></pre>
<pre><font color="#008000"> }</font></pre>
<P>If the file could not be opened, a message to that effect is echoed onto <font color="#008000">m_out</font>:</P>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += "No server found there. \r\n";</font></pre>
<pre><font color="#008000"> }</font></pre>
<P>Then whether the file existed or not, a line of dashes is tacked onto <font color="#008000">m_out</font> to indicate the end of this attempt, and one last call to <font color="#008000">UpdateData(FALSE)</font> gets the new <font
color="#008000">m_out</font> onto the screen:</P>
<pre><font color="#008000"> m_out += "-------------------------\r\n";</font></pre>
<pre><font color="#008000"> UpdateData(FALSE);</font></pre>
<pre><font color="#008000">}</font></pre>
<P>You can now build and run this application. If you enter <B>microsoft.com</B> in the text box and click Query, you will discover that there are Web pages at both <B>http://microsoft.com</B> and <B>http://www.microsoft.com</B>. Figure 19.8 shows the
results of that query.</P>
<A HREF="Ufigs08.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch19/Ufigs08.gif"><b>Fig. 19.8</b></A>
<P><I>Query can find Microsoft's Web sites.</I></P>
<P>If Query doesn't find Web pages at either the domain name you provided or <B>www.</B> plus the domain name, it doesn't mean that the domain doesn't exist or even that the organization that owns the domain name doesn't have a Web page. It does make it
less likely, however, that the organization both exists and has a Web page. If you see a stream of HTML, then you know for certain that the organization exists and has a Web page. You may be able to read the HTML yourself, but even if you cannot, you can
now connect to the site with a Web browser such as Microsoft's Internet Explorer.</P>
<H3><B>Querying FTP Sites</B></H3>
<P>As part of an investigation of a site name, you should check to see if there is an FTP site, too. Most FTP sites have names like <B>ftp.company.com</B>, though some older sites do not have names of that form. Checking for these sites is not as simple
as just calling <font color="#008000">TryURL()</font> again, because <font color="#008000">TryURL()</font> assumes that the URL leads to a file, and URLs like <B>ftp.greatidea.org</B> lead to a list of files that cannot simply be opened and read. Rather
than making <font color="#008000">TryURL()</font> even more complicated, add a function to the class called <font color="#008000">TryFTPSite(CString host)</font>. (Right-click <font color="#008000">CQueryDlg</font> in the ClassView and choose Add Function
to add the function. It can return <font color="#008000">void</font>.)</P>
<p><font color="#008000">TryFTPSite()</font> has to establish a connection within the session, and if the connection is established, it has to get some information that can be added to <font color="#008000">m_out</font> to show the user that the
connection has been made. Getting a list of files is reasonably complex, so because this is just an illustrative application, the simpler task of getting the name of the default FTP directory is the way to go. The code is in Listing 19.5.</P>
<P><I>Listing 19.5—QueryDlg.cpp—CQueryDlg::TryFTPSite()</I></P>
<pre><font color="#008000">void CQueryDlg::TryFTPSite(CString host)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CInternetSession session;</font></pre>
<pre><font color="#008000"> m_out += "Trying FTP site " + host + "\r\n";</font></pre>
<pre><font color="#008000"> UpdateData(FALSE);</font></pre>
<pre><font color="#008000"> CFtpConnection* connection = NULL;</font></pre>
<pre><font color="#008000"> try</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> connection = session.GetFtpConnection(host);</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> catch (CInternetException* pEx)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> //if anything went wrong, just set connection to NULL</font></pre>
<pre><font color="#008000"> connection = NULL;</font></pre>
<pre><font color="#008000"> pEx->Delete();</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> if (connection)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += "Connection established. \r\n";</font></pre>
<pre><font color="#008000"> CString line;</font></pre>
<pre><font color="#008000"> connection->GetCurrentDirectory(line);</font></pre>
<pre><font color="#008000"> m_out += "default directory is " + line + "\r\n";</font></pre>
<pre><font color="#008000"> connection->Close();</font></pre>
<pre><font color="#008000"> delete connection;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_out += "No server found there. \r\n";</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> m_out += "-------------------------\r\n";</font></pre>
<pre><font color="#008000"> UpdateData(FALSE);</font></pre>
<pre><font color="#008000">}</font></pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -