📄 基于 linux 和 minigui 的嵌入式系统软件开发指南(四).htm
字号:
键为分界,对多字节字符集文本,单词以单个字符为界。GetFirstMCharLen 函数返回第一个混和文本字符的字节长度。GetFirstWord
函数返回第一个混和文本单词的单词信息。</P>
<P>以下函数可以用来计算逻辑字体的输出长度和高度信息(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>580 int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, int max_extent,
581 int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size);
582
583 // Text output support
584 int GUIAPI GetFontHeight (HDC hdc);
585 int GUIAPI GetMaxFontWidth (HDC hdc);
586 void GUIAPI GetTextExtent (HDC hdc, const char* spText, int len, SIZE* pSize);
587 void GUIAPI GetTabbedTextExtent (HDC hdc, const char* spText, int len, SIZE* pSize);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>GetTextExtentPoint
函数计算在给定的输出宽度内输出多字节文本时(即输出的字符限制在一定的宽度当中),可输出的最大字符个数、每个字符所在的字节位置、每个字符的输出位置,以及实际的输出高度和宽度。GetFontHeight
和 GetMaxFontWidth 则返回逻辑字体的高度和最大字符宽度。GetTextExtent
计算文本的输出高度和宽度。GetTabbedTextExtent 函数返回格式化字符串的输出高度和宽度。</P>
<P>以下函数用来输出文本(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>596 int GUIAPI TextOutLen (HDC hdc, int x, int y, const char* spText, int len);
597 int GUIAPI TabbedTextOutLen (HDC hdc, int x, int y, const char* spText, int len);
598 int GUIAPI TabbedTextOutEx (HDC hdc, int x, int y, const char* spText, int nCount,
599 int nTabPositions, int *pTabPositions, int nTabOrigin);
600 void GUIAPI GetLastTextOutPos (HDC hdc, POINT* pt);
601
602 // Compatiblity definitions
603 #define TextOut(hdc, x, y, text) TextOutLen (hdc, x, y, text, -1)
604 #define TabbedTextOut(hdc, x, y, text) TabbedTextOutLen (hdc, x, y, text, -1)
...
621 int GUIAPI DrawTextEx (HDC hdc, const char* pText, int nCount,
622 RECT* pRect, int nIndent, UINT nFormat);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>TextOutLen 函数用来在给定位置输出指定长度的字符串,若长度为 -1,则字符串必须是以 '\0'
结尾的。TabbedTextOutLen 函数用来输出格式化字符串。TabbedTextOutEx 函数用来输出格式化字符串,但可以指定字符串中每个
TAB 键的位置。DrawText 是功能最复杂的输出函数,可以以不同的对齐方式在指定矩形内部输出文本。下面的程序段,就根据字符串所描述的那样,调用
DrawText 函数进行对齐文本输出:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>void OnModeDrawText (HDC hdc)
{
RECT rc1, rc2, rc3, rc4;
const char* szBuff1 = "This is a good day. \n"
"这是利用 DrawText 绘制的文本, 使用字体 GB2312 Song 12. "
"文本垂直靠上, 水平居中";
const char* szBuff2 = "This is a good day. \n"
"这是利用 DrawText 绘制的文本, 使用字体 GB2312 Song 16. "
"文本垂直靠上, 水平靠右";
const char* szBuff3 = "单行文本垂直居中, 水平居中";
const char* szBuff4 =
"这是利用 DrawTextEx 绘制的文本, 使用字体 GB2312 Song 16. "
"首行缩进值为 32. 文本垂直靠上, 水平靠左";
rc1.left = 1; rc1.top = 1; rc1.right = 401; rc1.bottom = 101;
rc2.left = 0; rc2.top = 110; rc2.right = 401; rc2.bottom = 351;
rc3.left = 0; rc3.top = 361; rc3.right = 401; rc3.bottom = 451;
rc4.left = 0; rc4.top = 461; rc4.right = 401; rc4.bottom = 551;
SetBkColor (hdc, COLOR_lightwhite);
Rectangle (hdc, rc1.left, rc1.top, rc1.right, rc1.bottom);
Rectangle (hdc, rc2.left, rc2.top, rc2.right, rc2.bottom);
Rectangle (hdc, rc3.left, rc3.top, rc3.right, rc3.bottom);
Rectangle (hdc, rc4.left, rc4.top, rc4.right, rc4.bottom);
InflateRect (&rc1, -1, -1);
InflateRect (&rc2, -1, -1);
InflateRect (&rc3, -1, -1);
InflateRect (&rc4, -1, -1);
SelectFont (hdc, logfontgb12);
DrawText (hdc, szBuff1, -1, &rc1, DT_NOCLIP | DT_CENTER | DT_WORDBREAK);
SelectFont (hdc, logfontgb16);
DrawText (hdc, szBuff2, -1, &rc2, DT_NOCLIP | DT_RIGHT | DT_WORDBREAK);
SelectFont (hdc, logfontgb24);
DrawText (hdc, szBuff3, -1, &rc3, DT_NOCLIP | DT_SINGLELINE | DT_CENTER | DT_VCENTER);
SelectFont (hdc, logfontgb16);
DrawTextEx (hdc, szBuff4, -1, &rc4, 32, DT_NOCLIP | DT_LEFT | DT_WORDBREAK);
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>有关逻辑字体和文本输出的函数详细使用方法,可见 mglite-exec 包中的 fontest 示例程序。</P>
<P><A id=7 name=7><SPAN class=atitle2>7 小结</SPAN></A><BR>本文讲述了 MiniGUI
中接口最多也最复杂的 GDI
函数及其使用方法。其中包括:设备上下文的概念、获取和释放;矩形操作和区域操作;基本绘图函数;位图操作函数;逻辑字体操作函数等等。目前版本的 GDI
接口还有许多功能上的缺陷,我们将在下一个版本开发中着重进行改善。关于 MiniGUI 下一版本的开发计划,请参见本文附录。</P>
<P><SPAN class=atitle3>附录:MiniGUI 的最新开发计划</SPAN><BR>MiniGUI
发展到今天,得到了许多用户的认可,使用它的人也越来越多了。目前,用户已经从国内发展到了国外。这说明 MiniGUI
当中的许多设计思想得到了认可,也大大激励了我们的开发热情。</P>
<P>作为一个面向实时嵌入式系统的 GUI,MiniGUI 的 1.0.xx
版本基本能够满足许多嵌入式系统的应用需求。但这还远远不够,我们仍然需要进一步的开发,以便让 MiniGUI 在嵌入式 GUI
系统中达到领先地位。</P>
<P>MiniGUI 发展到今天,得到了许多用户的认可,使用它的人也越来越多了。目前,用户已经从国内发展到了国外。这说明 MiniGUI
当中的许多设计思想得到了认可,也大大激励了我们的开发热情。</P>
<P>作为一个面向实时嵌入式系统的 GUI,MiniGUI 的 1.0.xx
版本基本能够满足许多嵌入式系统的应用需求。但这还远远不够,我们仍然需要进一步的开发,以便让 MiniGUI 在嵌入式 GUI
系统中达到领先地位。</P>
<P>我们已经开始了 MiniGUI 新版本开发(即 1.1.xx),对这个版本,有如下新的设想:</P>
<OL class=n01>
<LI>MiniGUI-Lite 的全局鼠标支持。目前的 MiniGUI-Lite
版本,鼠标的位置刷新是由鼠标所在客户或者服务器管理的。新版本中,将考虑由服务器统一管理。这个工作目前已经基本完成。
<LI>在 MiniGUI-Lite 中添加层(Layer)的概念和处理。在一次 MiniGUI-Lite
会话中,可以建立多个层。每个层中可以包含能够同时向屏幕输出的多个客户,而每一时刻,能够在屏幕上显示的层只有一个。对层而言,我们可以进行层的激活处理。激活的层,将显示在屏幕上,而其他层的绘图将被屏蔽。对层中客户的绘图屏蔽算法,将考虑使用不同于当前
MiniGUI-Lite 通过信号和信号量结合的方法,因为这种方法在多线程应用中,可能出现问题。
<LI>层中客户可以互相剪切。后建立的客户,将剪切先建立的客户矩形。为此,要为每个层建立一个共享内存的 IPC
对象,客户通过该对象访问当前层客户之间的重叠和覆盖情况,而且要建立一个面向层的信号量和 age
值,用来协调客户剪切矩形的变化。层的客户剪切矩形的变化,将影响各个客户所建立窗口的全局剪切区域,从而影响 DC 的可见区域。
<LI>一个层中客户之间形成的 Z 序是固定的。不过,如果按照 3 所描述的方法,其实 Z
序也是可以变化的。考虑到性能因素,客户在层中所占的显示矩形不能变化,也就是说,既不能改变大小,也不能移动。但能够改变 Z
序,即改变客户之间的互相层叠关系。
<P>BTW:为什么要如此考虑?<BR>通过上面的方法,可以将一组具有共同目标的客户放置在同一个层上。比如,层中可以有一个 vcongui
程序,用它可以调试其他的 MiniGUI 程序。再比如,在 VOD 等程序中,实时播放 VCD
的客户就可以嵌入到主控界面当中。而服务器将具有较少的 GUI 能力,仅仅提供一个任务栏,用来激活某个层,或者改变客户在一个层中的 Z
序。</P>
<P>当然,这样安排对某些小屏幕的嵌入式应用来讲,比如 PDA,并不是非常适合,但对
STB、或者其他具有大屏幕的实时嵌入式系统来讲,将具有非常高的应用价值。</P>
<LI>底层图形引擎将进行非常重大的修改,这将影响到 MiniGUI-Threads 和 MiniGUI-Lite 两个版本。目前的
MiniGUI 图形引擎,因为受到历史原因的影响,有许多弊端。在新的版本中,我们将考虑类似 SDL
那样的设计方法,将底层图形设备抽象为一个内存对象,并考虑加速功能的实现。同时,我们还要实现许多尚未实现的图形功能,包括光栅操作、Alpha
混和、多边形支持、椭圆和弧线支持等等。
<P>BTW:当前 GAL 的设计弊端<BR>当前 GAL
的设计弊端主要是抽象层次太高,而且并没有在底层实现剪切域的直接支持。这是要在新版本中着重考虑改进的。新的剪切域算法,将考虑生成
x-y-banned 的剪切域,以便底层绘图函数能够直接利用剪切域进行设计绘图算法。</P>
<LI>将考虑在 MiniGUI-Lite 版本中实现对矢量字体的支持,同时增加 Cache 处理能力,以便提高矢量字体的渲染效率。
<LI>对窗口管理,在这次开发中将不作大的修改,主要将进行一些代码的清理工作。 </LI></OL><BR><BR>
<P>以上是我们对新版本的一些想法,希望大家能够讨论,并请多提建议和意见。我们将考虑首先实现层,然后实现图形引擎的改进,最后实现矢量字体在
MiniGUI-Lite 当中的支持及优化。如果您对 MiniGUI 新版本的开发有兴趣,可以加入我们的邮件列表,详细信息请参见<A
href="http://www.minigui.org/ctalk.shtml">http://www.minigui.org/ctalk.shtml</A>。</P><!-- AUTHOR BIOS --><!-- Make author heading singular or plural as needed -->
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><A id=author1 name=author1><SPAN class=atitle2>关于作者</SPAN></A>
<BR>魏永明(<A
href="mailto:ymwei@minigui.org">ymwei@minigui.org</A>),男,27
岁,工学硕士。国内最有影响的自由软件项目之一--MiniGUI 的创始人及主要开发人员。著有《Linux 实用教程》与《学用 Linux
与 Windows NT》,并主持翻译了《Red Hat Linux 奥秘》、《Linux 编程宝典》 等大量优秀的 Linux
技术著作。是清华大学 AKA Linux
编程技术系列讲座的主讲人。</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><!-- END PAPER BODY -->
<TABLE>
<TBODY>
<TR>
<TD width=10><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(四).files/c.gif" width=10
border=0></TD></TR></TBODY></TABLE><BR clear=all><IMG height=10 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(四).files/c.gif" width=100 border=0><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD align=right width="100%"><A
href="http://www-900.ibm.com/developerWorks/cn/linux/embed/minigui/guide/part4/index.shtml#top">到页首</A></TD>
<TD width=5><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(四).files/c.gif" width=5
border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#000000 colSpan=2><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(四).files/c.gif" width=100
border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff colSpan=2><IMG height=8 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(四).files/c.gif" width=100
border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=10 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD>
<FORM action=/developerWorks/cn/cnratings.nsf/RateArticle?CreateDocument
method=post><INPUT type=hidden
value="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南:使用 GDI 函数" name=ArticleTitle>
<INPUT type=hidden value=linux name=Zone> <INPUT type=hidden
value=/developerWorks/cn/thankyou/feedback-linux.html name=RedirectURL> <A
id=rating name=rating><B>您对这篇文章的看法如何?</B></A>
<TABLE cellSpacing=0 cellPadding=0 width=600 border=0>
<TBODY>
<TR>
<TD colSpan=5><IMG height=8 alt=""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -