`
lingzantia
  • 浏览: 150054 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

[翻译]-WinCE 程序设计 (3rd 版)--2.4 线条和形状

阅读更多

线条和形状
同Windows其它版本相比,Windows CE提供相当少的功能的领域之一就是基本线条绘制和形状绘制功能。用来创建复杂环形的Chord, Arc, 和Pie函数被去掉了。大部分使用"当前点[current point]"概念的函数也被去掉了。除了MoveToEx, LineTo和GetCurrentPositionEx外,处理当前点的其它GDI函数都不被Windows CE支持。因此想用 ArcTo、PolyBezierTo等函数来绘制一系列连接的直线和曲线是不可能了。不过即使在缺少很多图形函数的情况下,Windows CE依然提供了绘制直线和形状所需要的基本函数。

线条
简单调用Polyline就可以绘制一个或者多个线条了。函数原型如下:

BOOL Polyline (HDC hdc, const POINT *lppt, int cPoints);
第2个参数是指向POINT结构数组的指针,该结构定义如下:
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT

每个X、Y结合起来描述一个从屏幕左上角开始的像素。第三个参数是数组里的point结构的数量。因此绘制一个从(0,0)到(50,100)的直线,代码看起来如下:
POINTS pts[2];

pts[0].x = 0;
pts[0].y = 0;
pts[1].x = 50;
pts[1].y = 100;
PolyLine (hdc, &pts, 2);

绘制该直线的另外一个方法是使用MoveToEx和LineTo函数。它们的原型如下:
BOOL WINAPI MoveToEx (HDC hdc, int X, int Y, LPPOINT lpPoint);
BOOL WINAPI LineTo (HDC hdc, int X, int Y);

要使用这两个函数绘制线条,首先要调用MoveToEx将当前点移动到线条的起始坐标处,接下来用终点坐标调用LineTo。调用代码如下:
MoveToEx (hdc, 0, 0, NULL);
LineTo (hdc, 50, 100);

要查询当前点,可调用函数GetCurrentPositionEx,原型如下:
WINGDIAPI BOOL WINAPI GetCurrentPositionEx (HDC hdc, LPPOINT pPoint);

和前面绘制文本的例子一样,这些代码片段对设备描述表的状态做了大量假设。例如,绘制的(0, 0)和(50, 100)之间的线条是什么样子?宽度和颜色是什么以及是实心线条吗?所有版本的Windows,包括Windows CE在内,都允许指定这些参数。

画笔
画笔(pen)是用于指定线条外观和形状轮廓的工具。画笔是另一个GDI对象,像本章里描述的其它GDI对象一样,画笔要被创建、选进设备描述表,使用、取消选择,最后被销毁。 同其它备用GDI对象一样,可以使用GetStockObject来检索备用画笔。该函数原型如下:
HGDIOBJ GetStockObject (int fnObject);
所有版本的Windows都提供三种备用画笔,每个1像素宽。这些备用画笔有3种颜色:白色、黑色和NULL。当您使用GetStockObject时,该函数分别使用参数WHITE_PEN, BLACK_PEN和NULL_PEN来检索这些画笔中的一个。与应用程序创建的标准图形对象不同,备用对象不应该被应用程序删除。相反,当画笔不再需要的时候,应用程序只应简单地将画笔从设备描述表中取消选择即可。

要在Windows下创建自定义画笔,可以使用以下两个函数。第一个是:
HPEN CreatePen (int fnPenStyle, int nWidth, COLORREF crColor);
fnPenStyle规定要绘制的线条的外观。例如,使用PS_DASH标志可以创建一个虚线。Windows CE只支持PS_SOLID、PS_DASH和PS_NULL这三个风格标志。nWidth参数规定画笔的宽度。最后,crColor规定画笔的颜色。crColor的参数类型是COLORREF,可以使用RGB宏来构造该类型。RGB宏定义如下:

COLORREF RGB (BYTE bRed, BYTE bGreen, BYTE bBlue);
因此要创建一个红色实心线条,代码看起来像这样:
hPen = CreatePen (PS_SOLID, 1, RGB (0xff, 0, 0));

另一种画笔创建函数如下:
HPEN CreatePenIndirect (const LOGPEN *lplgpn);
其中逻辑画笔结构LOGPEN定义如下:
typedef struct tagLOGPEN {
UINT lopnStyle;
POINT lopnWidth;
COLORREF lopnColor;
} LOGPEN;
CreatePenIndirect用不同的形式为Windows提供了同样的参数。用CreatePenIndirect创建同样是1像素宽的红色画笔,代码如下:
LOGPEN lp;
HPEN hPen;
lp.lopnStyle = PS_SOLID;
lp.lopnWidth.x = 1;
lp.lopnWidth.y = 1;
lp.lopnColor = RGB (0xff, 0, 0);

hPen = CreatePenIndirect (&lp);

Windows CE不支持复杂画笔,比如宽度超过1像素的虚线。要确定支持什么,我们熟悉的GetDeviceCaps就派上用场了,给它的第2个参数取LINECAPS即可。具体可以参考Windows CE文档。

形状
线条很有用,不过Windows还提供了绘制形状的函数,包括填充和非填充的形状。Windows CE提供了Windows程序员大部分常见的函数。

Rectangle, RoundRect, Ellipse和Polygon都支持。

画刷
在讨论矩形和椭圆形之前,需要先讲述另一个曾经简要提到过的GDI对象--画刷(brush)。画刷通常是一个8*8像素的位图,用于填充形状。
Windows也用它来填充客户窗口地背景。Windows CE提供许多备用画刷,并提供从应用程序定义的图案创建画刷的能力。许多纯色备用画刷可以使用GetStockObject来检索。在众多可用画刷中,有一个是用于四色灰度级显示器的每个灰度的,四种灰度是:白色、浅灰色、深灰色和黑色。

要创建纯色画刷,可以调用以下函数:
HBRUSH CreateSolidBrush (COLORREF crColor);
crColor规定了画刷的颜色。颜色可以使用RGB宏来指定。
Windows CE下用Win32函数 CreateDIBPatternBrushPt创建自定义图案的画刷。函数原型如下:
HBRUSH CreateDIBPatternBrushPt (const void *lpPackedDIB, UINT iUsage);
第一个参数指向紧凑格式的DIB。这意味着指针指向一个缓冲区,包含有BITMAPINFO结构,并且紧随其后的是位图的位数据。您应该还记得BITMAPINFO结构实际上由BITMAPINFOHEADER结构及紧随其后的RGBQUAD格式的调色板构成,所以该缓冲区包含了创建DIB所需要的每个信息,即位图信息、调色板、位图的位数据。如果第二个参数设置为DIB_RGB_COLORS,则调色板在每个入口都包含有RGBQUAD值。对于每像素8位的位图来说,可以设置DIB_PAL_COLORS标志,但Windows CE会忽略位图的颜色表。

在Windows CE下CreateDIBPatternBrushPt更加重要,因为Windows CE下不支持阴影画刷,而其它版本的Windows使用CreateHatchBrush函数来支持阴影画刷。阴影画刷是由水平线条、垂直线条或斜线构成的画刷。这些画刷在灰度级显示器上特别有用,因为您可以使用不同阴影图案来突出图表的不同区域。不过,您可以使用CreateDIBPatternBrushPt和适当的位图图案来复制出这些画刷。本章后面的示例代码演示了在Windows CE下创建阴影画刷的方法。

默认情况下,画刷原点在窗口左上角。这并不总是你所希望的。例如,一个条形图使用阴影画刷填充从(100,100)到(125,220)的矩形。因为该矩形不能被8(画刷通常是8*8像素的正方形)整除,所以就用一个不怎么美观的局部画刷来填充条形图的左上角。为了避免这种情况,您可以移动画刷的原点,这样可以使用与形状的边角正确对齐的画刷来绘制各个形状了。用来完成这一调整的函数如下:BOOL SetBrushOrgEx (HDC hdc, int nXOrg, int nYOrg, LPPOINT lppt);
nXOrg和nYOrg允许将原点设置为0到7之间,这样就可以将原点定位在画刷8*8范围内任何一点。lppt填充的是画刷先前的版本,这样可以在必要的时候恢复先前的原点。

矩形
矩形函数绘制一个填充矩形或者一个中空矩形。该函数定义如下:
BOOL Rectangle (HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
该函数使用当前选择的画笔绘制矩形外框,使用当前画刷填充内部。要绘制中空矩形,需要在调用Rectangle之前把空画刷选择进设备描述表中。

理解绘制边框的实际像素是很重要的。假定我们要在(0,0)处绘制一个5*7的矩形,函数调用如下:
Rectangle(0,0,5,7);
假设画笔是1像素宽,结果矩形如图2-6所示。
图2-6:放大后的用Rectangele绘制的矩形视图。
注意观察矩形右边界实际上是如何绘制到第4列的,底部边缘是如何绘制到第6行的。这是标准的Windows惯例。矩形在Rectangle函数指定的右边界和底边界以内进行绘制。如果选择的画笔宽度超过1个像素,右边界和底边界以边框矩形居中进行绘制。(Windows其它版本允许使用PS_INSIDEFRAME画笔风格忽略画笔宽度,强制在框架内绘制矩形)

圆和椭圆
可以用Ellipse函数绘制圆和椭圆,该函数原型如下:
BOOL Ellipse (HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
使用传入的矩形作为边界矩形(bounding rectangle)来绘制椭圆,如图2-7所示。对于Rectangle函数,使用当前画刷来填充椭圆内部,使用当前画笔来绘制椭圆外框。
图2-7:展示了Ellipse使用传入的边界矩形绘制出的椭圆。

圆角矩形
RoundRect函数绘制一个圆角矩形,原型如下:
BOOL RoundRect (HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidth, int nHeight);
最后两个参数给出了用于圆角的椭圆的宽度和高度,如图2-8所示。指定椭圆的高度和宽度可以让程序绘制出完全一样的均匀的圆角。缩短椭圆的高度,可以使矩形的两侧更平,而缩短椭圆的宽度可以使矩形的顶部和底部更平。
图2-8:椭圆的高度和宽度规定了由RoundRect绘制的矩形的圆角

多边形
最后,Polygon绘制了一个多边形,函数原型如下:BOOL Polygon (HDC hdc, const POINT *lpPoints, int nCount);
第2个参数是一个指向Point结构数组的指针,该数组定义了描述多边形的各个点。从最终形状上看,会被点数多一条边,因为函数自动把最后一个点和第一个点连接起来,绘制出多边形的最后一条边。

填充函数
前面提到的函数都是使用画刷和画笔的组合在设备描述表上绘制形状的。只填充区域而不涉及绘制形状轮廓的画笔的函数也是有的。这些函数中的第一个就如下所示:
int FillRect (HDC hDC, CONST RECT* lprc, HBRUSH hbr);
FillRect的参数设备描述表句柄、需要填充的矩形以及用来填充矩形的画刷。要在矩形区域里绘制一个纯色或者图案,使用FillRect函数会是一个快捷方便的方式。
虽然FillRect很方便,但GradientFill可能更棒一些。GradientFill函数填充一个矩形区域,使用一个颜色从一边开始绘制,并逐渐平滑过度到另外一个颜色直到另外一边。图2-9展示了一个客户区使用GradientFill进行绘制的窗口。书中印刷的黑白插图不能看出颜色的效果,但即使在这样的图上,依然能轻易的看到平滑过度的样子。
图2-9:使用GradientFill函数绘制的窗口。
GradientFill函数原型如下:
BOOL GradientFill (HDC hdc, PTRIVERTEX pVertex, ULONG dwNumVertex, PVOID pMesh, ULONG dwNumMesh, ULONG dwMode);
第一个参数依旧是设备描述表。pVertex是指向TRIVERTEX结构数组的指针,dwNumVertex是TRIVERTEX数组中入口的数量。TRIVERTEX结构定义如下:
struct _TRIVERTEX {
LONG x;
Long y;
COLOR16 Red;
COLOR16 Green;
COLOR16 Blue;
COLOR16 Alpha;s
} TRIVERTEX;
TRIVERTEX结构的各个域描述了设备描述表里的一个点和一个RGB颜色。这些点应该是要填充的矩形的左上角和右下角。pMesh是指向GRADIENT_RECT结构的指针,该结构定义如下:
struct _GRADIENT_RECT
{
ULONG UpperLeft;
ULONG LowerRight;
} GRADIENT_RECT;
GRADIENT_RECT结构简单指出TRIVERTEX结构中的哪些入口是描述左上角或者是右下角的。最后,dwNumMesh参数包含GRADIENT_RECT结构的数量。dwMode结构包含标志位,指出是从左到右(GRADIENT_FILL_RECT_H)填充还是从上到下(GRADIENT_FILL_RECT_V)填充。GradientFill函数实际上比表面上看到的要更复杂,因为在桌面系统里,它还执行三角形填充,这种填充方式在Windows CE下不支持。下面是创建图2-9的窗口的代码片段:
TRIVERTEX vert[2];
GRADIENT_RECT gRect;

vert [0] .x = prect->left;
vert [0] .y = prect->top;
vert [0] .Red = 0x0000;
vert [0] .Green = 0x0000;
vert [0] .Blue = 0xff00;
vert [0] .Alpha = 0x0000;

vert [1] .x = prect->right;
vert [1] .y = prect->bottom;
vert [1] .Red = 0x0000;
vert [1] .Green = 0xff00;
vert [1] .Blue = 0x0000;
vert [1] .Alpha = 0x0000;

gRect.UpperLeft = 0;
gRect.LowerRight = 1;

GradientFill(hdc,vert,2,&gRect,1,GRADIENT_FILL_RECT_H);
Shapes示例程序
清单2-3中,Shapes程序演示了很多相关函数。在Shapes中,绘制了4个图形,每个使用不同的画刷进行了填充。Listing 2-3: Shapes示例程序
Shapes.h
//================================================================
// Header file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))

//----------------------------------------------------------------------
// Generic defines and data types
//
struct decodeUINT { // Structure associates
UINT Code; // messages
// with a function.
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
struct decodeCMD { // Structure associates
UINT Code; // menu IDs with a
LRESULT (*Fxn)(HWND, WORD, HWND, WORD); // function.
};

//----------------------------------------------------------------------
// Defines used by MyCreateHatchBrush
//
typedef struct {
BITMAPINFOHEADER bmi;
COLORREF dwPal[2];
BYTE bBits[64];
} BRUSHBMP;

#define HS_HORIZONTAL 0 /* ----- */
#define HS_VERTICAL 1 /* ||||| */
#define HS_FDIAGONAL 2 /* \\\\\ */
#define HS_BDIAGONAL 3 /* ///// */
#define HS_CROSS 4 /* +++++ */
#define HS_DIAGCROSS 5 /* xxxxx */

//----------------------------------------------------------------------
// Function prototypes
//
HWND InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);

// Window procedures
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);

Shapes.cpp
//======================================================================
// Shapes- Brush and shapes demo for Windows CE
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include "shapes.h" // Program-specific stuff

//----------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT ("Shapes");
HINSTANCE hInst; // Program instance handle

// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_PAINT, DoPaintMain,
WM_DESTROY, DoDestroyMain,
};

//======================================================================
//
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
MSG msg;
HWND hwndMain;

// Initialize this instance.
hwndMain = InitInstance(hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0)
return 0x10;

// Application message loop
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// Instance cleanup
return TermInstance (hInstance, msg.wParam);
}
//----------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow){
WNDCLASS wc;
HWND hWnd;

// Save program instance handle in global variable.
hInst = hInstance;

#if defined(WIN32_PLATFORM_PSPC)
// If Pocket PC, allow only one instance of the application.
hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return 0;
}
#endif
// Register application main window class.
wc.style = 0; // Window style
wc.lpfnWndProc = MainWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = NULL, // Application icon
wc.hCursor = LoadCursor (NULL, IDC_ARROW);// Default cursor
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL; // Menu name
wc.lpszClassName = szAppName; // Window class name

if (RegisterClass (&wc) == 0) return 0;
// Create main window.
hWnd = CreateWindowEx (WS_EX_NODRAG, // Ex Style
szAppName, // Window class
TEXT("Shapes"), // Window title
WS_VISIBLE, // Style flags
CW_USEDEFAULT, // x position
CW_USEDEFAULT, // y position
CW_USEDEFAULT, // Initial width
CW_USEDEFAULT, // Initial height
NULL, // Parent
NULL, // Menu, must be null
hInstance, // Application instance
NULL); // Pointer to create
// parameters
// Return fail code if window not created.
if (!IsWindow (hWnd)) return 0;

// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC) {

return nDefRC;
}
//======================================================================
// Message handling procedures for MainWindow
//

//----------------------------------------------------------------------
// MainWndProc - Callback function for application window
//
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call procedure.
//
for (i = 0; i < dim(MainMessages); i++) {
if (wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
//----------------------------------------------------------------
// MyCreateHatchBrush - Creates hatched brushes
//
HBRUSH MyCreateHatchBrush (INT fnStyle, COLORREF clrref) {
BRUSHBMP brbmp;
BYTE *pBytes;
int i;
DWORD dwBits[6][2] = {
{0x000000ff,0x00000000}, {0x10101010,0x10101010},
{0x01020408,0x10204080}, {0x80402010,0x08040201},
{0x101010ff,0x10101010}, {0x81422418,0x18244281},
};

if ((fnStyle < 0) || (fnStyle > dim(dwBits)))
return 0;
memset (&brbmp, 0, sizeof (brbmp));

brbmp.bmi.biSize = sizeof (BITMAPINFOHEADER);
brbmp.bmi.biWidth = 8;
brbmp.bmi.biHeight = 8;
brbmp.bmi.biPlanes = 1;
brbmp.bmi.biBitCount = 1;
brbmp.bmi.biClrUsed = 2;
brbmp.bmi.biClrImportant = 2;

// Initialize the palette of the bitmap.
brbmp.dwPal[0] = PALETTERGB(0xff,0xff,0xff);
brbmp.dwPal[1] = PALETTERGB((BYTE)((clrref >> 16) & 0xff),
(BYTE)((clrref >> 8) & 0xff),
(BYTE)(clrref & 0xff));

// Write the hatch data to the bitmap.
pBytes = (BYTE *)&dwBits[fnStyle];
for (i = 0; i < 8; i++)
brbmp.bBits[i*4] = *pBytes++;

// Return the handle of the brush created.
return CreateDIBPatternBrushPt (&brbmp, DIB_RGB_COLORS);
}
//----------------------------------------------------------------------
// DoPaintMain - Process WM_PAINT message for window.
//
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
RECT rect;
HDC hdc;
POINT ptArray[6];
HBRUSH hBr, hOldBr;
TCHAR szText[128];

GetClientRect (hWnd, &rect);
hdc = BeginPaint (hWnd, &ps);

// Draw ellipse.
hBr = (HBRUSH) GetStockObject (DKGRAY_BRUSH);
hOldBr = (HBRUSH) SelectObject (hdc, hBr);
Ellipse (hdc, 10, 50, 90, 130);
SelectObject (hdc, hOldBr);

// Draw round rectangle.
hBr = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
hOldBr = (HBRUSH) SelectObject (hdc, hBr);
RoundRect (hdc, 95, 50, 150, 130, 30, 30);
SelectObject (hdc, hOldBr);

// Draw hexagon using Polygon.
hBr = (HBRUSH) GetStockObject (WHITE_BRUSH);
hOldBr = (HBRUSH) SelectObject (hdc, hBr);
ptArray[0].x = 192;
ptArray[0].y = 50;
ptArray[1].x = 155;
ptArray[1].y = 75;
ptArray[2].x = 155;
ptArray[2].y = 105;
ptArray[3].x = 192;
ptArray[3].y = 130;
ptArray[4].x = 230;
ptArray[4].y = 105;
ptArray[5].x = 230;
ptArray[5].y = 75;

Polygon (hdc, ptArray, 6);
SelectObject (hdc, hOldBr);

hBr = (HBRUSH) MyCreateHatchBrush (HS_DIAGCROSS, RGB (0, 0, 0));
hOldBr = (HBRUSH) SelectObject (hdc, hBr);
Rectangle (hdc, 10, 145, 225, 210);
SelectObject (hdc, hOldBr);
DeleteObject (hBr);

SetBkMode (hdc, OPAQUE);
lstrcpy (szText, TEXT ("Opaque background"));
ExtTextOut (hdc, 20, 160, 0, NULL,
szText, lstrlen (szText), NULL);

SetBkMode (hdc, TRANSPARENT);
lstrcpy (szText, TEXT ("Transparent background"));
ExtTextOut (hdc, 20, 185, 0, NULL,
szText, lstrlen (szText), NULL);

EndPaint (hWnd, &ps);
return 0;
}
//----------------------------------------------------------------------
// DoDestroyMain - Process WM_DESTROY message for window
//
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
PostQuitMessage (0);
return 0;
}
在Shapes里,OnPaintMain使用先前讨论过的那些不同的函数绘制了四个图形。对每个形状,都创建了一个不同的画刷,并选择进设备描述表,绘制图形,最后从设备描述表中取消选择。第一个图形使用纯灰色阴影来填充,用的是GetStockObject函数来装载这些纯色画刷的。最后一个图形则是使用由CreateDIBPatternBrushPt函数创建的画刷来填充的。该画刷的创建过程封装到MyCreateHatchBrush函数里了,该函数模拟了Windows CE下不支持的CreateHatchBrush函数。通过填充一个位图结构和设置构成阴影图案的位数据,创建了一个黑白位图,用于创建阴影画刷。这个位图是一个由CreateDIBPatternBrushPta函数指定的8*8的位图。因为该位图是单色的,所以包括调色板和头在内,它的总大小只有大约100字节。注意,因为位图的每个扫描行必须是双字对齐的,所以每个一字节扫描行的最后3个字节是没有使用的。

最后,程序写两行文字到最后的矩形里。文本进一步演示了opaque和transparent这两个系统绘图模式之间的差异。在本例中,文本绘制时使用opaque模式会更适合实际情况,因为在transparent模式下,阴影线会使字母变的模糊。图2-10展示了Shapes窗口。
图2-10演示了如何绘制不同填充的图形。

为了使事情简单一些,例子Shapes假设其运行在至少240像素宽的显示器上。这使得Shapes程序在手持式PC和Pocket PC上都能很好的运行。我只是浅显的描述了Windows CE中GWE的GDI部分,本章的目标并不是为GDI编程的各方面提供完整的描述。相反,我想去演示Windows CE下用于基本图画和文本的方法。在本书其它章节里,扩展了本章涉及的技术。通常,在演示如何在代码中使用的时候,我会谈论这些新技术和新引入的函数。为了扩展您的知识,我推荐《Windows 程序设计》(Programming Windows, 5th edition, by Charles Petzold)(Microsoft Press, 1998)一书作为学习Windows GDI的最佳资料。

既然我们已经看了输出,那么是时候把注意力转到系统输出--键盘和触摸板方面了。

分享到:
评论

相关推荐

    lazarus-1.0.8-fpc-2.6.2-cross-arm-wince-win32

    lazarus-1.0.8-fpc-2.6.2-cross-arm-wince-win32 freepascal 用于开发WINCE程序

    WINCE程序设计 WINCE程序设计

    《WINCE程序设计》深入解析 Windows CE(简称WinCE)是微软公司开发的一款嵌入式操作系统,主要用于掌上设备、工业控制、汽车电子、医疗设备等领域的应用。它的设计思路是将完整的Windows桌面系统精简,形成一个轻...

    Lazarus-0.9.28.2-fpc-2.2.4-cross-arm-wince-win32

    标题 "Lazarus-0.9.28.2-fpc-2.2.4-cross-arm-wince-win32" 暗示了一个用于开发针对Windows CE(掌上设备操作系统)应用程序的开源集成开发环境(IDE)——Lazarus的一个特定版本。Lazarus是Free Pascal编译器(FPC...

    hobd汉化版-wince

    Wince不支持所有的Windows桌面应用,但它提供了类似的操作界面和API,使得开发者可以创建特定于硬件的应用程序。 4. **汉化软件**:汉化是为了适应中文用户而对英文软件进行翻译和调整的过程。这包括菜单、对话框、...

    .net-cf-wince-curve.rar_WINCE 曲线_WINCE 曲线_wince 曲线控件_曲线 wince_

    描述中的".net-cf-wince-curve.rar"是一个包含用于Windows CE平台的曲线绘制控件的压缩文件。该控件可能提供API和方法,使开发者能够轻松地在Wince设备上生成实时数据曲线,这对于需要实时监测和分析数据的科学仪器...

    C# 各种文件格式的转换 ----winCE试验版

    C# 各种文件格式的转换 ----winCE试验版 京华志&精华志出品 希望大家互相学习,互相进步 支持CSDN 支持微软 主要包括C# ASP.NET SQLDBA 源码 毕业设计 开题报告 答辩PPT等

    wince程序设计 wince程序设计 wince程序设计

    - .NET Compact Framework:微软提供的.NET框架的精简版,允许开发者使用C#或VB.NET开发WinCE应用程序,享受丰富的类库和垃圾回收机制。 - WinAPI:WinCE提供了一套与Windows桌面系统类似的API,使得移植Windows...

    qt-wince安装.pdf

    首先,你需要下载适用于Windows CE的Qt源代码包,例如`qt-embedded-wince-opensource-src-4.4.0.zip`。 2. **安装Visual Studio 2005** 安装Visual Studio 2005是必要的,因为Qt的构建系统依赖于其编译器。在安装...

    qt-wince安装.docx

    - Qt的嵌入式开发包:qt-embedded-wince-opensource-src-4.4.0.zip - Microsoft Visual Studio 2005 (VS2005),用于编译和调试 - Windows Mobile 5.0 Pocket PC SDK,提供针对Windows CE的开发环境 - Microsoft ...

    博创2410开发板光盘资料----WINCE实验指导书

    - 设计和实现控制数码管和LED的驱动程序。 - 测试各种显示模式。 - 调整显示效果以达到最佳性能。 #### 3.5 WinCE系统触摸屏实验 - **实验目的**: 学习触摸屏设备的驱动开发。 - **实验内容**: - 设计触摸屏...

    3G-USB-WINCE驱动,支持华为部分无线网卡

    兼容wince5.0/6.0 以下列出的是调试通过的型号列表,仅供参考. 1. WCDMA/DSDPA: Hua Wei E180 Hua Wei E220 Hua Wei E1750(Modem:COM6,ATCMD:COM8,COM7 not use) Hua Wei E1550 Hua Wei E156G(Modem:COM6,ATCMD:...

    wince程序设计教程

    本教程将深入探讨Wince程序设计的基础与高级特性,帮助初学者快速掌握这一领域的核心技能。 一、Windows CE概述 Windows CE是一个可裁剪、实时的、32位的操作系统,其设计目标是满足小型设备的特定需求。它提供了...

    wince程序设计中文版1

    wince程序设计中文影印版 积分要多了,不好意思,我也不知道怎么取消 一共三个压缩包,须全部下载了解压,只让传10m,没办法啊 part1 http://download.csdn.net/source/257557 part2 ...

    IDA教程-WinCE ARM调试器入门教程.pdf

    IDA教程-WinCE ARM调试器入门教程.pdf

    最新Qt-WinCE全解

    将Qt与WinCE结合,可以创建强大的嵌入式应用程序,提供丰富的用户界面和强大的功能。 ### Qt for WinCE 的环境搭建 1. **安装基础环境**: 首先,你需要在开发机上安装Windows CE的开发环境,通常包括Visual Studio...

    VS2005-CoreCon-x86-WINCE600,wince开发软件安装包

    "VS2005-CoreCon-x86-WINCE600"这个安装包就是专门为Windows CE 6.00平台的开发设计的,它包含了构建、调试和测试嵌入式应用程序所需的工具和组件。 首先,"CoreCon"是Visual Studio 2005中的核心连接组件,它是...

    Image-update--WinCE-6.0.rar_gk7000_update WINCE_wince 6.0

    标题中的“Image-update--WinCE-6.0.rar_gk7000_update WINCE_wince 6.0”指的是一个针对Windows CE 6.0操作系统进行更新的镜像文件,该更新是针对名为“gk7000”的特定硬件平台设计的。在Windows CE系统中,"image...

    基于ARM-WinCE的电机监控系统设计.pdf

    本文将对基于ARM-WinCE的电机监控系统设计进行详细的介绍,包括系统设计、系统结构、硬件电路设计、软件设计和测试过程等方面。 系统设计 基于ARM-WinCE的电机监控系统设计是指使用ARM处理器作为核心,Windows CE...

    STL-WInCE 标准模板库EVC

    EVC(Embedded Visual C++)是微软为开发WinCE应用程序提供的集成开发环境。 STL-WinCE是针对Windows CE平台定制的STL版本,它允许开发者在WinCE系统中使用如向量(vector)、列表(list)、映射(map)、集合(set...

    S3C2442-WINCE 5.0 BSP包

    在S3C2442-WINCE 5.0 BSP中,开发者可以利用该驱动来识别和管理各种USB设备,如鼠标、键盘、闪存盘等,增强系统的兼容性和实用性。 TFT LCD和VGA接口驱动则是为了支持图形用户界面。TFT LCD驱动使得系统能够驱动...

Global site tag (gtag.js) - Google Analytics