📄 基于 linux 和 minigui 的嵌入式系统软件开发指南(四).htm
字号:
映射模式</SPAN><BR>一个设备上下文被初始化之后,其坐标系原点通常是输出矩形的左上角,而 x 轴水平向左,y
轴垂直向下,并以象素为单位。这种坐标的映射模式标识为 MM_TEXT。MiniGUI
提供了一套函数,可以改变这种映射方式,包括对默认坐标系进行偏移、缩放等操作。这些函数的原型如下(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>453 int GUIAPI GetMapMode (HDC hdc);
454 void GUIAPI GetViewportExt (HDC hdc, POINT* pPt);
455 void GUIAPI GetViewportOrg (HDC hdc, POINT* pPt);
456 void GUIAPI GetWindowExt (HDC hdc, POINT* pPt);
457 void GUIAPI GetWindowOrg (HDC hdc, POINT* pPt);
458 void GUIAPI SetMapMode (HDC hdc, int mapmode);
459 void GUIAPI SetViewportExt (HDC hdc, POINT* pPt);
460 void GUIAPI SetViewportOrg (HDC hdc, POINT* pPt);
461 void GUIAPI SetWindowExt (HDC hdc, POINT* pPt);
462 void GUIAPI SetWindowOrg (HDC hdc, POINT* pPt);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>GetMapMode 函数返回当前的映射模式,若不是 MM_TEXT 模式,则返回MM_ANISOTROPIC。SetMapMode
函数设置映射模式,MiniGUI 目前只支持两种映射模式,即MM_ANISOTROPIC 和 MM_TEXT。Get
函数组用来返回映射模式信息,包括偏移量、缩放比例等等,而 Set 函数组用来设置相应的映射信息。</P>
<P>通常情况下,MiniGUI 的 GDI 函数所指定的坐标参数称为"逻辑坐标",在绘制之前,首先要转化成"设备坐标"。当使用 MM_TEXT
映射模式时,逻辑坐标和设备坐标是等价的。LPtoDP 函数用来完成逻辑坐标到设备坐标的转换,DPtoLP
函数用来完成从设备坐标到逻辑坐标的转换。逻辑坐标和设备坐标的关系可从 LPtoDP 函数中看到(src/gdi/coor.c):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE> 61 void GUIAPI LPtoDP(HDC hdc, POINT* pPt)
62 {
63 PDC pdc;
64
65 pdc = dc_HDC2PDC(hdc);
66
67 if (pdc->mapmode != MM_TEXT) {
68 pPt->x = (pPt->x - pdc->WindowOrig.x)
69 * pdc->ViewExtent.x / pdc->WindowExtent.x
70 + pdc->ViewOrig.x;
71
72 pPt->y = (pPt->y - pdc->WindowOrig.y)
73 * pdc->ViewExtent.y / pdc->WindowExtent.y
74 + pdc->ViewOrig.y;
75 }
76 }
77
</CODE>
</PRE></TD></TR></TBODY></TABLE>另外,LPtoSP 函数和 SPtoLP
函数完成逻辑坐标和屏幕坐标之间的转换。<BR><BR>
<P><A id=3 name=3><SPAN class=atitle2>3 矩形操作和区域操作</SPAN></A><BR><SPAN
class=atitle3>3.1 矩形操作</SPAN><BR>在 MiniGUI
中,矩形是如下定义的(include/common.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>120 typedef struct tagRECT
121 {
122 int left;
123 int top;
124 int right;
125 int bottom;
126 } RECT;
127 typedef RECT* PRECT;
128 typedef RECT* LPRECT;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>简而言之,矩形就是用来表示屏幕上一个矩形区域的数据结构,定义了矩形左上角的 x, y 坐标(left 和 top)以及右下角的 x, y
坐标(right 和 bottom)。需要注意的是,MiniGUI
中的矩形,其右侧的边和下面的边是不属于该矩形的。例如,要表示屏幕上的一条扫描线,应该用<BR><CODE>RECT rc = {x, y, x +
w + 1, y + 1};</CODE><BR>表示。其中 x 是扫描线的起点,y 是扫描线的垂直位置,w 是扫描线宽度。</P>
<P>MiniGUI 提供了一组函数,可对 RECT 对象进行操作:</P>
<UL class=n01>
<LI>SetRect 对 RECT 对象的各个分量进行赋值;
<LI>SetRectEmpty 将 RECT 对象设置为空。MiniGUI 中的空矩形定义为高度或宽度为零的矩形;
<LI>IsRectEmpty 判断给定 RECT 对象是否为空。
<LI>NormalizeRect 对给定矩形进行正规化处理。MiniGUI 中的矩形,应该满足(right > left 并且
bottom > top)的条件。满足这一条件的矩形又称"正规化矩形",该函数可以对任意矩形进行正规化处理。
<LI>CopyRect 复制矩形;
<LI>EqualRect 判断两个 RECT 对象是否相等,即两个 RECT 对象的各个分量相等;
<LI>IntersectRect 该函数求两个 RECT 对象之交集。若两个矩形根本不相交,则函数返回
FALSE,且结果矩形未定义;否则返回交矩形。
<LI>DoesIntersec 该函数仅仅判断两个矩形是否相交。
<LI>IsCovered 该函数判断 RECT 对象 A 是否全部覆盖 RECT 对象 B,即 RECT B 是 RECT A 的真子集。
<LI>UnionRect 该函数求两个矩形之并。如果两个矩形根本无法相并,则返回
FALSE。两个相并之后的矩形,其中所包含的任意点,应该属于两个相并矩形之一。
<LI>GetBoundRect 该函数求两个矩形的外包最小矩形。
<LI>SubstractRect 该函数从一个矩形中减去另外一个矩形。注意,两个矩形相减的结果可能生成 4
个不相交的矩形。该函数将返回结果矩形的个数以及差矩形。详细信息可参见"MiniGUI 体系结构之二――多窗口管理和控件及控件类"一文。
<LI>OffsetRect 该函数对给定的 RECT 对象进行平移处理。
<LI>InflateRect 该函数对给定的 RECT 对象进行膨胀处理。注意膨胀之后的矩形宽度和高度是给定膨胀值的两倍。
<LI>InflateRectToPt 该函数将给定的 RECT 对象膨胀到指定的点。
<LI>PtInRect 该函数判断给定的点是否位于指定的 RECT 对象中。 </LI></UL><BR><BR>
<P><SPAN class=atitle3>3.2 区域操作</SPAN><BR>在 MiniGUI
中,区域定义为互不相交矩形的集合,在内部用链表形式表示。MiniGUI 的区域可以用来表示窗口的剪切域、无效区域、可见区域等等。在 MiniGUI
中,区域和剪切域的定义是一样的,剪切域定义如下(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE> 76 // Clip Rect
77 typedef struct tagCLIPRECT
78 {
79 RECT rc;
80 struct tagCLIPRECT* next;
81 }CLIPRECT;
82 typedef CLIPRECT* PCLIPRECT;
83
84 // Clip Region
85 typedef struct tagCLIPRGN
86 {
87 RECT rcBound; // bound rect of clip region
88 PCLIPRECT head; // clip rect list head
89 PCLIPRECT tail; // clip rect list tail
90 PBLOCKHEAP heap; // heap of clip rect
91 } CLIPRGN;
92 typedef CLIPRGN* PCLIPRGN;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>每个剪切域对象有一个 BLOCKHEAP 成员。该成员是剪切域分配 RECT 对象的私有堆。在使用一个剪切域对象之前,首先应该建立一个
BLOCKHEAP 对象,并对剪切域对象进行初始化。如下所示:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>static BLOCKHEAP sg_MyFreeClipRectList;
...
CLIPRGN my_region
InitFreeClipRectList (&sg_MyFreeClipRectList, 20);
InitClipRgn (&my_regioni, &sg_MyFreeClipRectList);
</CODE>
</PRE></TD></TR></TBODY></TABLE>在实际使用当中,多个剪切域可以共享同一个 BLOCKHEAP 对象。<BR><BR>
<P>在初始化剪切域对象之后,可以对剪切域进行如下操作:</P>
<UL class=n01>
<LI>SetClipRgn 该函数将剪切域设置为仅包含一个矩形的剪切域;
<LI>ClipRgnCopy 该函数复制剪切域;
<LI>ClipRgnIntersect 该函数求两个剪切域的交集;
<LI>GetClipRgnBoundRect 该函数求剪切域的外包最小矩形;
<LI>IsEmptyClipRgn 该函数判断剪切域是否为空,即是否包含剪切矩形;
<LI>EmptyClipRgn 该函数释放剪切域中的剪切矩形,并清空剪切域;
<LI>AddClipRect 该函数将一个剪切矩形追加到剪切域中。注意该操作并不判断该剪切域是否和剪切矩形相交。
<LI>IntersectClipRect 该函数求剪切区域和给定矩形相交的剪切区域。
<LI>SubtractClipRect 该函数从剪切区域中减去指定的矩形。 </LI></UL>矩形和区域的运算构成了窗口管理的主要算法,也是高级
GDI 函数的基本算法之一,在 GUI 编程中占有非常重要的地位。<BR><BR>
<P><A id=4 name=4><SPAN class=atitle2>4 基本图形操作</SPAN></A><BR><SPAN
class=atitle3>4.1 基本绘图属性</SPAN><BR>在了解基本绘图函数之前,我们首先了解一下基本绘图属性。在 MiniGUI
的目前版本中,绘图属性比较少,大体包括线条颜色、填充颜色、文本背景模式、文本颜色、TAB 键宽度等等。表 1 给出了这些属性的操作函数。</P>
<P>表 1 基本绘图属性及其操作函数</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" border=1>
<TBODY>
<TR>
<TD>绘图属性</TD>
<TD>操作函数</TD>
<TD>受影响的 GDI 函数</TD></TR>
<TR>
<TD>线条颜色</TD>
<TD>GetPenColor/SetPenColor</TD>
<TD>LineTo、Circle、Rectangle</TD></TR>
<TR>
<TD>填充颜色</TD>
<TD>GetBrushColor/SetBrushColor</TD>
<TD>FillBox</TD></TR>
<TR>
<TD>文本背景模式</TD>
<TD>GetBkMode/SetBkMode</TD>
<TD>TextOut、DrawText</TD></TR>
<TR>
<TD>文本颜色</TD>
<TD>GetTextColor/SetTextColor</TD>
<TD>同上</TD></TR>
<TR>
<TD>TAB 键宽度</TD>
<TD>GetTabStop/SetTabStop</TD>
<TD>同上</TD></TR></TBODY></TABLE>MiniGUI
目前版本中还定义了刷子和笔的若干函数,这些函数是为将来兼容性而定义的,目前无用。<BR><BR>
<P><SPAN class=atitle3>4.2 基本绘图函数</SPAN><BR>MiniGUI
中的基本绘图函数为点、线、圆、矩形、调色板操作等基本函数,原型定义如下(include/gdi.h,版本 1.0.06):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>433 // Palette support
434 int GUIAPI GetPalette (HDC hdc, int start, int len, gal_color* cmap);
435 int GUIAPI SetPalette (HDC hdc, int start, int len, gal_color* cmap);
436 int GUIAPI SetColorfulPalette (HDC hdc);
437
438 // General drawing support
439 void GUIAPI SetPixel (HDC hdc, int x, int y, gal_pixel c);
440 void GUIAPI SetPixelRGB (HDC hdc, int x, int y, int r, int g, int b);
441 gal_pixel GUIAPI GetPixel (HDC hdc, int x, int y);
442 void GUIAPI GetPixelRGB (HDC hdc, int x, int y, int* r, int* g, int* b);
443 gal_pixel GUIAPI RGB2Pixel (HDC hdc, int r, int g, int b);
444
445 void GUIAPI LineTo (HDC hdc, int x, int y);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -