⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtl for mfc programmers, part ix - gdi classes, common dialogs, and utility classes - wtl.htm

📁 MFC程序员的WTL指南,非常具体,WTL入门最好的书
💻 HTM
📖 第 1 页 / 共 4 页
字号:
    还多了了一些额外的特性,这些特性在你使用<CODE>_ATL_MIN_CRT方式编译代码的时候就显得十分有用,比如,</CODE><CODE>_cstrchr() 
    和 </CODE><CODE>_cstrstr()函数。</CODE><CODE>当不使用_ATL_MIN_CRT方式编译时它们会被相应的CRT函数取代,不会产生额外的代码</CODE>。(译者注:<code>使用_ATL_MIN_CRT方式编译是为了减少对CRT库的依赖,从而产生较小的可执行文件,不过这样就不能使用很多CRT的标准函数,比如strstr、strchr等等,在这种情况下WTL的CString会使用自己的函数代替,从而保证CString能够正常工作,当不使用_ATL_MIN_CRT方式时,CString会直接调用CRT库函数</code>)</P>
  <H4>CFindFile</H4>
  <P><CODE>CFindFile</CODE> <CODE>封装了FindFirstFile()和F</CODE><CODE>indNextFile()</CODE> 
    APIs,它比MFC<CODE>的CFileFind还要容易使用一些,使用方式可以参考下面的模式:</CODE></P>
  <PRE><font color="#0000FF">CFindFile finder;
CString sPattern = _T(<SPAN class=cpp-string>"C:\\windows\\*.exe"</SPAN>);
 
  <SPAN class=cpp-keyword>if</SPAN> ( finder.FindFirstFile ( sPattern ) )
    {
    <SPAN class=cpp-keyword>do</SPAN>
      {
      <SPAN class=cpp-comment>// act on the file that was found</SPAN>
      }
    <SPAN class=cpp-keyword>while</SPAN> ( finder.FindNextFile() );
    }
 
  finder.Close();</font></PRE>
  <P><CODE>如果FindFirstFile()</CODE> 返回<CODE>t<SPAN 
      class=cpp-keyword>rue,就表示至少有一个文件匹配查找模式,在循环内,你可以访问</SPAN></CODE><CODE>CFindFile</CODE> 
    的公有成员<CODE>m_fd,这是一个</CODE><CODE>WIN32_FIND_DATA</CODE> 数据结构,包含了这个文件的信息,循环可以一直继续直到<CODE>FindNextFile()</CODE> 
    返回<CODE><SPAN 
      class=cpp-keyword>false,这表示你已经把所有的文件遍历了一遍。</SPAN></CODE></P>
  <P><CODE>为了使用方便,CFindFile</CODE> 还提供了一些操作<CODE>m_fd</CODE>的函数,这些函数的返回值只在<CODE>成功调用了FindFirstFile或</CODE><CODE>FindNextFile()之后才有意义。</CODE></P>
  <PRE><font color="#0000FF">ULONGLONG GetFileSize()</font></PRE>
  <P>返回文件的大小,数据类型时64位无符号整形数。</P>
  <PRE><font color="#0000FF">BOOL GetFileName(LPTSTR lpstrFileName, <SPAN class=cpp-keyword>int</SPAN> cchLength)
CString GetFileName()</font></PRE>
  <P>得到查找到文件的名字和扩展名(<CODE>从m_fd.cFileName复制数据</CODE>)。</P>
  <PRE><font color="#0000FF">BOOL GetFilePath(LPTSTR lpstrFilePath, <SPAN class=cpp-keyword>int</SPAN> cchLength)
CString GetFilePath()</font></PRE>
  <P>返回查找到文件的全路径。</P>
  <PRE><font color="#0000FF">BOOL GetFileTitle(LPTSTR lpstrFileTitle, <SPAN class=cpp-keyword>int</SPAN> cchLength)
CString GetFileTitle()</font></PRE>
  <P>返回文件的标题 (就是没有扩展名)。</P>
  <PRE><font color="#0000FF">BOOL GetFileURL(LPTSTR lpstrFileURL, <SPAN class=cpp-keyword>int</SPAN> cchLength)
CString GetFileURL()</font></PRE>
  <P>创建一个<CODE>file:<SPAN class=cpp-comment>//</SPAN></CODE> URL,包含文件的全路径。(译者注:比如“file://d:\doc\sss.doc”)</P>
  <PRE><font color="#0000FF">BOOL GetRoot(LPTSTR lpstrRoot, <SPAN class=cpp-keyword>int</SPAN> cchLength)
CString GetRoot()</font></PRE>
  <P>得到文件所在的目录。</P>
  <PRE><font color="#0000FF">BOOL GetLastWriteTime(FILETIME* pTimeStamp)
BOOL GetLastAccessTime(FILETIME* pTimeStamp)
BOOL GetCreationTime(FILETIME* pTimeStamp)</font></PRE>
  <P><CODE>这些函数从m_fd的数据成员ftLastWriteTime、</CODE><CODE>ftLastAccessTime和</CODE><CODE>ftCreationTime</CODE> 
    复制数据。</P>
  <P><CODE>CFindFile</CODE> 还有一些辅助函数用于检查文件的属性。</P>
  <PRE><font color="#0000FF">BOOL IsDots()</font></PRE>
  <P>如果文件是"<CODE>.</CODE>" 或 "<CODE>..</CODE>" 目录就返回true。</P>
  <PRE><font color="#0000FF">BOOL MatchesMask(DWORD dwMask)</font></PRE>
  <P>将文件的属性和<CODE>dwMask</CODE> (<CODE>通常是一些FILE_ATTRIBUTE_*</CODE> 属性的组合)比较,看看查找到的文件是是否有指定的属性如果文件属性包含dwMask指定的位掩码,就返回true。</P>
  <PRE><font color="#0000FF">BOOL IsReadOnly()
BOOL IsDirectory()
BOOL IsCompressed()
BOOL IsSystem()
BOOL IsHidden()
BOOL IsTemporary()
BOOL IsNormal()
BOOL IsArchived()</font></PRE>
  <P><CODE>这些函数是MatchesMask()</CODE> 函数的更直观的替代者,它们通常只是测试属性中的某一个,比如,<CODE>IsReadOnly()</CODE> 
    就是调用<CODE>MatchesMask(FILE_ATTRIBUTE_READONLY)。</CODE></P>
  <H3><A name=globalfuncs></A><font color="#FFFF66">全局函数</font></H3>
  WTL 还有一些很有用的全局函数,比如检查 DLL 版本或者显示一个消息框窗口。</P> 
  <PRE><font color="#0000FF"><SPAN class=cpp-keyword>bool</SPAN> AtlIsOldWindows()</font></PRE>
  <P>判断Windows的版本是否太老,如果是Windows 95、 98、 NT 3 或 NT 4这样的系统就会返回true。</P>
  <PRE><font color="#0000FF">HFONT AtlGetDefaultGuiFont()</font></PRE>
  <P><CODE>返回值和调用GetStockObject(DEFAULT_GUI_FONT)的返回值相同,在英文版的</CODE> Windows 2000 
    或更新的版本 (也包括一些使用拉丁字母的单字节语言)中,这个字库的名字(face name)是“MS Shell Dlg”。这(种字体)对于对话框效果很好,但是如果你要在界面上创建自己的字体,这就不是一个很好的选择。MS 
    Shell Dlg 就是 MS Sans Serif的别名, 而不是使用新字体Tahoma。 要避免使用MS Sans Serif,你可以通过消息框得到字体:</P>
  <PRE><font color="#0000FF">NONCLIENTMETRICS ncm = { <SPAN class=cpp-keyword>sizeof</SPAN>(NONCLIENTMETRICS) };
CFont font;
 
  <SPAN class=cpp-keyword>if</SPAN> ( SystemParametersInfo ( SPI_GETNONCLIENTMETRICS, <SPAN class=cpp-literal>0</SPAN>, &amp;ncm, <SPAN class=cpp-keyword>false</SPAN> ) )
    font.CreateFontIndirect ( &amp;ncm.lfMessageFont );</font></PRE>
  <P>另一种方法是检查<CODE>AtlGetDefaultGuiFont()返回的字体名称,如果是“</CODE>MS Shell Dlg”就将其改成“MS 
    Shell Dlg 2”,它将使用新字体 Tahoma。</P>
  <PRE><font color="#0000FF">HFONT AtlCreateBoldFont(HFONT hFont = NULL)</font></PRE>
  <P>创建指定字体的加粗版本,<CODE>如果hFont</CODE> 是 NULL,<CODE>AtlCreateBoldFont()</CODE> 
    就创建一个通过<CODE>AtlGetDefaultGuiFont()</CODE>得到的字体的加粗版本。</P>
  <PRE><font color="#0000FF">BOOL AtlInitCommonControls(DWORD dwFlags)</font></PRE>
  <P><CODE>这是对InitCommonControlsEx()</CODE> API的封装,使用一些指定的标志初始化<CODE>INITCOMMONCONTROLSEX</CODE> 
    结构,然后调用<code>InitCommonControlsEx()</code>。</P>
  <PRE><font color="#0000FF">HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)</font></PRE>
  <P>这两个函数在指定的模块种查找名为<CODE>DllGetVersion()的导出函数,如果函数存在就调用这个函数,如果调用成功就返回一个</CODE><CODE>DLLVERSIONINFO</CODE>结构的版本信息。</P>
  <PRE><font color="#0000FF">HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)</font></PRE>
  <P>返回comctl32.dll的主版本号和次版本号。</P>
  <PRE><font color="#0000FF">HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)</font></PRE>
  <P>返回shell32.dll的主版本号和次版本号。</P>
  <PRE><font color="#0000FF"><SPAN class=cpp-keyword>bool</SPAN> AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, <SPAN class=cpp-keyword>int</SPAN> cchLen)</font></PRE>
  <P>将一个文件名截断,从而使其长度小于<CODE>cchLen</CODE>,在结尾添加省略号,它和<CODE>shlwapi.dll中的PathCompactPath()</CODE> 
    <code>和</code> <CODE>PathSetDlgItemPath()</CODE> 功能相似。</P>
  <PRE><font color="#0000FF"><SPAN class=cpp-keyword>int</SPAN> AtlMessageBox(HWND hWndOwner, _U_STRINGorID message,
                  _U_STRINGorID title = NULL,
                  UINT uType = MB_OK | MB_ICONINFORMATION)</font></PRE>
  <P><CODE>和MessageBox()</CODE>一样,显示一个消息框,但是使用了<CODE>_U_STRINGorID</CODE> 参数,这样你就可以传递字符串资源ID作为参数,<CODE>AtlMessageBox()</CODE> 
    会自动装载字符串资源。</P>
  <H3><A name=macros></A><font color="#FFFF66">宏</font></H3>
  <P>在WTL 的头文件中你会看到各种各样的预处理宏,大多数的宏都可以在编译选项中设置,从而改变WTL代码的某些行为。</P>
  <P>以下几个宏与编译设置紧密相关,在WTL的代码中到处都有它们的身影:</P>
  <DL>
    <DT><CODE>_WTL_VER</CODE> 
    <DD>对于 WTL 7.1 被定义为 0x0710。 
    <DT><CODE>_ATL_MIN_CRT</CODE> 
    <DD>如果这个宏被定义了,ATL将不链接C标准库,由于很多WTL的类(尤其是CString)都要使用C标准库函数,很多特殊的代码被编译进来以代替CRT函数。 
    <DT><CODE>_ATL_VER</CODE> 
    <DD>对于VC6,这个版本是<CODE><SPAN class=cpp-literal>0x0300</SPAN></CODE>,对于VC7,这个版本是<CODE><SPAN class=cpp-literal>0x0700</SPAN></CODE> 
      ,对于VC8,这个版本是 0x0800。 
    <DT><CODE>_WIN32_WCE</CODE> 
    <DD>是否编译的是 Windows CE 二进制映象,一些WTL代码因为Windows CE不支持相应的特性而不可用。</DD>
  </DL>
  <P>下面的宏默认是不定义的,要使用它们需要在<CODE></CODE><I>stdafx.h</I><code>文件中所有<span class=cpp-preprocessor>#include语句之前定义它们。</span></code></P>
  <DL>
    <DT><CODE>_ATL_NO_OLD_NAMES</CODE> 
    <DD>这个宏只在维护WTL 3的代码时起作用,它增加了很多编译检测用于识别两个老的类名和函数名:<CODE>CUpdateUIObject</CODE> 
      已经改名为 <CODE>CIdleHandler,</CODE><CODE>DoUpdate()也改名为</CODE><CODE>OnIdle()</CODE>。 
    <DT><CODE>_ATL_USE_CSTRING_FLOAT</CODE> 
    <DD>定义这个标号可以使<CODE>CString支持浮点运算,它不能和</CODE><CODE>_ATL_MIN_CRT一起使用,如果想在 <code>CString::Format()</code>函数中使用%I64格式,就必须定义这个选项。如果定义了</CODE><CODE>_ATL_USE_CSTRING_FLOAT</CODE> 
      标号,<CODE>CString::Format()</CODE> <CODE>将调用_vstprintf()</CODE>,这个函数能够识别<CODE>%I64</CODE> 
      格式。 
    <DT><CODE>_ATL_USE_DDX_FLOAT</CODE> 
    <DD>定义这个标号可以使 DDX 代码支持浮点运算<CODE>,它不能和_ATL_MIN_CRT同时使用。</CODE> 
    <DT><CODE>_ATL_NO_MSIMG</CODE> 
    <DD>定义这个标号将使编译器忽略<CODE><SPAN 
        class=cpp-preprocessor>#pragma comment(lib, "msimg32")</SPAN></CODE> 代码行,也就是禁止<CODE>CDCT</CODE> 
      使用 msimg32 函数: <CODE>AlphaBlend()、</CODE><CODE>TransparentBlt()和</CODE><CODE>GradientFill()。</CODE> 
    <DT><CODE>_ATL_NO_OPENGL</CODE> 
    <DD>定义这个标号编译器将忽略<CODE><SPAN 
        class=cpp-preprocessor>#pragma comment(lib, "opengl32")</SPAN></CODE> 
      代码行,也就是禁止<CODE>CDCT</CODE> 使用 OpenGL。 
    <DT><CODE>_WTL_FORWARD_DECLARE_CSTRING</CODE> 
    <DD>已经废弃,使用<CODE>_WTL_USE_CSTRING</CODE> <code>代替。</code> 
    <DT><CODE>_WTL_USE_CSTRING</CODE> 
    <dd>定义这个标号将向前声明<CODE>CString</CODE>类,这样,那些在<I>atlmisc.h</I> 文件之前包含的头文件也可以使用<CODE>CString。</CODE></dd>
    <DT><CODE>_WTL_NO_CSTRING</CODE> 
    <DD>定义这个标号将不能使用<CODE>WTL::CString。</CODE> 
    <DT><CODE>_WTL_NO_AUTOMATIC_NAMESPACE</CODE> 
    <DD>定义这个标号将阻止直接使用WTL命名空间(<code><span class=cpp-keyword>namespace</span></code>)<CODE>。</CODE> 
    <DT><CODE>_WTL_NO_AUTO_THEME</CODE> 
    <DD><CODE>定义这个标号阻止CMDICommandBarCtrlImpl</CODE> 使用 XP 主题。 
    <DT><CODE>_WTL_NEW_PAGE_NOTIFY_HANDLERS</CODE> 
    <DD>定义这个标号可以在<code>CPropertyPage</code>中使用较新的<CODE>PSN_*</CODE> 通知消息响应函数,因为老的WTL 
      3的消息响应函数已经废弃掉了,这个标号应该总是被定义,除非你是在维护老的WTL3 代码。 
    <DT><CODE>_WTL_NO_WTYPES</CODE> 
    <DD>定义这个标号将禁止使用WTL封装的<CODE>CSize、</CODE><CODE>CPoint和</CODE><CODE>CRect</CODE>类。 
    <DT><CODE>_WTL_NO_THEME_DELAYLOAD</CODE> 
    <DD>在VC6中编译代码时,定义这个标号将阻止<I>uxtheme.dll</I> 被自动标记为延时加载。</DD>
  </DL>
  <P>注意: 如果<CODE>_WTL_USE_CSTRING</CODE> <CODE>和_WTL_NO_CSTRING</CODE> 同时定义,产生的结果就只能在<I>atlmisc.h</I> 
    文件包含之后使用CString。</P>
  <H2><A name=samplecode></A><font color="#FFFF66">例子工程</font></H2>
  <P>本文的演示工程是一个下载工具,这个名为Kibbles的下载工具演示了几个本文介绍的类。这个下载工具使用了BITS(<a 
      href="http://msdn.microsoft.com/library/en-us/bits/bits/bits_start_page.asp">background 
    intelligent transfer service</a>)组件,Windows 2000及其以后的操作系统都支持这个组件,也就是说这个程序只能运行在基于NT技术的操作系统上,所以我就将其创建成了Unicode工程。</P>
  <P>这个程序有一个视图窗口,这个视图窗口用来显示下载过程,它使用了很多GDI函数,也包括专门画饼图的Pie()函数。第一次运行时,程序的初始界面是这样的:</P>
  <input name="imageField" type="image" src="images/kibbles0.png" width="387" height="430" border="0">
  <br>
  <br>
  <P>你可以从浏览器中拖一个链接到这个窗口中,程序会创建一个新的BITS并将链接指定的目标下载到“我的文档”文件夹。当然也可以单击工具栏上第三个按钮直接添加一个URL,工具栏上的第四个按钮则允许你修改默认的下载文件存放位置。</P>
  <P>当一个下载任务正在进行,Kibbles会显示一些下载任务的细节,下载的过程显示如下:<br>
    <br>
    <img src="images/kibbles1.png" width="387" height="430"> <br>
    <br>
    工具栏上的前两个按钮用来修改过程显示的颜色,第一个按钮会打开一个选项对话框,在选项对话框中可以设置过程饼图中各部分的颜色:</P>
  <img src="images/choosecolors.png" width="359" height="216"><br>
  <br>
  <P>对话框中使用了Tim Smith的文章“<A 
      href="http://www.codeproject.com/wtl/wtlcolorbutton.asp">Color Picker for 
    WTL with XP themes</A>”中介绍的一个很棒的按钮类,可以查看<CODE>Kibbles工程中的CChooseColorsDlg</CODE> 
    类的代码了解这个按钮类是如何工作的。<I>“Text color”</I> 按钮是一个普通的按钮,它的响应函数<CODE>OnChooseTextColor()演示了如何使用WTL的</CODE><CODE>CColorDialog类。第二个工具栏按钮的功能是使用随即颜色显示下载过程</CODE>。</P>
  <P>第五个工具栏按钮用来设置背景图片,Kibbles使用这个图片在饼图上显示下载过程。默认的图片程序资源中包含的一个图片,你也可以选择任何BMP位图文件作为背景图片:</P>
  <img src="images/kibbles2.png" width="387" height="430"><br>
  <br>
  <P><CODE>CMainFrame::OnToolbarDropdown()</CODE> 的代码响应按钮的press事件并显示一个弹出式菜单,这个函数还使用了<CODE>CFindFile</CODE> 
    类遍历“我的文档”文件夹。关于各种GDI函数的用法可以查看<CODE>CKibblesView::OnPaint()函数的代码。</CODE></P>
  <P>关于工具栏有一点需要特别注意:这个工具栏使用了256色的位图,不过VC的工具栏编辑器只支持16色位图,如果你使用工具栏编辑器修改过工具栏位图,你的工具栏位图就会被转换成16色。我的建议是,在另一个目录中保存这个高彩色的位图,使用图像编辑工具直接编辑这个图片,然后在“res”目录中另存一个256色的版本。<br>
  </P>
  <H2><a name=copying></a><font color="#FFFF66">版权和许可协议</font></H2>
  <P>这篇文章受版权保护, (c)2006 by Michael Dunn。我知道不能阻止人们通过网络拷贝这些文章,但是我必须要说的是,如果你有兴趣翻译本系列文章,请一定让我知道(汗....,还好翻译第一篇之前给Michael发了一封邮件),我不会拒绝你的翻译请求,我只是想知道我的文章被翻译了几个版本,这样我可以在这里给出相应版本的链接。</P>
  <P>有两个文件除外,就是<I>ColorButton.cpp</I> 和 <I>ColorButton.h</I>,这篇文章附带的演示代码是向所有人公开的,这样每个人都可以从代码中受益。 
    (我不让文章也向所有人(版权)公开是因为这样能够提高我自己和CodeProject网站的知名度(%……¥%¥#%¥#晕)。) 如果你的程序中使用了我的演示代码,最好能给我发个Email,当然这不是强制要求,只是为了满足我的一点好奇心,我想知道是否有人从我的代码中受益。</P>
  <P><I>文件ColorButton.cpp</I> 和 <I>ColorButton.h</I> 来自Tim Smith的文章“<A 
      href="http://www.codeproject.com/wtl/wtlcolorbutton.asp">Color Picker for 
    WTL with XP themes</A>”,它们不包含在上面的许可声明中,它们的许可声明包含在文件的注释部分。</P>
  <H2><A name=revisionhistory></A><font color="#FFFF42">修订历史</font></H2>
  <P>2006年2月8日,第一次发布。</P>
  <P>&nbsp;</P>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -