﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Code Knight-随笔分类-GUI</title><link>http://www.cppblog.com/winmain/category/12308.html</link><description>Programming is so cool</description><language>zh-cn</language><lastBuildDate>Sat, 06 Mar 2010 14:22:12 GMT</lastBuildDate><pubDate>Sat, 06 Mar 2010 14:22:12 GMT</pubDate><ttl>60</ttl><item><title>[转]GUI库比较一图通</title><link>http://www.cppblog.com/winmain/archive/2010/03/02/108735.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 02 Mar 2010 11:57:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/03/02/108735.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108735.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/03/02/108735.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108735.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108735.html</trackback:ping><description><![CDATA[原帖：<a href="http://www.cppblog.com/lingjingqiu/archive/2009/01/06/71363.html">http://www.cppblog.com/lingjingqiu/archive/2009/01/06/71363.html</a><br>
<table style="WIDTH: 1029px; HEIGHT: 1706px" border=1>
    <tbody>
        <tr>
            <td style="FONT-SIZE: 10pt">界面库名称<br></td>
            <td style="VERTICAL-ALIGN: top">接口设计<br></td>
            <td style="VERTICAL-ALIGN: top">界面编辑器<br></td>
            <td style="VERTICAL-ALIGN: top">高级布局功能<br></td>
            <td style="VERTICAL-ALIGN: top">平面绘制<br></td>
            <td style="VERTICAL-ALIGN: top">平台兼容性<br></td>
            <td style="VERTICAL-ALIGN: top">语言支持<br></td>
            <td style="VERTICAL-ALIGN: top">IDE兼容性<br></td>
            <td style="VERTICAL-ALIGN: top">视图-模型分离机制<br></td>
            <td style="VERTICAL-ALIGN: top">运行时<br></td>
            <td style="VERTICAL-ALIGN: top">其它<br></td>
        </tr>
        <tr>
            <td>Windows Forms<br></td>
            <td style="VERTICAL-ALIGN: top">接口优秀。C++下使用CLI扩展，其它语言为原生支持。<br></td>
            <td style="VERTICAL-ALIGN: top">界面编辑器完整，包括布局、属性、消息关联的完整设置。不可预览。<br></td>
            <td style="VERTICAL-ALIGN: top">Table Layout，Splitter Layout，Flow Layout等，Anchor和Dock机制。多分辨率界面下表现良好。<br></td>
            <td style="VERTICAL-ALIGN: top">GDI+，面向对象的2D绘制接口，使用简便。<br></td>
            <td style="VERTICAL-ALIGN: top">需要.Net平台支持。WIndows或Linux（Mono，非官方支持），支持Windows CE<br></td>
            <td style="VERTICAL-ALIGN: top">C++/CLI, 支持.net的语言。<br></td>
            <td style="VERTICAL-ALIGN: top">仅VS。<br></td>
            <td style="VERTICAL-ALIGN: top">布局和视图方案建立在代码中。部分组件支持Model-View架构。<br></td>
            <td style="VERTICAL-ALIGN: top">需要部署对应的.net<br></td>
            <td style="VERTICAL-ALIGN: top">商业协议<br></td>
        </tr>
        <tr>
            <td style="VERTICAL-ALIGN: top">MFC<br></td>
            <td style="VERTICAL-ALIGN: top">基于宏和虚函数，使用特殊格式注释，使用自定义的RTTI系统。类接口设计优良。通过回调函数和虚继承重载调用客户代码。<br></td>
            <td style="VERTICAL-ALIGN: top">基于资源编辑器，仅能对空间基本布局和少量属性进行调整。不可预览。<br></td>
            <td style="VERTICAL-ALIGN: top">缺乏高级布局功能，多分辨率需要是手工或程序中调整。<br></td>
            <td style="VERTICAL-ALIGN: top">GDI及GDI封装，可选GDI+<br></td>
            <td style="VERTICAL-ALIGN: top">Windows，Windows CE<br></td>
            <td style="VERTICAL-ALIGN: top">C++ Only，<br>支持COM时可以实现Binary级别复用。<br></td>
            <td style="VERTICAL-ALIGN: top">仅Visual Studio<br></td>
            <td style="VERTICAL-ALIGN: top">使用资源保存控件的基本控件布局，提供Doc-View机制和控件数据交换支持视图分离。<br></td>
            <td style="VERTICAL-ALIGN: top">需要部署MFC运行时库。<br></td>
            <td style="VERTICAL-ALIGN: top">商业协议<br></td>
        </tr>
        <tr>
            <td style="VERTICAL-ALIGN: top">WTL<br></td>
            <td style="VERTICAL-ALIGN: top">基于模板和虚函数。类接口类似于MFC。需要使用多重继承。通过模板特化和回调函数与客户代码交互。<br></td>
            <td style="VERTICAL-ALIGN: top">同MFC<br></td>
            <td style="VERTICAL-ALIGN: top">同MFC<br></td>
            <td style="VERTICAL-ALIGN: top">同MFC<br></td>
            <td style="VERTICAL-ALIGN: top">同MFC<br></td>
            <td style="VERTICAL-ALIGN: top">同MFC，对COM的支持比MFC完善很多。<br></td>
            <td style="VERTICAL-ALIGN: top">Visual Studio，Windows下支持标准的C++编译器。<br></td>
            <td style="VERTICAL-ALIGN: top">使用资源文件保存空间布局。<br></td>
            <td style="VERTICAL-ALIGN: top">无<br></td>
            <td style="VERTICAL-ALIGN: top">自由协议<br></td>
        </tr>
        <tr>
            <td style="VERTICAL-ALIGN: top">wxWidget<br></td>
            <td style="VERTICAL-ALIGN: top">宏，自定义RTTI。使用回调函数与用户代码交互。<br></td>
            <td style="VERTICAL-ALIGN: top">无官方界面编辑器。可使用第三方界面编辑器。部分编辑器具有完整的所见即所得功能，且具有预览能力。<br></td>
            <td style="VERTICAL-ALIGN: top">使用Sizer实现多分辨率的布局。功能偏弱。<br></td>
            <td style="VERTICAL-ALIGN: top">wxDC等。<br></td>
            <td style="VERTICAL-ALIGN: top">Windows，Linux，Unix，MacOS等<br></td>
            <td style="VERTICAL-ALIGN: top">C++, .NET, Python,<br>Lua,<br>Ruby等<br></td>
            <td style="VERTICAL-ALIGN: top">良好的编译器兼容性，缺乏IDE继承。<br></td>
            <td style="VERTICAL-ALIGN: top">可以将界面属性生成到代码中，也可以使用XML格式保存。<br></td>
            <td style="VERTICAL-ALIGN: top">wx的动态链接库或静态链接。<br></td>
            <td style="VERTICAL-ALIGN: top">自由协议<br></td>
        </tr>
        <tr>
            <td style="VERTICAL-ALIGN: top">Qt<br></td>
            <td style="VERTICAL-ALIGN: top">使用宏和自定义的RTTI。使用Singal-Slot机制实现用户代码交互。可通过继承实现扩展。<br></td>
            <td style="VERTICAL-ALIGN: top">Qt Designer，具备完整的所见即所得编辑功能。可预览界面。<br></td>
            <td style="VERTICAL-ALIGN: top">具备完整的布局功能。多分辨率/多平台下表现良好。<br></td>
            <td style="VERTICAL-ALIGN: top">QCanvas等。<br></td>
            <td style="VERTICAL-ALIGN: top">Windows，Linux，Unix，MacOS等。<br></td>
            <td style="VERTICAL-ALIGN: top">C++，Python等<br></td>
            <td style="VERTICAL-ALIGN: top">可集成到Eclipse和VS<br></td>
            <td style="VERTICAL-ALIGN: top">使用资源文件保存界面信息。部分组件具备Model-View-Delegate架构<br></td>
            <td style="VERTICAL-ALIGN: top">qt的动态链接库。<br></td>
            <td style="VERTICAL-ALIGN: top">开源协议+商业协议<br></td>
        </tr>
        <tr>
            <td style="VERTICAL-ALIGN: top">GTK+<br></td>
            <td style="VERTICAL-ALIGN: top">使用signal-slot机制完成用户代码交互。<br></td>
            <td style="VERTICAL-ALIGN: top">GLADE，具备所见即所得的界面编辑功能<br></td>
            <td style="VERTICAL-ALIGN: top">Layout Containers，具备较完整的布局能力。<br></td>
            <td style="VERTICAL-ALIGN: top">GTK Graphics Context<br></td>
            <td style="VERTICAL-ALIGN: top">Windows，Linux，Unix，MacOS等。</td>
            <td style="VERTICAL-ALIGN: top">C，C++，Python，.NET等。<br></td>
            <td style="VERTICAL-ALIGN: top">（暂时未知）<br></td>
            <td style="VERTICAL-ALIGN: top">使用代码完成界面设置。部分组件具备Model-View架构。<br></td>
            <td style="VERTICAL-ALIGN: top">GTK Runtime<br></td>
            <td style="VERTICAL-ALIGN: top">开源协议<br></td>
        </tr>
    </tbody>
</table>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-01-06 19:05 qtopia <br>Nokia 最近推了 Qt Creator，是较好的IDE环境&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-01-06 19:05 t <br>博主还可以增加一栏&#8220;国际化支持&#8221;&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较[未登录] 2009-01-08 12:48 kenlistian <br>我觉得wxwidget是不错的选择。&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-01-11 20:25 www <br>wxwidget做简单的还可以, 做复杂的界面,嘿嘿,那就麻烦了. win下还是MFC最爽.&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-01-19 00:49 ArenAK <br>有没有哪一个是作者比较喜欢用的呢，及其原因？&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较[未登录] 2009-01-19 16:35 六水 <br>写的好~&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-02-05 11:08 空明流转 <br>@六水<br>我就知道你是友情赞助的。。。&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较[未登录] 2009-02-11 22:35 六水 <br>这你也知道？&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-02-25 10:19 aladdina <br>wxWidgets的代码质量不是很高，有一些比较初级的bug。我用过一段时间的wxWidgets，自己测试没问题，但是用户总会发回一些crash report。</p>
<p>另外，wxWidgets和Qt除了对于一些常见应用，比如窗口、DC的封装之外，还提供了很多系统接口的封装，比如clipboard, thread, socket等。</p>
<p>Qt有Qt Creator作为IDE，工程项目文件可以跨平台，另外，工程文件也可以用qmake转成平台无关的makefile。准备最近有空试试Qt，个人觉得商业代码质量还是要稍微好一些。</p>
<p>&nbsp; 回复&nbsp; 更多评论 <br>&nbsp;&nbsp; </p>
<p><br># re: C++下Windows Forms + MFC + WTL + wxWidgets + Qt + GTK+ 非官方综合比较 2009-09-18 12:09 idol <br>gtk 哪有 signal-slot机制，用的明明是 callbacks&nbsp; 回复&nbsp; 更多评论 </p>
<img src ="http://www.cppblog.com/winmain/aggbug/108735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-03-02 19:57 <a href="http://www.cppblog.com/winmain/archive/2010/03/02/108735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]游戏中的点阵字体和TrueType字体</title><link>http://www.cppblog.com/winmain/archive/2010/02/28/108626.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sun, 28 Feb 2010 12:19:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/28/108626.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108626.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/28/108626.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108626.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108626.html</trackback:ping><description><![CDATA[<p><span style="FONT-SIZE: 12pt"><font size=2>点阵字库<br>　　包括现在，有很多游戏都还是使用的点阵字库。因为操作起来比较方便，加上这方面的经验已经积累了好几年了。通常如果只是一种字体就可以满足需要的话，它会是一个比较好、快的解决办法。但是它有3个缺点:<br>1. 如果放大显示，不做处理的话，显示出来的汉字，是很难看的。<br>2. 像是UCDOS所提供的点阵字库，只有24点阵的有几种字体，如：宋体、黑体、揩体&#8230;，而16点阵的好象就只有宋体一种。<br>3. 点阵字库，通常是有版权的，尤其是第三方制作的汉字库（如：方正）。<br>　　在这样的情况下，当我们写好这样的一个显示函数，就算是解决了如：放大、快速显示等问题的话，可供选择的字体还是太过于局限了。所以，在字体的要求比较强的情况下，点阵字库并不是一个好的解决方法，他不够灵活。尽管我们对于它的操作是如此得熟练，可以写出优美的代码来展示我们的编程技巧。</font></span></p>
<p><br><font size=2>TTF<br>　　TTF是True Type Font的简称。在Windows\Fonts目录下面，我们可以看到许多后缀为ttf的文件，它就是接下来我们接下来所要谈到的。<br>　　TTF是一种矢量字库。我们经常可以听到矢量这个词，像是FLASH中的矢量图形，在100*100分辨率下制作的flash，就算它放大为全屏，显示出的画面也不会出现马赛克。所谓矢量，其实说白了就是用点和线来描述图形，这样，在图形需要放大的时候，只要把所有这个图形的点和线放大相应的倍数就可以了。而且，在网站上有很多的TTF字库可以下载，或者你可以去买一些专门的字库光盘。然后在你发行你精心制作的游戏时，可以顺便捎上这些后缀为.ttf 的文件就行了。包括Quake这样的惊世之作，也都是用的TTF字库。<br>　　这样，我们就可以解决点阵汉字的一些问题。通过TTF，我们在字体的质量和字库的数量上获得了暂时性的胜利。</font></p>
<p><br><font size=2>字库的读取和显示<br>　　先前谈到点阵字库，只需要很简单的一些操作，就可以显示出想要的汉字。下面我给出一个读取hzk16的函数，它需要一个Surface以供显示用：<br>　　#include &lt;io.h&gt;<br>　　#include &lt;stdio.h&gt;<br>　　#include &lt;conio.h&gt;<br>　　<br>　　// 读取16x16<br>　　void DispHZ16(int x, int y, BYTE *Str, LPDIRECTDRAWSURFACE surf)<br>　　{<br>　　 const int Mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };<br>　　 FILE *HzkFp;<br>　　 WORD i, j, k=0, m;<br>　　 WORD HzNum;<br>　　 WORD QuHao;<br>　　 WORD WeiHao;<br>　　 long offset;<br>　　 BYTE dotBuffer[32]; <br>　　<br>　　 HzkFp = fopen("HZK16", "rb");<br>　　 <br>　　 HzNum = strlen((const char *)Str)/2;<br>　　<br>　　 DDSURFACEDESC ddsd;<br>　　 LPWORD lpSurface;<br>　　 HRESULT ddrval;<br>　　 <br>　　 ddsd.dwSize = sizeof(ddsd);<br>　　 <br>　　 while((ddrval=surf-&gt;Lock(NULL, &amp;ddsd, 0, NULL))==DDERR_WASSTILLDRAWING);<br>　　 if(ddrval == DD_OK)<br>　　 lpSurface = (LPWORD)ddsd.lpSurface;<br>　　<br>　　 for(i = 0; i&lt;HzNum; i++)<br>　　 { <br>　　 QuHao = Str[i*2]-160;<br>　　 WeiHao = Str[i*2+1]-160;<br>　　<br>　　 offset = ((QuHao - 1) * 94 + (WeiHao-1))*32;<br>　　<br>　　 fseek(HzkFp, offset, SEEK_SET);<br>　　 fread(dotBuffer, 32, 1, HzkFp);<br>　　<br>　　 for(j=0;j&lt;16;j++) <br>　　 for(k=0;k&lt;2;k++) <br>　　 for(m=0;m&lt;8;m++) <br>　　 if(dotBuffer[j*2+k] &amp; Mask[m])<br>　　 {<br>　　 lpSurface[ddsd.lPitch*(y+j+1) + x+k*8+m] = 0x000000;<br>　　 }<br>　　 x+=16;<br>　　 }<br>　　<br>　　 surf-&gt;Unlock(NULL);<br>　　<br>　　 fclose(HzkFp);<br>　　}<br>　　其实原理很简单：<br>1. 打开字库<br>2. 计算字符串长度（这个函数只支持中文），并且Lock Surface<br>3. 依次计算出每个汉字所对应的区码和位码（汉字的第1个字节是区码，第2个字节就是位码），然后通过公式计算出这个汉字在字库中的偏移量：<br>offset = ((QuHao - 1) * 94 + (WeiHao-1))*32;<br>4. 读出一个32个字节的点阵<br>5. 绘制到Surface上<br>　　以上只是16＊16点阵字库的显示方法，24＊24的读取方法与之类似，大家可以参照相关资料来书写出自己的代码。<br>　　<br>　　如何显示TTF字库呢，有很多种手段，下面我按从简单到复杂的的顺序依次介绍:<br>1. 使用Windows API，也就是大家所熟悉的TextOut。通过它，还需要一个HDC（设备句柄），我们就可以随意地在屏幕任何地方显示出文字了。<br>2. 在http://www.freetype.org，有一个FreeType的免费库，而且是OpenSource的。它目前有2个版本：1.0和 2.0。其区别在于，1.0只能读取TTF格式的，而2.0支持更多的文件格式，在使用它之前请详细阅读所要遵循的Licence，以下是摘自 FreeType2.0对字库的支持列表：<br>o TrueType fonts (and collections) <br>o Type 1 fonts <br>o CID-keyed Type 1 fonts <br>o CFF fonts <br>o OpenType fonts (both TrueType and CFF variants) <br>o SFNT-based bitmap fonts <br>o X11 PCF fonts <br>o Windows FNT fonts <br>3. 自己研究TTF的格式，然后自己来操作。<br>晕<br>....... ╮╮ <br>　 　 \█/倒！ <br>　　　 ●<br>虽然我们想要把每一件事情都做好，但是也不是每一件事情都要亲历亲为。如果你非要这样，也行^____^，但是过不了多久，你就会陷入泥沼，到时候你会发现自己的热情正在慢慢被磨灭，什么叫做抓狂，相信你很快就会知道^_^。<br><br>在有多种选择可以取舍的情况下，我们需要考虑一下，对比一下各种解决方法的优劣。<br><br>　　在DirectDraw时代，我们都不自觉地喜欢上了GetDC，因为&#8230;&#8230;多方便啊。可是现在已经到了DirectX8.1时代了（我要使劲地摇那些还沉醉于DirectX7中，为如何在使用alpha时提升那可怜的1、2个fps的朋友们：醒醒，该起床了！），HDC已经被M$列为禁用品。怎么办呢？是的，你可能已经想到了，我们还一直保存着窗口的hWnd呢，可以通过它来得到hdc，从而调用那些需要hdc的API，可是，这样做是更为愚蠢的，这样对你是没有一点好处的，不信，你就试试吧。有一句话，请牢记：要想你的游戏有更快的速度的话，请不要再去碰HDC了。<br>　　我们非常清楚hdc是一个超慢的解决办法，它无法在我们的高速游戏中满60分及格。下面来看看FreeType，它更像是一个Service。它的解决方法是，先通过一系列的初始化和设置，告诉FreeType字体的名字和大小等，然后它会动态地申请一个Graphic，再把我们要显示的字画到这个 Graphic上，你还可以把它保存为tga格式。不过我们最终所想要的不是这个，所以可能我们还需要从这个Graphic上逐点读取或者用 CopyRect，然后再画到我们的画面上。其实它已经是很方便的了，可是需要你去学习如何配置和使用它，这是很花时间的一件事情，而且它最大的优点是可以跨平台，我们需要它吗？如果有一个更为简单的办法，像是如果Textout不是那么慢的话，就好了&#8230;&#8230;<br>　　在这里，顺便谈一下另2个字体显示类：ID3DXFont和CD3DFONT。可能早就有人会说怎么在上面的列表中没有它们？原因我会在下面慢慢地说明：<br>　　ID3DXFont，它存在于D3DX库中，一个现成的字体类，不过对于它的处理方法&#8230;&#8230;我实在不敢恭维，就引用一位大师所说的话来表达我的看法吧: 在内部实现中， ID3DXFont::DrawText()函数确实做了我上面讨论的工作，先建立一张GDI兼容的位图，把文本绘制到位图上，而后把位图拷贝到纹理贴图上去，最后把纹理渲染到屏幕上。这样你就聚齐了所有的龟速的原始GDI函数，还包括了一大堆的额外开销 — 最终，这个函数比原来GDI的DrawTextEx()函数要慢上超过六倍&#8230;&#8230;<br>　　CD3DFONT，是由M$在D3D的框架代码中提供。不过它只能显示英文，有很多朋友通过自己定制和修改这个类，来实现自己的中文显示。不过效果都不是很好。其实原理，跟ID3DXFont的方法差不多，不过处理方法要聪明了一点。</font></p>
<p><br><font size=2>分析与思考<br>　　那么我们应该怎么办呢？通常我们会幻想，如果可以像处理英文那样，把所有的汉字都保存在一张位图里，该有多好。这样，显示的速度就不是问题了，直接可以CopyRect上去。可是，这样可能吗？首先，必须每一种字体都要生成这样的一个巨型位图。而且据说在GB2312中，一共有6000多个汉字，就算是用16*16，oh my god，这个位图该有多大啊（据说会有2.5M^__^）！！！而且在DirectX8.1中，对于Texture（显示的最小单位，就好象是原来 DirectSurface的概念一样。说过多少遍了，不要再用DirectX8以前的东西了。不要试着去回忆那些美好的过去，我很明白，要你一下子放弃原来多年所获得的成就，是一件很痛苦的事情，但是包袱太重，是会影响进步的。就像是我们的国家&#8230;&#8230;扯远了），不同的显卡，支持的最大容量也是不同的。比方说早期的Voodoo，只支持256*256大小的Texture。而在我的显卡（Geforce2 MX 200）上测试，支持最大2048*2048大小的Texture。对于这样的硬件不确定性，我们只能取其最小值，也就是256*256。<br>　　汉字虽然很多，但是常用的汉字，其实也就只有那么几百个。像这样的字：鬯、鞴，你一辈子会看到多少次呢？如果可以做一个类似于Cache的东西，保存着常用的那些个汉字，在需要显示的的时候，先在Cache中查找，如果有的话，就马上画上去；如果没有，就从字库中提取到Cache中。这样的话，在使用 Texture来保存汉字的位图信息的同时，对于每个汉字，我们还要定义一个结构，然后用一个东西把它串起来，综合它们2个，也就实现了我们所要的 Cache了。刚开始，我所定义的结构是这样的：<br>　　struct Char{<br>　　 char hz[3]; // 保存汉字<br>　　 int frequency;// 使用频率<br>　　 RECT rect; // 这个字对应位图的区域<br>　　 Bool isUsing; // 是否使用<br>　　}<br>　　对于汉字和英文，我在这里大概地讲一下原理：汉字是由2个字节保存，而英文只需要1个。而判断一个字是否是汉字，只需判断第1个byte是否&gt;128（在原来的GB2312中，汉字的2个字节都是&gt;128的。而新的GBK字库，汉字的第2个字节不一定&gt;128，我想这是扩大了字库容量的原因。我的意思是说，如果给一个字符串你，随机给其中一个位置，然后我问你这个位置是什么？你的回答只能是：1 英文 2 汉字的首字节 3 汉字的尾字节。而这个问题的解法，为了稳妥起见，你必须从字符串的开始判断起）。也就是说在char[3]中，如果保存的是汉字，则char[0]保存汉字第1个字节，char[1]保存汉字第2个字节，第3个存放&#8217;\0&#8217;；如果是英文的话，则只用到char[0]，其它的全部为&#8217;\0&#8217;。<br>　　接下来，对于使用char[3]来保存汉字，是否真的很合适呢？因为如果把它当作一个字符串来看的话，在查找时就需要使用 strcmp 来比较字符串了，这样一定是会影响速度的。如果不把它看作字符串（字符串的最后一个字节需要以&#8217;\0&#8217;结尾），只用char[2]的话，我们可以只是简单地调用宏MAKEWORD，把2个byte压成1个WORD。当把文字作为一个WORD来看的时候，这样查找比较时可以用WORD内建的==操作，这样要比调用strcmp函数要快得多。<br>　　int frequency用来标志每个WORD的使用频率。设想，如果一个字已经存在于Cache中，以后每对它调用一次，就让frequency++。这样做还有一个用意是，是否可以在一个合适的时候，以frequency为参照来对这整个Cache排个序，把常用的字放在前面。那么在显示时，可以先在 Cache中查找所要显示的字是否已经存在于Cache中，如果有则直接显示，没有的话才需要采取某种手段将字加入到Cache中。一些常用的字（像：我、的、着、了、过&#8230;&#8230;），使得显示的速度将会大大提高。<br>　　其实上面说了半天的Cache，它具体是什么呢？其实就是指的最小绘制单位，在DirectX7里是Surface，而在DirectX8中就是 Texture。使用它来存放显示过的汉字，这样，就不用每次都从字库中读取或是调用如TextOut这类GDI超慢的函数了。因为每次在绘制一个文字之前，都会先在这个Cache中找，有的话就直接画上去，没有才会调用TextOut操作。而这样做的原因，我们先设想一下：游戏一般会控制为30fps或是60fps的速度不停地刷新，如果在GameLoop中有任何的代码是龟速级的话，这样就会导致fps的最大数的降低，也就意味着在保证30fps或 60fps的同时，能绘制到屏幕上的物体的数量减少了。这就是我们为什么要使用Texture来作为Cache的实现的原因。再一个，文字在屏幕上显示时一般会保持一段时间，这个时间可能是1秒-3秒，我们的游戏也就会相应地更新60fps或180fps，这是因为人们需要阅读它们。或者是一些如标题这样的文字，它们总是不会更新的，或是更新得很慢。我们完全可以在第一时间，比方说我们的画面有60fps，在第1个fps时，我们得知要显示文字&#8221;唐&#8221;，然后先在Cache中找，结果很糟：没有找到！这时马上用TextOut写到Texture上（现在还是属于第1个fps的时间范围内），而接下来的59个 fps（甚至更多），都不用再调TextOut了，而是直接从我们的Cache：Texture上Copy到屏幕上，速度得到了保障。谈到GDI的函数，为了实现设备无关性，它们的速度都很慢。其实它们也不像说得那么慢，如果不是每一帧都要调用它们，也算是蛮快的^_^。那么这个RECT rect，就代表着这个文字所对应在Texture上的区域位置。<br>　　使用什么东西来把这n个Char串起来呢，一般会想到的是链表，原因无非有2个：1 随时有新的字加进来，而内存是不连续的 2 它几乎没有容量的限制（除非是内存用完了）。不过链表的访问速度是很慢的，如果使用像数组这样的东西就好了。仔细想想，在这里，我们用来存储的 Cache，最大也就是256*256（理由上面说了），所以大小应该会是固定的。我们只需要在数组中的给每一个汉字加上一个标志，说明这个位置的使用情况。那么就使用数组吧，这样的话，访问的速度要更快一些，直接首地址+偏移量就够了，不必像链表，在查找时需要逐node访问。当然，我绝不会想到用 new Char来申请这个数组。因为这样做实在没有必要，请不要过于迷信自己的能力，在STL中已经有vector了，为什么还要自己写呢？^_^最后的一个 bool成员变量isUsing，也就是上面所说，用来标志使用情况的。</font></p>
<p><br><font size=2>实际的操作<br>　　上面考虑了那么多，我认为都是实际操作之前所应该有的。先谈谈如何显示吧，因为在DirectX8.1中已经将DirectDraw和 Direct3D融合为DirectGraphics了。所以无法像原来那样了&#8230;&#8230;&#8230;&#8230;哦，实在有太多东西要讲了，我还是推荐几篇文章给你吧^_^：<br>　　http://vip.6to23.com/mays/develop/directx/200201/Geczy3Din2D.htm<br>　　http://vip.6to23.com/mays/develop/directx/200201/GESurface.htm<br>　　http://vip.6to23.com/mays/develop/directx/200112/2DGtoDX8.htm<br>　　http://vip.6to23.com/mays/develop/directx/200201/DX8adv2D.htm<br>　　接下来，我会假设你已经具备了在DirectX8.1中绘图的基本概念了，所以在你继续往下阅读之前，请务必先仔细阅读以上推荐的文章。<br>　　前面提到，需要一个vector来对应Texture上各个位置文字的信息，上面已经创建了一个结构Char，则这个vector的定义为：<br>　　 vector &lt;Char&gt; _vBuf; // 记录缓冲中现有的文字情况<br>　　首先，由于可以利用硬件的放大缩小机能，所以字体的大小精度要求不是很高，只需要支持16*16和24*24大小的字体就可以了。我们需要一个这样的初始化函数：<br>　　bool CFont:: <br>　　/*-------------------------------------------------------------<br>　　LPDIRECT3DDEVICE8 pd3dDevice --- D3DDevice设备<br>　　char szFontName[] --- 字体名(如: 宋体)<br>　　int nSize --- 字体大小, 只支持16和24<br>　　int nLevel --- 纹理的大小级别<br>　　-------------------------------------------------------------*/<br>　　Init( LPDIRECT3DDEVICE8 pd3dDevice, char szFontName[], int nSize, int nLevel )。<br>　　<br>　　在DirectX8.1中，由SetTexture(&#8230;)所贴的图的大小，也就是Texture的大小，是有大小限制的，长和宽都必须是2^n，而且位图越大，所花费的显存越大，这样留给其他显示用的显存就少了。所以，必须根据需求的不同，来自定Texture(也就是Cache)的大小。因为汉字点阵大小的原因，所以从实用角度而言（比方说只是显示fps或是短小的标题），开辟一个64*64大小的Texture，才能满足最低情况下的需要（这时如果选择16点阵的话可以存放16个汉字，24点阵可以存放7个，依次类推&#8230;&#8230;）。<br>　　根据设置，创建Texture：<br>　　 _TextureSize = 32 &lt;&lt; nLevel; // 纹理大小<br>　　 _TextSize = nSize; // 文字大小<br>　　 _TextureSize = 32 &lt;&lt; nLevel; // 纹理大小<br>　　 <br>　　 _RowNum = _TextureSize / _TextSize; // 计算一行可以容纳多少个文字<br>　　 _Max = _RowNum * _RowNum; // 计算缓冲最大值<br>　　<br>　　创建字体，还是需要使用Win32 API。也就是先创建一个HDC：<br>　　 _hDc = CreateCompatibleDC(NULL);<br>　　<br>　　然后创建一个BITMAP和一个FONT，将它们与HDC关联起来。<br>　　 LOGFONT LogFont;<br>　　 ZeroMemory( &amp;LogFont, sizeof(LogFont) );<br>　　 LogFont.lfHeight = -_TextSize;<br>　　 LogFont.lfWidth = 0;<br>　　 LogFont.lfEscapement = 0;<br>　　 LogFont.lfOrientation = 0;<br>　　 LogFont.lfWeight = FW_BOLD;<br>　　 LogFont.lfItalic = FALSE;<br>　　 LogFont.lfUnderline = FALSE;<br>　　 LogFont.lfStrikeOut = FALSE;<br>　　 LogFont.lfCharSet = DEFAULT_CHARSET;<br>　　 LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; <br>　　 LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; <br>　　 LogFont.lfQuality = DEFAULT_QUALITY;<br>　　 LogFont.lfPitchAndFamily = DEFAULT_PITCH;<br>　　 lstrcpy( LogFont.lfFaceName, szFontName );<br>　　 <br>　　 _hFont = CreateFontIndirect( &amp;LogFont );<br>　　 if ( NULL == _hFont )<br>　　 {<br>　　 DeleteDC( _hDc );<br>　　 return false;<br>　　 }<br>　　 <br>　　（只需要创建一个字体大小的BITMAP即可）<br>　　 BITMAPINFO bmi;<br>　　 ZeroMemory(&amp;bmi.bmiHeader, sizeof(BITMAPINFOHEADER));<br>　　 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);<br>　　 bmi.bmiHeader.biWidth = _TextSize;<br>　　 bmi.bmiHeader.biHeight = -_TextSize;<br>　　 bmi.bmiHeader.biPlanes = 1;<br>　　 bmi.bmiHeader.biBitCount = 32;<br>　　 bmi.bmiHeader.biCompression = BI_RGB;<br>　　 <br>　　（这里需要定义一个指针指向位图的数据：<br>　　 DWORD * _pBits; // 位图的数据指针）<br>　　<br>　　 _hBmp = CreateDIBSection( _hDc, &amp;bmi, DIB_RGB_COLORS,<br>　　 (void **) &amp;_pBits, NULL, 0 );<br>　　 if ( NULL == _hBmp || NULL == _pBits )<br>　　 {<br>　　 DeleteObject( _hFont );<br>　　 DeleteDC( _hDc );<br>　　 return false;<br>　　 }<br>　　 <br>　　 // 将hBmp和hFont加入到hDc<br>　　 SelectObject( _hDc, _hBmp );<br>　　 SelectObject( _hDc, _hFont );<br>　　<br>　　接着设置背景色和文字色：<br>　　 SetTextColor( _hDc, RGB(255,255,255) );<br>　　 SetBkColor( _hDc, 0 );<br>　　<br>　　设置文字为上对齐：<br>　　 SetTextAlign( _hDc, TA_TOP );<br>　　<br>　　创建Texture所需要的顶点缓冲：<br>　　 if ( FAILED( _pd3dDevice-&gt;CreateVertexBuffer( _Max * 6 * sizeof(FONT2DVERTEX),<br>　　 D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,<br>　　 D3DPOOL_DEFAULT, &amp;_pVB ) ) )<br>　　 {<br>　　 DeleteObject( _hFont );<br>　　 DeleteObject( _hBmp );<br>　　 DeleteDC( _hDc );<br>　　 return false;<br>　　 }<br>　　 <br>　　创建Texture<br>　　 if ( FAILED( _pd3dDevice-&gt;CreateTexture( _TextureSize, _TextureSize, 1, 0, <br>　　 D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &amp;_pTexture ) ) )<br>　　 {<br>　　 DeleteObject( _hFont );<br>　　 DeleteObject( _hBmp );<br>　　 DeleteDC( _hDc );<br>　　 SAFE_RELEASE(_pVB);<br>　　 return false;<br>　　 }<br>　　<br>　　设置渲染设备的渲染属性：<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_ALPHAREF, 0x08 );<br>　　 _pd3dDevice-&gt;SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );<br>　　 _pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );<br>　　 <br>　　 _pd3dDevice-&gt;SetTexture( 0, _pTexture );<br>　　 _pd3dDevice-&gt;SetVertexShader( D3DFVF_FONT2DVERTEX );<br>　　 _pd3dDevice-&gt;SetStreamSource( 0, _pVB, sizeof(FONT2DVERTEX) );<br>　　<br>　　设置缓冲的最大容量<br>　　 _vBuf.resize( _Max );<br>　　<br>　　这样，初始化完成了。接下来是如何把一个汉字写到Texture中，以及如何进行管理。定义函数：<br>　　// 得到文字在纹理中的位置<br>　　void CFont::<br>　　/*-------------------------------------------------------------<br>　　char c1 --- 文字的第1个字节<br>　　char c2 --- 文字的第2个字节<br>　　int &amp; tX --- 写入纹理中的坐标x<br>　　int &amp; tY --- 写入纹理中的坐标y<br>　　-------------------------------------------------------------*/<br>　　Char2Texture( char c1, char c2, int &amp; tX, int &amp; tY )<br>　　{<br>　　 WORD w = MAKEWORD(c1, c2); // 把此字变为WORD<br>　　 vector&lt;Char&gt;::iterator it = find( _vBuf.begin(), _vBuf.end(), w );<br>　　 if ( it == _vBuf.end() ) // 如果没找到<br>　　 {<br>　　 it = find( _vBuf.begin(), _vBuf.end(), 0 ); // 查找空闲位置<br>　　 if ( it == _vBuf.end() ) // 缓冲已满<br>　　 {<br>　　 for(; it!=_vBuf.begin(); it-- )<br>　　 {<br>　　 it-&gt;hz = 0;<br>　　 }<br>　　// Log.Output( "字体缓冲已满, 清空!" );<br>　　 }<br>　　<br>　　 // 计算当前空闲的Char在缓冲中是第几个<br>　　 int at = it-_vBuf.begin();<br>　　<br>　　 // 得到空闲位置的坐标<br>　　 tX = (at % _RowNum) * _TextSize;<br>　　 tY = (at / _RowNum) * _TextSize;<br>　　<br>　　 // 设置这个Char为使用中<br>　　 (*it).hz = w;<br>　　<br>　　 RECT rect = {0, 0, _TextSize, _TextSize};<br>　　 char sz[3] = {c1, c2, '\0'};<br>　　 // 填充背景为黑色(透明色)<br>　　 FillRect( _hDc, &amp;rect, (HBRUSH)GetStockObject(BLACK_BRUSH) );<br>　　 // 往hBitmap上写字<br>　　 ::TextOut( _hDc, 0, 0, sz, c1 &amp; 0x80 ? 2 : 1 );<br>　　 <br>　　 // 锁定表面, 把汉字写入纹理, 白色的是字(可见), 黑色为背景(透明)<br>　　 D3DLOCKED_RECT d3dlr;<br>　　 _pTexture-&gt;LockRect(0, &amp;d3dlr, NULL, D3DLOCK_NOSYSLOCK);<br>　　 BYTE * pDstRow = (BYTE*)( (WORD *)d3dlr.pBits + tY * _TextureSize + tX );<br>　　 <br>　　 for (DWORD y=0; y&lt;_TextSize; y++)<br>　　 {<br>　　 WORD * pDst16 = (WORD*)pDstRow;<br>　　 for (DWORD x=0; x&lt;_TextSize; x++)<br>　　 {<br>　　 BYTE bAlpha = (BYTE)((_pBits[_TextSize * y + x] &amp; 0xff) &gt;&gt; 4);<br>　　 if (bAlpha &gt; 0)<br>　　 *pDst16++ = (bAlpha &lt;&lt; 12) | 0x0fff;<br>　　 else<br>　　 *pDst16++ = 0x0000;<br>　　 }<br>　　 pDstRow += d3dlr.Pitch;<br>　　 }<br>　　 _pTexture-&gt;UnlockRect( NULL );<br>　　 }<br>　　 else<br>　　 {<br>　　 // 计算当前空闲的Char在缓冲中是第几个<br>　　 int at = it-_vBuf.begin();<br>　　<br>　　 // 得到这个字的坐标<br>　　 tX = (at % _RowNum) * _TextSize;<br>　　 tY = (at / _RowNum) * _TextSize;<br>　　 }<br>　　}<br>　　以上代码中的注释已经很清楚了，相信无须我多言。这里唯一需要声明的是：原来所定义的Char结构是这样的<br>　　struct Char{<br>　　 char hz[3]; // 保存汉字<br>　　 int frequency;// 使用频率<br>　　 RECT rect; // 这个字对应位图的区域<br>　　 Bool isUsing; // 是否使用<br>　　}<br>　　后来因为将char hz[3]合成为WORD，所以改为WORD hz。然后对于int frequency，这个词频应该如何表现，我一直没有想到很好的方法。frequency应该在何时++呢？是在每次被使用的时候吗？但是这样的话，上面说过，游戏是以60fps的速度在刷新，如果停上1分钟的话，变量很快就会溢出了。就算是使用像是DWORD或__int64这样的巨型变量保存，也是不安全的。除非能在某个合适的时候将frequency清零，但是这个&#8220;时候&#8221;是什么时候呢？或者设置一个最大值，如65535，但是这样也基本上没什么用途，很快，所有在vector中的Char中的frequency都会++成65535的。回忆一下最初，是因为想把常用字放到vector的前面，以便每次find操作可以最快返回结果的。而经过我的测试，即使不做这样的优化操作，速度也是很快的，毕竟Cache不是很大，加上vector是连续内存空间。所以可以放弃使用int frequency。<br>　　然后对于RECT rect，因为没有了int frequency，意味着一旦将汉字写入到Texture，其位置就不会变动了。所以，很容易根据find函数操作后的iterator，直接计算出这个汉字所在Texture的位置。这样，RECT rect也不再必须。<br>　　而bool isUsing，它本身就是个鸡肋，要也可以，这样结构更加清晰。不过，直接通过观察WORD hz为0或非0，即可实现isUsing的作用了。<br>　　为什么要对结构Char这么精雕细琢呢？<br>1. 既然没有必要的东西，就应该删除<br>2. Char结构的大小越大，vector所要求的内存越大<br>3. 小的结构，find可以更快地查找出所结果<br>　　为什么find会正常工作呢？这里我要大概地讲一下find是如何查找出所需的位置的：它只是简单地使用while从vector的begin一直遍历到end，逐个判断，直到找到为止。find要求必须实现自己的operator ==()，进一步跟踪到find的源码中，发现也是这样。于是前面的结构Char变成了现在这样：<br>　　 struct Char{<br>　　 WORD hz; // 文字<br>　　<br>　　 Char() : hz(0) {}<br>　　<br>　　 // 用作查找文字<br>　　 inline bool operator == ( WORD h ) const<br>　　 {<br>　　 return hz==h ? true : false;<br>　　 }<br>　　 };<br>　　是不是很简单？^___^<br>　　<br>　　终于到了显示的函数了：<br>　　// 得到文字在纹理中的位置<br>　　bool CFont::<br>　　/*-------------------------------------------------------------<br>　　char szText[] --- 显示的字符串<br>　　int x --- 屏幕坐标x<br>　　int y --- 屏幕坐标y<br>　　D3DCOLOR --- 颜色及alpha值<br>　　int nLen --- 字符串长度<br>　　float fScale --- 放大比例<br>　　-------------------------------------------------------------*/<br>　　TextOut( char szText[], int x, int y, D3DCOLOR color, int nLen, float fScale )<br>　　{<br>　　 Assert( szText!=NULL );<br>　　<br>　　 float sx = x, sy = y,<br>　　 offset=0, w=0, h=0, tx1=0, ty1=0, tx2=0, ty2=0;<br>　　 w = h = (float)_TextSize * fScale;<br>　　<br>　　 char ch[3] = {0,0,0};<br>　　 FONT2DVERTEX * pVertices = NULL;<br>　　 UINT wNumTriangles = 0;<br>　　 _pVB-&gt;Lock(0, 0, (BYTE**)&amp;pVertices, D3DLOCK_DISCARD);<br>　　<br>　　 if ( -1 == nLen || // 默认值-1<br>　　 nLen &gt; lstrlen( szText ) ) // 如果nLen大于字符串实际长度, 则nLen=实际长度<br>　　 nLen = lstrlen( szText );<br>　　 for (int n=0; n&lt;nLen; n++ )<br>　　 {<br>　　 ch[0] = szText[n];<br>　　<br>　　 if ( ch[0]=='\n' )<br>　　 {<br>　　 sy+=h;<br>　　 sx=x;<br>　　 continue;<br>　　 }<br>　　<br>　　 if ( ch[0] &amp; 0x80 )<br>　　 {<br>　　 n++;<br>　　 ch[1] = szText[n];<br>　　 offset = w;<br>　　 }<br>　　 else<br>　　 {<br>　　 ch[1] = '\0';<br>　　 offset = w / 2 ;<br>　　 }<br>　　<br>　　 int a, b;<br>　　 Char2Texture( ch[0], ch[1], a, b );<br>　　 <br>　　 // 计算纹理左上角 0.0-1.0<br>　　 tx1 = (float)(a) / _TextureSize;<br>　　 ty1 = (float)(b) / _TextureSize;<br>　　 // 计算纹理右上角 0.0-1.0<br>　　 tx2 = tx1 + (float)_TextSize / _TextureSize;<br>　　 ty2 = ty1 + (float)_TextSize / _TextureSize;<br>　　<br>　　 // 填充顶点缓冲区<br>　　 *pVertices++ = FONT2DVERTEX(sx, sy + h, 0.9f, color, tx1, ty2);<br>　　 *pVertices++ = FONT2DVERTEX(sx, sy, 0.9f, color, tx1, ty1);<br>　　 *pVertices++ = FONT2DVERTEX(sx + w, sy + h, 0.9f, color, tx2, ty2);<br>　　 *pVertices++ = FONT2DVERTEX(sx + w, sy, 0.9f, color, tx2, ty1);<br>　　 *pVertices++ = FONT2DVERTEX(sx + w, sy + h, 0.9f, color, tx2, ty2);<br>　　 *pVertices++ = FONT2DVERTEX(sx, sy, 0.9f, color, tx1, ty1);<br>　　<br>　　 wNumTriangles+=2;<br>　　<br>　　 sx+=offset; // 坐标x增量<br>　　 }<br>　　 _pVB-&gt;Unlock();<br>　　 _pd3dDevice-&gt;DrawPrimitive( D3DPT_TRIANGLELIST, 0, wNumTriangles );<br>　　<br>　　 return true;<br>　　}</font></p>
<p><br><font size=2>结束语<br>　　记得有一句名言： Keep it simple and stupid.在实现功能的同时，保持代码简单、清晰是非常重要的一件事。相信在往后的日子里，在不论是别人阅读或是你自己回顾的时候，你都会发现一如既往地遵守这个守则，是多么得重要！<br>　　相信通过上面我那无数的废话，加上代码中还算足够的注释，聪明的你一定能够明白这其中的原理了吧。如果以上的内容还不足以让你完全搞清楚的话，你可以登录我的主页：<br>　　</font></p>
<p><font size=2>炎龙工作室<br>　　上面不仅包括了上面所写的程序代码，还有一个用来演示效果的一个很简单的demo。<br>　　说明，以上所实现的CFont是包含在我的游戏引擎中的一个部件，而目前已经实现的部件包括有：<br>1. CGameFrame（游戏框架类） ----- 封装了窗口及D3D设备的建立，需要派生出自己的子类<br>2. CAudio和CSound（声音类） ----- 支持wav/mid/mp3的播放<br>3. CDirectInput（控制类） ----- 键盘、鼠标操作<br>4. CDirectShow（视频类） ----- 支持avi/mpg/mov等的播放<br>5. CSpriteX（精灵类） ----- 方便游戏中对精灵的控制<br>6. CFont（字体类） ----- 中英文字体的显示<br>7. CTimer（时间类） ----- 高精度时间的控制<br>8. FPS（fps 类） ----- fps的计算<br>9. LOG（日志类） ----- 游戏中的错误反应以及状态记录<br>　　最重要的是，这个Game Engine完全是开放源代码的。关于更新的情况、版本说明以及源码下载，请随时关注我的主页！<br>接下来，我将会继续完善这个Engine，可能加入的有：高效粒子系统、斜45度角地图&#8230;&#8230;</font></p>
<img src ="http://www.cppblog.com/winmain/aggbug/108626.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-28 20:19 <a href="http://www.cppblog.com/winmain/archive/2010/02/28/108626.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]CEGUI中的汉字显示实现</title><link>http://www.cppblog.com/winmain/archive/2010/02/27/108576.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sat, 27 Feb 2010 13:38:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/27/108576.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108576.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/27/108576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108576.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108576.html</trackback:ping><description><![CDATA[<p>几日前，用&nbsp;<wbr>CEGUI做界面，发现无法应用CEGUI的window中setText()函数直接显示中文。上网google一下，原来经过简单的字符转化可以显示中文（偷着乐，CEGUI太方便了）。</p>
<p>&nbsp;<wbr></p>
<p>方法如下（引用）：http://blog.csdn.net/kun1234567/archive/2008/04/11/2282761.aspx</p>
<p>CEGUI使用utf8编码格式。这就意味着我们可以很简单的就显示中文。</p>
<p>&nbsp;<wbr></p>
<p>1、弄个包含中文的字体，在这里我借用大多数例子里的 &#8220;C：/windows/Font/simhei.ttf&#8221;文件。把这个文件拷贝到Datafiles文件夹的Font文件夹里。</p>
<p>&nbsp;<wbr></p>
<p>2、随便照着一个 .Font文件，自己写一个simhei.font文件。可以用TXT写，然后保存，有的朋友说需要保存为utf8编码格式，实际上是不需要的。</p>
<p>&nbsp;<wbr></p>
<p>3、同时注意修改你加载到程序里的scheme文件，将里面的字体文件设置成simhei.ttf。你也可以继续使用FirstWindow这个例子，这样的话直接修改源代码里的字体为simhei.tff。</p>
<p>&nbsp;<wbr></p>
<p>4、现在在程序里进行字符编码转换，我拿代码说明问题：</p>
<p>&nbsp;<wbr></p>
<p>std::wstring aa = L"123中文abcあいうえお";</p>
<p>char buff[128] = "";</p>
<p>WideCharToMultiByte( CP_UTF8, 0, aa.c_str(), aa.size(), buff, sizeof(buff), 0, 0);</p>
<p>button1-&gt;setText ( CEGUI::String ( CEGUI::utf8* )buff );</p>
<p>&nbsp;<wbr></p>
<p>原理是这样的，对于utf8来说，英文字符和ansi编码在内存布局上没什么区别，都是一个UCHAR。但是对于非英文字符，则是UCHAR+UCHAR+UCHAR。如果我们手工进行编码格式转换，会比较烦琐。</p>
<p>&nbsp;<wbr></p>
<p>比较偷懒的方法就是，我们先用WCHAR(unicode内存布局,UCHAR+UCHAR+UCHAR+UCHAR)来储存需要显示的字符串，然后调用Win32API来帮我们把宽字符转换成char(多字节字符集内存布局)。</p>
<p>&nbsp;<wbr></p>
<p>这就是基本方法了，然后我们可以根据这个转换方针，利用Win32API随意的转换字符编码格式，从而满足程序中的各种需求。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 通过此方法可以显示中文，还没来得急高兴就发现了第二个问题：这种方法显示中文速度太慢（显示几十个字需要等上7、8秒左右）。难道没有高效的方法吗？</p>
<p>于是继续Google(我很懒，别人能做的事情从来不麻烦自己，懒得跟踪代码)，结果还真让我找到了两篇相关的文章：一份是千里马肝的《游戏中汉字显示的实现与技巧》，另一份是免费打工仔的《让OGRE支持中文》。从中找到了原因：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 原来在游戏中，是将点阵字库或tif字体里的文字写进纹理，根据需求贴到指定的位置。英文的显示非常简单，只有26个字母，就算再加一些标点、符号什么的，用一张位图，就可以足以显示所有的单词了。而中文要像处理英文那样，把所有的汉字都保存在一张位图里，那么每一种字体都要生成一个巨型位图。在 GB2312中，一共有6000多个汉字，就算是用16*16，据说会有2.5M！（马肝兄说的，我没算过）</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 继续Google，也没有找到解决问题的直接办法，唉，再懒也得自己上阵了。</p>
<p>通过跟踪调试，发现了问题所在，原来罪魁祸首就是他：</p>
<p>&nbsp;<wbr></p>
<p align=left>const FontGlyph *Font::getGlyphData (utf32 codepoint)</p>
<p align=left>{</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (codepoint &gt; d_maxCodepoint)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return 0;</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (d_glyphPageLoaded)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint page = codepoint / GLYPHS_PER_PAGE;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint mask = 1 &lt;&lt; (page &amp; (BITS_PER_UINT - 1));</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (!(d_glyphPageLoaded [page / BITS_PER_UINT] &amp; mask))</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_glyphPageLoaded [page / BITS_PER_UINT] |= mask;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> rasterize (codepoint &amp; ~(GLYPHS_PER_PAGE - 1),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> codepoint | (GLYPHS_PER_PAGE - 1));</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CodepointMap::const_iterator pos = d_cp_map.find (codepoint);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return (pos != d_cp_map.end()) ? &amp;pos-&gt;second : 0;</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>原来CEGUI根据Unicode字符的编码顺序，为每256个字符分配一张纹理（例如编码0-255存放在纹理一，编码768-1023 存放在纹理四）。英文很容易搞定了，那么几个字符一张纹理就够了，可中文就得靠运气了，有时显示几个字就要生成几张纹理，还要将每张纹理用不需要的相邻字填满，劳民伤财！</p>
<p>发现了问题，我便按照千里马肝的思想对函数进行了改造，将使用的文字放入一张纹理中，因为纹理最大承载256个字，所以，当汉字超过256个时，则将不常用的去掉，将新的字符写入。</p>
<p>后来我发现汉字的引用没有太多的规律，常用的一千多汉字出现的概率没有那么悬殊（废话，要不怎么是常用呢!），没有办法很好地按照使用的频率将汉字限制在256个字以内，写进纹理，就索性一旦满了就将字全部释放掉，重新写入。（也需有我没找到，还请高手指教）</p>
<p>代码如下：</p>
<p align=left>const FontGlyph *Font::getGlyphData (utf32 codepoint)</p>
<p align=left>{</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (codepoint &gt; d_maxCodepoint)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return 0;</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if(codepoint &lt; 256)&nbsp;<wbr> //决定保留一张纹理放英文和字符</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (d_glyphPageLoaded)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint page = codepoint / GLYPHS_PER_PAGE;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint mask = 1 &lt;&lt; (page &amp; (BITS_PER_UINT - 1));</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (!(d_glyphPageLoaded [page / BITS_PER_UINT] &amp; mask))</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_glyphPageLoaded [page / BITS_PER_UINT] |= mask;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> rasterize (codepoint &amp; ~(GLYPHS_PER_PAGE - 1),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> codepoint | (GLYPHS_PER_PAGE - 1));</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CodepointMap::const_iterator pos = d_cp_map.find (codepoint);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return (pos != d_cp_map.end()) ? &amp;pos-&gt;second : 0;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> else //显示汉字啦</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CodepointMap::const_iterator pos;</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> pos = d_hz_map.find (codepoint);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if(pos != d_hz_map.end())</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return (pos != d_hz_map.end()) ? &amp;pos-&gt;second : 0;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> else</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> rasterizeHZ(codepoint);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> pos = d_hz_map.find (codepoint);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return (pos != d_hz_map.end()) ? &amp;pos-&gt;second : 0;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>}</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>void FreeTypeFont::rasterizeHZ (utf32 codepoint)</p>
<p align=left>{</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> int num;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint texsize = 512;</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if(d_hz_map.size() &lt; 256)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> float adv = d_fontFace-&gt;glyph-&gt;metrics.horiAdvance * float(FT_POS_COEF);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_hz_map[codepoint] = FontGlyph (adv);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> else</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_hz_map.clear();</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> ImagesetManager::getSingleton ().destroyImageset (hzImageset-&gt;getName ());</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> hzImageset = ImagesetManager::getSingleton ().createImageset (</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_name + "_auto_glyph_images_" ,</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System::getSingleton ().getRenderer ()-&gt;createTexture ());</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_glyphImages.push_back (hzImageset);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> float adv = d_fontFace-&gt;glyph-&gt;metrics.horiAdvance * float(FT_POS_COEF);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> d_hz_map[codepoint] = FontGlyph (adv);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CodepointMap::const_iterator hzInter&nbsp;<wbr> = d_hz_map.find(codepoint);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (!hzInter-&gt;second.getImage())</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Render the glyph</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (FT_Load_Char (d_fontFace, hzInter-&gt;first, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT |</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (d_antiAliased ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO)))</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> std::stringstream err;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> err &lt;&lt; "Font::loadFreetypeGlyph - Failed to load glyph for codepoint: ";</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> err &lt;&lt; static_cast&lt;unsigned int&gt; (hzInter-&gt;first);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> err &lt;&lt; ".&nbsp;<wbr> Will use an empty image for this glyph!";</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Logger::getSingleton ().logEvent (err.str (), Errors);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Create a 'null' image for this glyph so we do not seg later</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Rect area(0, 0, 0, 0);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Point offset(0, 0);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> name += hzInter-&gt;first;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> hzImageset-&gt;defineImage(name, area, offset);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> ((FontGlyph &amp;)hzInter-&gt;second).setImage(&amp;hzImageset-&gt;getImage(name));</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> else</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint glyph_w = d_fontFace-&gt;glyph-&gt;bitmap.width + INTER_GLYPH_PAD_SPACE;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint glyph_h = d_fontFace-&gt;glyph-&gt;bitmap.rows + INTER_GLYPH_PAD_SPACE;</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Check if glyph right margin does not exceed texture size</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint x_next = m_nHZX + glyph_w;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (x_next &gt; texsize)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> m_nHZX = INTER_GLYPH_PAD_SPACE;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> x_next = m_nHZX + glyph_w;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> m_nHZY = m_nHZYB;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Check if glyph bottom margine does not exceed texture size</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> uint y_bot = m_nHZY + glyph_h;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Copy rendered glyph to memory buffer in RGBA format</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> drawGlyphToBuffer (hzmem_buffer + (m_nHZY * texsize) + m_nHZX, texsize);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Create a new image in the imageset</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Rect area(static_cast&lt;float&gt;(m_nHZX),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> static_cast&lt;float&gt;(m_nHZY),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> static_cast&lt;float&gt;(m_nHZX + glyph_w - INTER_GLYPH_PAD_SPACE),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> static_cast&lt;float&gt;(m_nHZY + glyph_h - INTER_GLYPH_PAD_SPACE));</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Point offset(d_fontFace-&gt;glyph-&gt;metrics.horiBearingX * static_cast&lt;float&gt;(FT_POS_COEF),</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -d_fontFace-&gt;glyph-&gt;metrics.horiBearingY * static_cast&lt;float&gt;(FT_POS_COEF));</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> name += hzInter-&gt;first;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> hzImageset-&gt;defineImage (name, area, offset);</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> ((FontGlyph &amp;)hzInter-&gt;second).setImage (&amp;hzImageset-&gt;getImage (name));</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Advance to next position</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> m_nHZX = x_next;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if (y_bot &gt; m_nHZYB)</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> m_nHZYB = y_bot;</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // Copy our memory buffer into the texture and free it</p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> hzImageset-&gt;getTexture ()-&gt;loadFromMemory (hzmem_buffer, texsize, texsize, Texture::PF_RGBA);</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>}</p>
<p align=left>&nbsp;<wbr></p>
<p align=left>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> OK，问题搞定，打完收工。试试，效果还不错，可以洗洗睡了。特将自己的一点体会写出来，给新手提供个捷径，也希望高手批评指教。</p>
<img src ="http://www.cppblog.com/winmain/aggbug/108576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-27 21:38 <a href="http://www.cppblog.com/winmain/archive/2010/02/27/108576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QT小记之在VS2005中使用QT</title><link>http://www.cppblog.com/winmain/archive/2010/01/31/106885.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sun, 31 Jan 2010 06:44:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/01/31/106885.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/106885.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/01/31/106885.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/106885.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/106885.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; QT的结构很清晰明了，看过第一个HELLO WORLD便爱上了它，感觉CEGUI有借鉴过QT的设计。<br>&nbsp;&nbsp;&nbsp; 如何在Windows平台下使用QT开发？<br>&nbsp;&nbsp;&nbsp; 一，下载SDK包<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 请去官网(QT被NOKIA收购，貌似使用协议更宽松了）下载win版本的QTSDK包。（地址如不知请百度GOOGLE之）<br>&nbsp;&nbsp;&nbsp; 二，设置开发环境相关变量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 系统环变：PATH下加入：(<span class=ColorResultsClass highlight="true" realoffset="1153" alpha-value="20"></span>yourqtinstallpath)\bin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 添加新的环境变量,名字为"QMAKESPEC",值为"win32-msvc<span class=ColorResultsClass highlight="true" realoffset="1174" alpha-value="20">2005</span>".<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VS2005环境：include和lib分别包含qt的include目录和qt的lib目录<br>&nbsp;&nbsp;&nbsp; 三, 编译你所需要的QT Lib<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过"开始"菜单 -&gt; "Microsoft Visual Studio <span class=ColorResultsClass highlight="true" realoffset="561" alpha-value="20">2005</span>" -&gt; "Visual Studio Tools", 运行命令行（勿使用cmd，找不到nmake)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<span class=ColorResultsClass highlight="true" realoffset="1153" alpha-value="20"></span>yourqtinstallpath)&gt;configure -no-stl -no-dsp -vcproj <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 待QMake完成 继续简单的敲入nmake即可（等待编译吧）<br>&nbsp;&nbsp;&nbsp; 四,创建QT工程 helloworld<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有三种办法把QT代码生成为VS工程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1，使用qmake,如代码在C盘下<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C:\&gt; qmake -project -t vcapp -o projectname.pro<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C:\&gt; qmake<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2，编写pro工程文件。如果是商业版的就不用了。具体可以参考帮助文档qmake。新建记事本文件，文件名修改为hello.pro，文件名没有 特殊要求哈；输入
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCES +=main.cpp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CONFIG +=<span class=ColorResultsClass highlight="true" realoffset="1714" alpha-value="20">qt</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ok 保存。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开命令行，切换目录到hello.cpp所在目录。生成Makefile文件；输入：</p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; qmake -o Makefile hello.pro&nbsp;； </p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 接下来生成项目文件.vcproj文件。 </p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; qmake -tp vc -o hello.vcproj hello.pro <br></p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp; 3，直接使用<span class=ColorResultsClass highlight="true" realoffset="1237" alpha-value="20">Qt</span> Visual Studio Integration v1.2.2 for.<span class=ColorResultsClass highlight="true" realoffset="1237" alpha-value="20">VS</span>.2003.<span class=ColorResultsClass highlight="true" realoffset="1237" alpha-value="20">2005插件(详见http://blog.csdn.net/znf19850924/archive/2008/01/16/2047373.aspx)</span></p>
<p style="TEXT-INDENT: 2em"><strong>&nbsp;&nbsp;&nbsp; 需要配置<span class=ColorResultsClass highlight="true" realoffset="1384" alpha-value="20"></span>如下：</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Tools" -&gt; "Options" -&gt; "<span class=ColorResultsClass highlight="true" realoffset="1405" alpha-value="20">Qt</span>" -&gt; "Builds", 添加我们刚才编译的<span class=ColorResultsClass highlight="true" realoffset="1405" alpha-value="20">Qt</span>代码,名字为"<span class=ColorResultsClass highlight="true" realoffset="1405" alpha-value="20">Qt</span> 4.3.2", 路径为(<span class=ColorResultsClass highlight="true" realoffset="1153" alpha-value="20"></span>yourqtinstallpath)</p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; 启动一个新的工程.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 选择"<span class=ColorResultsClass highlight="true" realoffset="1927" alpha-value="20">Qt</span> projects" -&gt; "<span class=ColorResultsClass highlight="true" realoffset="1927" alpha-value="20">Qt</span> Application"类型,输入工程名字,单击OK.</p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; 双击工程文件里面的"test.ui",马上出现了所见及所得的窗体编辑器,在上面添加一个按钮.</p>
<p style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; 双击按钮,产生相应的消息响应函数.<br></p>
<p style="TEXT-INDENT: 2em">&nbsp; &nbsp;&nbsp; 添加头文件:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include &lt;QMessageBox&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 在函数void Test::on_pushButton_clicked()体内添加如下代码:<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QMessageBox box(this);<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; box.setText("Haha, hit me.");<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; box.exec();</p>
&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PS:另外可以直接使用QTSDK自带安装的QTCreate来进行QT工程，在安装好SDK后不需要进行任何配置就能够运行DEMO并看到效果，可能自身已经配置好，但是如何引入到VS中，暂时还不知道，没有研究。<br>
<img src ="http://www.cppblog.com/winmain/aggbug/106885.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-01-31 14:44 <a href="http://www.cppblog.com/winmain/archive/2010/01/31/106885.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VS05编译wxWidgets</title><link>http://www.cppblog.com/winmain/archive/2009/02/16/73974.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Mon, 16 Feb 2009 14:59:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/02/16/73974.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/73974.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/02/16/73974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/73974.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/73974.html</trackback:ping><description><![CDATA[找了好多文章照着做弄了一下午才弄好，自己归总一下，wxWidgets版本2.8.9。<br><br>导读： <br>　　1. 去http://www.wxwidgets.org/downloads/下载一个wxMSW版本的wxWidgets。 <br>　　2. 运行安装文件。在安装好后设置环境变量WXWIN，指向wxWidgets的安装目录。因为安装过程仅仅是把文件拷贝到指定的目录，所以还需要对wxWidgets进行编译。 <br>　　3. 进入$(WXWIN)\build\msw目录，用VS2005打开wx.dsw，提示是否进行项目转换，点确定。如果想要连接静态运行库，在编译前应该对每个项目进行设置。<br>　　 <img style="WIDTH: 283px; HEIGHT: 176px" border=0 src="http://www.cppblog.com/images/cppblog_com/winmain/1.JPG"><br>　　&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; 编译Debug版本的库：用Visual Studio 2005打开build\msw\wx.dsw文件，Solution Configurations中选中Unicode Debug，直接Build Solution就可以编译出Debug版本的wxWidgets库了。(默认的是Multi-Threaded debug dll)<br>　　&nbsp; 编译Relase版本的库：Release 版本的wxWidgets库虽然也可以通过类似的方法去编译，但编译出来的库仍然依赖于visual studio 2005的运行时库。Debug版本的库依赖VS2005也就算了，反正是自己调试用的。Release版本可是要给别人用的，再带上一大堆dll就不好了。为了解决这个问题，我们需要先在Solution Configuration中选中Unicode Release，然后在Solution Explorer中，针对每一个project在项目属性的C/C++ --&gt; Code Generation --&gt; Runtime Library中选Multi-Threaded。(HOHO, 有20个项目要改属性啊~~~)。最后再Build Solution就可以了。(也就是LIB库)<br><br>　　 <br>　　编译好后的wxWidgets会在$(WXWIN)\lib\vc_lib目录下生成一系列的lib文件，这些lib文件的名字遵循下面的命名规则：不依赖于GUI组件的库会以"wxbase"开头，紧跟着的是版本号，然后的字母表明这个库是否是编译为Unicode('u')或是否是编译为Debug('d')，名字中的最后部分是wxWidgets组件的名字。 <br>　　注意：wxWidgets编译完后在$(WXWIN)\build\msw目录下会生成许多预编译头文件，占了很大的空间，如果确定以后不再编译wxWidgets库的话，可以考虑删掉。 <br>　　设置VC开发环境 <br>　　打开Tools -&gt; Options -&gt; Projects and Solutions -&gt; VC++ Directories <br>　　1. 在Include files中加入$(WXWIN)\include和$(WXWIN)\include\msvc <br>　　2. 在Library files中加入$(WXWIN)\lib\vc_lib <br>　　创建wxWidgets项目 <br>　　新建一个General -&gt; Empty Project或Win32 -&gt; Win32 Project项目，然后设置项目的一些属性，可以选择下面的其中一个来设置。譬如你如果打算使用Unicode，那么选择Unicode Debug或Unicode Release，如果你仅仅想调试程序而非发布，则只需要选择Debug设置。 <br>　　Debug： <br>　　Project Properties -&gt; General -&gt; Character Set: No Set <br>　　Project Properties -&gt; C/C++ -&gt; Code Generation -&gt; Runtime Library: Multi-threaded Debug DLL (/MDd)<br>　　Project Properties -&gt; Linker -&gt; Input -&gt; Additional Dependencies: wxbase28d.lib wxmsw28d_core.lib winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib <br><br>　　Release： <br>　　Project Properties -&gt; General -&gt; Character Set: No Set <br>　　Project Properties -&gt; C/C++ -&gt; Code Generation -&gt; Runtime Library: Multi-threaded (/MT) <br>　　Project Properties -&gt; Linker -&gt; Input -&gt; Additional Dependencies: wxbase28.lib wxmsw28_core.lib winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib <br><br>　　Unicode Debug： <br>　　Project Properties -&gt; General -&gt; Character Set: Use Unicode Character Set <br>　　Project Properties -&gt; C/C++ -&gt; Code Generation -&gt; Runtime Library: Multi-threaded Debug DLL (/MDd)<br>　　Project Properties -&gt; Linker -&gt; Input -&gt; Additional Dependencies: wxbase28ud.lib wxmsw28ud_core.lib winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib <br><br>　　Unicode Release： <br>　　Project Properties -&gt; General -&gt; Character Set: Use Unicode Character Set <br>　　Project Properties -&gt; C/C++ -&gt; Code Generation -&gt; Runtime Library: Multi-threaded (/MT) <br>　　Project Properties -&gt; Linker -&gt; Input -&gt; Additional Dependencies: wxbase28u.lib wxmsw28u_core.lib winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib <br><br>　　问题 <br>　　1. 在编译时出现了Cannot open include file: '../mswu/wx/setup.h': No such file or directory错误 <br>　　这是因为项目属性的Character Set设置不正确，必须与使用的wxWidgets库的Character Set一致。 <br>　　2. 在编译时出现了MSVCRT.lib(MSVCRT.dll) : error LNK2005: _free already defined in LIBC.lib(free.obj) <br>　　这是因为没有连接正确的wxWidgets库，譬如Unicode Debug版本的项目就需要连接Unicode+Debug版本的wxWidgets库(库名后缀为'ud'的lib文件)。或者是wxWidgets和Application使用的Runtime Library不相同。 <br>　　3. 运行是出现No Debugging Information对话框 <br>　　将Project Properties -&gt; Linker -&gt; Debugging -&gt; Generate Debug Info的值改成Yes (/DEBUG)。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">#ifndef&nbsp;WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722<br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">对于支持预编译的编译器，包含此文件<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;For&nbsp;compilers&nbsp;that&nbsp;support&nbsp;precompilation,&nbsp;includes&nbsp;"wx.h".</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">wx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">wxprec.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">对于不支持预编译的编译器，进行如下操作</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#ifndef&nbsp;WX_PRECOMP<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Include&nbsp;your&nbsp;minimal&nbsp;set&nbsp;of&nbsp;headers&nbsp;here,&nbsp;or&nbsp;wx.h</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">wx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">wx.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">定义wxApp类</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;HelloWorldApp&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;wxApp<br>{<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在程序初始化时调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;OnInit();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在程序结束时调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;OnExit();<br>};<br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">定义wxGetApp()函数，可以取得HelloWorldApp类型的全局程序变量</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DECLARE_APP(HelloWorldApp)<br><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722</span></div>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000"><br><br>#ifndef&nbsp;WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722<br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">对于支持预编译的编译器，包含此文件<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;For&nbsp;compilers&nbsp;that&nbsp;support&nbsp;precompilation,&nbsp;includes&nbsp;"wx.h".</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">wx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">wxprec.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">对于不支持预编译的编译器，进行如下操作</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#ifndef&nbsp;WX_PRECOMP<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Include&nbsp;your&nbsp;minimal&nbsp;set&nbsp;of&nbsp;headers&nbsp;here,&nbsp;or&nbsp;wx.h</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">wx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">wx.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">定义wxApp类</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;HelloWorldApp&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;wxApp<br>{<br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在程序初始化时调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;OnInit();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在程序结束时调用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;OnExit();<br>};<br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">定义wxGetApp()函数，可以取得HelloWorldApp类型的全局程序变量</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DECLARE_APP(HelloWorldApp)<br><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">WXWIDGETS_EXAMPLE_HELLOWORLDAPP_H_20080722</span></div>
<img border=0 src="http://www.cppblog.com/images/cppblog_com/winmain/2.JPG"><br><br>
<img src ="http://www.cppblog.com/winmain/aggbug/73974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2009-02-16 22:59 <a href="http://www.cppblog.com/winmain/archive/2009/02/16/73974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>