User interface 如何在Windows GUI中绘制垂直文本? 我需要在我的C++ C++ Win32 GUI应用程序中绘制一个垂直文本的列(在日语中是从上到下,而不是从左到右)。我浏览了MSDN,只找到了如何从右向左绘制文本

User interface 如何在Windows GUI中绘制垂直文本? 我需要在我的C++ C++ Win32 GUI应用程序中绘制一个垂直文本的列(在日语中是从上到下,而不是从左到右)。我浏览了MSDN,只找到了如何从右向左绘制文本,user-interface,winapi,visual-c++,fonts,User Interface,Winapi,Visual C++,Fonts,除了分别绘制每个字符外,如何从上到下输出文本?纯Win32 API无法以这种方式绘制(未旋转的)垂直文本(使用任意字体),一次只能绘制一个字符 您可以使用 但这也可能不是您想要的,因为文本是垂直的,但字符也会旋转 类似地,您可以使用lfEscapement值为900或2700的CreateFont来获得旋转文本,但这将旋转所有内容。所以这也没用 要进行日文自上而下的绘制,您希望字符不旋转,但每个字符的位置在Y方向前进,而不是在X方向前进。Windows没有针对所有字体执行此操作的API。(可以从

除了分别绘制每个字符外,如何从上到下输出文本?

纯Win32 API无法以这种方式绘制(未旋转的)垂直文本(使用任意字体),一次只能绘制一个字符

您可以使用 但这也可能不是您想要的,因为文本是垂直的,但字符也会旋转

类似地,您可以使用lfEscapement值为900或2700的CreateFont来获得旋转文本,但这将旋转所有内容。所以这也没用

要进行日文自上而下的绘制,您希望字符不旋转,但每个字符的位置在Y方向前进,而不是在X方向前进。Windows没有针对所有字体执行此操作的API。(可以从右到左、从左到右,但不能从上到下)

从理论上讲,创建一个方向为900、转位为2700的字体可以满足您的需要,但如果设置转位,则大多数字体的方向都会被忽略。对于日文字体,这可能会有不同的效果。值得花点时间玩玩。(有关这方面的更多信息,请参见附录)

我认为你最好的选择可能是一次画一个角色的循环,这样你就可以完全控制每个角色的位置

如果使用ETO_不透明绘制列中的第一个字符,而不是与所有其他字符一起绘制,则允许您在需要时垂直紧排字符

补遗 Roygbiv指出了一篇有趣的文章,文章中说,名称以@开头的字体的行为与其他字体不同。当您使用CreateFont时,这些特殊字体的lfEscapement值为2700,这些特殊字体在页面向下移动的同时产生直立字符。因此,虽然无法对任意字体执行所需操作,但您可以使用某些字体使其正常工作


出于好奇,我编写了一个小的控制台应用程序来列举字体和名称。我的Windows Server 2003计算机没有以@开头的字体。但是我的Windows7机器有几个。虽然看起来都是中文字体,但我在默认的Windows7Ultimate安装中没有看到日文字体

在Win32中,使用
LOGFONT
结构的
lfEscapement
成员定义字体的旋转:

LOGFONT LogFont

LogFont.lfEscapement = 900;  // 90 degreees rotated text
... // Many more initializations
HFONT newFont = CreateFontIndirect(LogFont);
SelectObject(hdc, newFont);

char tx[255];
strcpy(tx, "vertical text");
TextOut(hdc, x, y, tx, strlen(tx)); // draw a vertical font
有关更多信息,请参阅结构和功能的联机帮助

只是一个想法:
您是否尝试过使用仅适合最宽字符的非常窄的矩形来使用
DrawText
DrawTextEx

此库使用的方法听起来很慢,但如果确实需要,似乎提供了源代码:

您可能也会发现此讨论很有用——显然,您需要一种垂直字体(以@开头),API将处理其余字体。

正确答案是:

有三种方法可以做到这一点:

  • 使用编辑或控件渲染文本
  • 使用API
  • 使用以at符号(@)开头的字体名称的函数
这篇文章讨论了其中的一些方法

幸运的是,使用Win32,您不需要编写代码来旋转字符。要在Windows 2000和Windows XP上垂直显示文本,请像往常一样枚举可用字体,然后选择字体名称以at符号(@)开头的字体。然后创建LOGFONT结构,将擒纵机构和方向设置为270度。对TextOut的调用与对水平文本的调用相同


作为一种快速的回答,如果使用标准控件(例如CEdit)并在键入的每个字符后插入新行,会发生什么情况?

使用
lfEscapement
(如果需要
lfOrientation
)在许多方面都优于使矩形最小宽度(例如:荷兰语单词“wij”的“i”和“j”相邻,因为它们的组合宽度小于“w”),或在每个字符后插入换行符。

不正确-Win32可以。请参阅我的帖子。请再次阅读问题,在这种情况下,旋转字符没有任何帮助。我收回它,假设这将适用于某些字体,而不是普通的英文字体。考虑到日语混合了汉字、平假名和片假名脚本,这听起来是个坏主意。
HFONT gui_font  =   CreateFont( -MulDiv( 9, GetDeviceCaps( GetDC( hWnd ), LOGPIXELSY ), 72 ),
                        0, 
                        900,  // here
                        0,
                        FW_THIN, 0, 0, 0,
                        DEFAULT_CHARSET,
                        OUT_DEFAULT_PRECIS,
                        CLIP_DEFAULT_PRECIS,
                        DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH,
                        L"Segoe UI" );