中国人自古就有自右至左、从上到下书写汉字的习惯。而当我们在自己所编写的应用程序中使用输出函数输出的总是自左至右的横排文字。有没有可能在我们的应用程序中实现竖写汉字的效果呢?笔者偶然发现了一种利用VC实现竖写汉字效果的方法,现在就把它介绍给大家。

  

Windows系统内置了许多名称以“@”开头的字集,这些字集有一个共同的特点,即其所包含的文字全都是平躺着的(字头朝左,字底朝右)。如果我们能将这些字逆时针旋转270度后再显示出来,就可以达到实现竖写汉字效果的目的了。

  要使文字发生旋转,我们只需创建一个逻辑字体并设定该逻辑字体的显示角度,再设定其字体名称为一个以“@”开头的字集的名称即可。我们可以采用两种方式创建逻辑字体。

  其一,用CFont类的成员函数CreateFont直接创建逻辑字体。CreateFont的参数定义如下:

BOOL CreateFont( 
                 int nHeight,           //字体的高度
                 int nWidth,            //字体的宽度
                 int nEscapement,       //字体显示的角度
                 int nOrientation,      //字体的角度
                 int nWeight,           //字体的磅数
                 BYTE bItalic,          //斜体字体
                 BYTE bUnderline,       //带下划线的字体
                 BYTE cStrikeOut,       //带删除线的字体
                 BYTE nCharSet,         //所需的字符集
                 BYTE nOutPrecision,    //输出的精度
                 BYTE nClipPrecision,   //裁减的精度 
                 BYTE nQuality,         //逻辑字体与输出设备的实际
                                        //字体之间的精度
                 BYTE nPitchAndFamily,  //字体间距和字体集
                 LPCTSTR lpszFacename   //字体名称
               );

  其中nEscapement单位为0.1角度,方向为逆时针,所以为了使平躺的字立起来应设定其值为2700,lpszFacename则赋以“@”开头的字集的名称,如“@system”。

  其二,利用LOGFONT结构,将该结构作为参数调用CFont类的成员函数CreateFontIndirect创建逻辑字体。LOGFONT结构通常被用来描述一种逻辑字体,结构内的各变量分别代表逻辑字体的各个属性,这些变量与函数CreateFont的参数相同。其结构如下:

typedef struct tagLOGFONT { // lf 
          LONG lfHeight;         //字体的高度
          LONG lfWidth;          //字体的宽度
          LONG lfEscapement;     //字体显示的角度 
          LONG lfOrientation;    //字体的角度
          LONG lfWeight;         //字体的磅数
          BYTE lfItalic;         //斜体字体
          BYTE lfUnderline;      //带下划线的字体
          BYTE lfStrikeOut;      //带删除线的字体
          BYTE lfCharSet;        //所需的字符集
          BYTE lfOutPrecision;   //输出的精度
          BYTE lfClipPrecision;  //裁减的精度
          BYTE lfQuality;        //逻辑字体与输出设备的
                                           //实际字体之间的精度
          BYTE lfPitchAndFamily; //字体间距和字体集
          TCHAR lfFaceName[LF_FACESIZE]; //字体名称
} LOGFONT;

  下面我们就以一个示例来说明竖写汉字的实现方法:

  1.建立一个MFC AppWizard(exe)应用工程CHNfont。在MFC AppWizard向导的第一步中选择Single Document,再点击按键Finish->OK完成工程的建立。

  2.在CMainFrame::OnCreate函数中添加如下代码,使窗体最大化。AfxGetMainWnd()->ShowWindow(SW_SHOWMAXIMIZED);

  3.添加如下代码实现竖写功能。

void CChildView::OnPaint() 
       {
CPaintDC dc(this);// device context for painting

/////// 利用CFont::CreateFont(...)函数实现竖写汉字////////
CFont myFont;     //创建字体对象

//创建逻辑字体
myFont.CreateFont(
              56,        //字体高度(旋转后的字体宽度)=56 
              20,        //字体宽度(旋转后的字体高度)=20
              2700,       //字体显示角度=270°
              0,                  //nOrientation=0
              10,                 //字体磅数=10
              FALSE,              //非斜体
              FALSE,              //无下划线
              FALSE,       //无删除线
              DEFAULT_CHARSET,    //使用缺省字符集
              OUT_DEFAULT_PRECIS, //缺省输出精度
              CLIP_DEFAULT_PRECIS,//缺省裁减精度 
              DEFAULT_QUALITY,    //nQuality=缺省值
              DEFAULT_PITCH,      //nPitchAndFamily=缺省值
              "@system");         //字体名=@system
CFont *pOldFont=dc.SelectObject(&myFont);//选入设备描述表
CRect rtClient;
GetClientRect(rtClient);   //获取客户区尺寸、位置信息
//在客户区适当位置输出文字
dc.TextOut(rtClient.Width()/2+30,rtClient.Height()/8,
               "无边落木萧萧下");
dc.SelectObject(pOldFont); //将myFont从设备环境中分离
myFont.DeleteObject();     //删除myFont对象

/////////// 利用LOGFONT结构实现竖写汉字//////////////
LOGFONT lf;                     //定义字体结构
lf.lfWeight=10;                 //字体磅数=10
lf.lfHeight=56;      //字体高度(旋转后的字体宽度)=56 
lf.lfWidth=20;                  //字体宽度(旋转后的字体高度)=20
lf.lfUnderline=FALSE;           //无下划线
lf.lfStrikeOut=FALSE;           //无删除线
lf.lfItalic=FALSE;              //非斜体
lf.lfEscapement=2700;           //字体显示角度=270°
lf.lfCharSet=DEFAULT_CHARSET;   //使用缺省字符集
        strcpy(lf.lfFaceName,"@system"); //字体名=@system
    
CFont myLogFont;                   //定义字体对象
myLogFont.CreateFontIndirect(&lf); //创建逻辑字体
pOldFont=dc.SelectObject(&myLogFont);//选入设备描述表
//在客户区适当位置输出文字
dc.TextOut(rtClient.Width()/2-30,rtClient.Height()/8,
                 "不尽长江滚滚来");
dc.SelectObject(pOldFont); //将myFont从设备环境中分离
myLogFont.DeleteObject();  //删除myLogFont对象
       }
 
4.编译连接,运行。

以上实例在Windows98下,以VC++6.0编译通过。

用VC实现竖写汉字的方法的更多相关文章

  1. springmvc2 一个控制器写多个方法(非注解方式)

    出处:http://blog.csdn.net/xuewenke/article/details/23895999 springmvc2 一个控制器写多个方法(非注解方式) 分类: spring 20 ...

  2. VC++获取IDC_EDIT的7种方法

    VC++获取IDC_EDIT的7种方法 http://blog.csdn.net/baizengfei/article/details/7997618 //第一种方法 int number1, num ...

  3. struts2 action配置时 method 省略不写 默认执行方法是父类ActionSuppot中的execute()方法

    struts2 action配置时 method 省略不写 默认执行方法是父类ActionSuppot中的execute()方法

  4. SpringMVC实现一个controller写多个方法

    MultiActionController与ParameterMethodNameResolver在一个Controller类中定义多个方法,并根据使用者的请求来执行当中的某个方法,相当于Struts ...

  5. 使用第三方工具覆写Object中方法

    我们在实际开发中,经常需要覆写Object中的equals,hashcode,toString方法,其实编写这些代码并不是很难,但很枯燥和乏味. 下面推荐Google的Guava jar包来覆写上面的 ...

  6. CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写

    Q: CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写 A: 建议统一写,CI框架会自动识别已经加载过的类,所以不用担心重复加载的问题 class C_User ...

  7. VC中调用COM组件的方法(转载)

    原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...

  8. 应用反射写的tostring方法

    应用反射写的tostring方法 应用反射写的tostring方法,方便以后查询 代码 package com.chzhao.reflecttest; import java.lang.reflect ...

  9. [改善Java代码]覆写变长方法也循规蹈矩

    建议6:覆写变长方法也循规蹈矩 在Java中,子类覆写父类中的方法很常见,这样做既可以修正Bug也可以提供扩展的业务功能支持,同时还符合开闭原则(Open-Closed Principle),我们来看 ...

随机推荐

  1. Linux远程桌面工具 -- NoMachine

    玩Linux系统,会经常用到远程桌面软件. 我一直用的2个是Xmanager 和 VNC. 今天看到一个新软件: NoMachine. NoMachine NX 是一个快速的终端服务器和虚拟桌面软件, ...

  2. java困惑(二)函数以及引用改变

    具体的Visio 文档在资源

  3. Case of the Zeros and Ones

    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description Andrew ...

  4. 解决打包时IsCmdBld.exe出错的问题

    1.查看环境变量是否配置了 2.查看是否是使用administrator登陆的,要求使用administrator登陆否则可能会出现权限不足的现象

  5. TCP连接状态具体解释

    tcp状态: LISTEN:侦听来自远方的TCPport的连接请求 SYN-SENT:再发送连接请求后等待匹配的连接请求 SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认 ...

  6. Java 生成本文文件的时候,Dos格式转成Unix格式

    仅仅须要在生成文本的最后 加上 sb.append("\n\r");就可以 是/n/r 不是/r/n

  7. Linux入门:文件权限、用户、用户组(比较清楚)

    单个文件名或目录名长度不超过255字符: 文件或目录的绝对路径长度不超过4096字符:   一.文件所有者与用户组     一个文件有很多属性,包括文件类型.文件权限.文件隐藏权限.文件所有者.用户组 ...

  8. Pro Android 4 第五章 理解Intent

         Android引入了一个名为Intent的概念用来唤醒各种组件.Android中的组件包括:activities(UI 组件),services(后台代码),broadcast receiv ...

  9. cocos2d-x游戏开发系列教程-坦克大战游戏之坦克的显示

    1.先定义坦克的一些属性 class Tank : public CCSprite { public : Tank(); ~Tank(); static Tank* createTankWithTan ...

  10. MSSQL - SqlDataAdapter连接数据库提高性能用法

    SqlDataAdapter 与 SqlConnection 和 SqlCommand 一起使用,以便在连接到 SQL Server 数据库时提高性能. SqlDataAdapter 的这一实现自动打 ...