如何使用Win32下的GDI等接口实现绚丽,高效的界面

如何使用Win32下的GDI等接口实现绚丽,高效的界面,第1张

1如何让界面绚丽

怎么样的算绚丽有很漂亮的有Alpha透明有Animation

每个人的审美观点都不同,所以如果你的界面很多人认为绚丽那就可以了。设计界面主要是Designer的工作,包括UI逻辑的设计,色彩搭配设计等,我认为这也可以进一步分工:熟悉用户习惯的Designer、美学Designer等。但是一般情况下这些让程序员给代劳了。

下面介绍Windows提供给开发人员的相关接口,利用这些接口设计你认为绚丽的界面。

2如何透明如何半透明如何颜色渐变

以下是我使用Imaging COM组件封装的一个函数,可以使用其绘制PNG,当然也可以绘制其它。绘制带Alpha通道的PNG即实现了透明。

#include <imagingh>

#include <initguidh>

#include <imgguidsh>

#pragma comment(lib, "Imaginglib")

BOOL DrawPNG(HDC hDC, TCHAR szPicString, RECT &rcDraw)

{

BOOL br = FALSE;

IImagingFactory pImgFactory = NULL;

IImage pImage = NULL;

ImageInfo sImgInfo;

CoInitializeEx(NULL, COINIT_MULTITHREADED);

// Create the imaging factory

if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory,

NULL,

CLSCTX_INPROC_SERVER,

IID_IImagingFactory,

(void )&pImgFactory)))

{

// Load the image from the JPG file

if (SUCCEEDED(pImgFactory->CreateImageFromFile(

szPicString,

&pImage)))

{

// Draw the image

pImage->Draw(hDC, &rcDraw, NULL);

pImage->Release();

pImage = NULL;

br = TRUE;

}

pImgFactory->Release();

}

CoUninitialize();

return br;

}

------------------------------------------------------------------------------------------------------

而封装的这个函数实现了将一个DC根据Alpha值半透明绘制到另一个DC上,使用GDI函数AlphaBlend实现。

BOOL AlphaBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,

int nWidthDest, int nHeightDest,

HDC hdcSrc, int nXOriginSrc, int nYoriginSrc,

int nWidthSrc, int nHeightSrc,

BYTE alpha) {

BLENDFUNCTION bf;

bfBlendOp = AC_SRC_OVER;

bfBlendFlags = 0;

bfSourceConstantAlpha = alpha;

bfAlphaFormat = 0;

return AlphaBlend(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,

hdcSrc, nXOriginSrc, nYoriginSrc, nWidthSrc, nHeightSrc, bf);

}

如果你的设备支持AlphaBlend硬件加速那将是非常棒的事情,否则软件方式会有点影响性能。

------------------------------------------------------------------------------------------------------

颜色渐变也是直接有API可以支持:

BOOL GradientFill(

HDC hdc,

PTRIVERTEX pVertex,

ULONG nVertex,

PVOID pMesh,

ULONG nCount,

ULONG ulMode

);

hdc

[in] Handle to the destination device context

pVertex

[in] Pointer to an array of TRIVERTEX structures, each of which defines a triangle vertex

nVertex

[in] The number of vertices in pVertex

pMesh

[in] Array of GRADIENT_RECT structures in rectangle mode

nCount

[in] The number of rectangles in pMesh

ulMode

[in] Specifies gradient fill mode The following table shows the possible values for ulMode

This function fills rectangular regions with a background color that is interpolated from color values specified at the vertices

不管你使用Net CF平台调用这些API,还是Win32/MFC/ATL/WTL直接调用这些API,你都是可以实现这些效果的。更多内容请查询开发文档,毕竟那才是最好的参考资料。

3如何实现动画

动画的原理就是一帧一帧的画面按照时间轴向后移动,在骗过眼睛之后就成了动画,所以你得到动画最简单的方法就是按照一定间隔将不同一张一张绘制到屏幕上,虽然很简单,但是在编程中经常使用这种方法。有时简单的往往是最好的。

这里还有个技巧,比如将每张使用Photoshop中的运动滤镜模糊下,这样使用上面方法得到的动画会有种非常快速的感觉。也可以用类似的方法来用2D表现三维的事物,得到3D动画的效果。

还可以使用GIF动画的方式,比如在开机和关机时。以下封装的函数仅供参考,我没用心整理。

BOOL DisplayGIF(TCHAR szPicString)

{

HANDLE hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

if (hFile == INVALID_HANDLE_VALUE)

{

return FALSE;

}

DWORD dwFileSize = GetFileSize(hFile, NULL);

if ( (DWORD)-1 == dwFileSize )

{

CloseHandle(hFile);

return FALSE;

}

HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);

if (hGlobal == NULL)

{

CloseHandle(hFile);

return FALSE;

}

LPVOID pvData = GlobalLock(hGlobal);

if (pvData == NULL)

{

GlobalUnlock(hGlobal);

CloseHandle(hFile);

return FALSE;

}

DWORD dwBytesRead = 0;

BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);

GlobalUnlock(hGlobal);

CloseHandle(hFile);

if (!bRead)

{

return FALSE;

}

IStream pStream = NULL;

if ( FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream)) )

{

return FALSE;

}

IImage pImage = NULL;

RECT rc;

IImagingFactory pImgFactory = NULL;

CoInitializeEx(NULL, COINIT_MULTITHREADED);

if ( !SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void )&pImgFactory)) )

{

return FALSE;

}

IImageDecoder pDecoder = NULL;

UINT nCount = 0;

if ( !SUCCEEDED(pImgFactory->CreateImageDecoder(pStream, DecoderInitFlagNone, &pDecoder)) )

{

return FALSE;

}

pDecoder->GetFrameDimensionsCount(&nCount);

GUID pDimensionIDs = (GUID)new GUID[nCount];

pDecoder->GetFrameDimensionsList(pDimensionIDs,nCount);

TCHAR strGuid[39];

StringFromGUID2(pDimensionIDs[0], strGuid, 39);

UINT frameCount = 0;

pDecoder->GetFrameCount(&pDimensionIDs[0],&frameCount);

UINT iSize = 0;

pDecoder->GetPropertyItemSize(PropertyTagFrameDelay,&iSize);

BYTE pBuff = new BYTE[iSize];

PropertyItem pItem = (PropertyItem)pBuff;

pDecoder->GetPropertyItem(PropertyTagFrameDelay,iSize,pItem);

int fCount = 0;

ImageInfo Info;

pImgFactory->CreateImageFromStream(pStream,&pImage);

pImage->GetImageInfo(&Info);

rcleft = rctop = 0;

rcright = InfoWidth;

rcbottom = InfoHeight;

HDC tempDC;

HBITMAP hbmNew = NULL;

void pv;

BITMAPINFO bmi = { 0 };

HBITMAP hbmOld = NULL;

tempDC = CreateCompatibleDC(NULL);

bmibmiHeaderbiSize = sizeof(BITMAPINFOHEADER);

bmibmiHeaderbiWidth = InfoWidth;

bmibmiHeaderbiHeight = InfoHeight;

bmibmiHeaderbiPlanes = 1;

bmibmiHeaderbiBitCount = (SHORT) max(16, GetDeviceCaps(tempDC, BITSPIXEL));

bmibmiHeaderbiCompression = BI_RGB;

hbmNew = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, &pv, NULL, 0);

hbmOld = (HBITMAP)SelectObject(tempDC, hbmNew);

pImage->Draw(tempDC, &rc, NULL);

pDecoder->SelectActiveFrame(&pDimensionIDs[0], ++fCount);

BitBlt(g_hdc, 0, 0, rcright - rcleft, rcbottom - rctop, tempDC, 0, 0, SRCCOPY);

delete []pBuff;

delete []pDimensionIDs;

pDecoder->Release();

pImage->Release();

pImgFactory->Release();

CoUninitialize();

return TRUE;

}

4如何有较高的运行效率

后面的内容会介绍到使用GDI这些“较高层次”的接口是很难有较高的运行效率。

但是可以使用一些技巧,比如“空间换取时间”。相信"Lazy Computation”你有听过,延迟处理这项任务直到真正需要的时候(在编程中我们也会经常用到,需要有这个意识。)这里使用的技巧有点恰恰相反的味道,把用户将来很可能用到的地方先处理好,然后储存起来,而并不是等到用户真正需要的时候才去处理。

比如使用Imaging COM组件绘制PNG时,每次都需要加载组件的库文件,然后卸载,界面可能要反复刷新,然后反复绘制PNG。这时可以考虑在程序启动的时候使用非界面主线程将绘制好的PNG保存起来(比如以Device Context的形式),界面刷新的时候仅仅是BitBlt到目标设备。BitBlt的效率是比较高的,如果仍然不能满足你的效率要求,可以考虑下面介绍的DirectDraw等技术。

上面的方法对于具有丰富开发经验的应该比较清楚,但是新手往往会忽略。在开发界面时我们要保证一个基本原则:想尽一切办法在现有的条件下提高界面响应用户的速度,界面要以用户为中心。所以开发时需要保持这个意识。

5如何提高程序启动速度

第4部分说过,为了提高运行效率,可以将常用的界面在程序启动时一起缓存到内存中,那么程序的启动时间会大大增加,如何解决这个问题我的建议是UI主线程仅仅加载少量的用户启动后直接就能看到的界面,而另起一个子线程(叫A)用于加载其它界面,其它界面加载完之后这个子线程退出,当用户点击其它界面时,主线程如果发现子线程A并没有退出,说明其它界面还没有加载完,让用户等待。

这么设计的好处是,将最耗时的任务分摊出去,即能保证了用户快速看到界面,又能在之后的运行中有较高的效率。

6如何在绚丽和效率之间平衡

最好的方法是得到界面运行时具体的时间消耗数据,如果必要可以精确到每个函数。得到一份系统正常情况下的数据,得到几份环境恶劣情况下的数据(比如系统非常繁忙、设备电量很少、要处理的数据非常多等)。定量的去分析解决这些问题。如果在恶劣的环境下你的绚丽界面表现的仍然不错,恭喜你,你太棒了!

Windows CE/Windows Mobile也提供了些基本的Performance API(像DirectDraw等技术还有自己的Performance接口和工具):

BOOL QueryPerformanceCounter(

LARGE_INTEGER lpPerformanceCount

);

lpPerformanceCount

[in] Pointer to a variable that the function sets, in counts, to the current performance-counter value If the installed hardware does not support a high-resolution performance counter, this parameter can be set to zero

This function retrieves the current value of the high-resolution performance counter if one is provided by the OEM

BOOL QueryPerformanceFrequency(

LARGE_INTEGER lpFrequency

);

lpFrequency

[out] Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency If the installed hardware does not support a high-resolution performance counter, the value passed back through this pointer can be zero

This function retrieves the frequency of the high-resolution performance counter if one is provided by the OEM

上面两个API需要OEM在OAL层提供实现,精度可以低于1ms,否则可以使用下面的API。

DWORD GetTickCount(void);

For Release configurations, this function returns the number of milliseconds since the device booted, excluding any time that the system was suspended GetTickCount starts at zero on boot and then counts up from there

For debug configurations, 180 seconds is subtracted from the the number of milliseconds since the device booted This enables code that uses GetTickCount to be easily tested for correct overflow handling

另外优化PNG、Bitmap、GIF等,让清晰度和大小刚好满足要求。

7控件为什么如此降低运行效率怎样减少控件的使用

手机软件不同于桌面系统软件,一方面手机的处理速度更低、电池容量更小,另一方面用户会使用手机处理更紧急的事情。所以这也是我认为 不应该完全把桌面系统软件开发经验借鉴到手机软件开发上的原因。一个240x320分辨率大小的手机界面,你给放上5、6个控件,甚至更多,这个界面注定不会太高效率,这样的界面也不适合作为用户最常用的界面,比如今日界面。另一方面,Windows的标准、通用控件不会有太绚丽的外观,即使自定义的。但是这些控件能够带来很明显的开发速度。所以我们要协调好。不能为了窗口而窗口,更不能一切皆窗口。

那么你会问如何协调。我的建议是能不用控件的地方就不要用,大多地方可以直接使用,比如实现多状态按钮你可以这样做:

WM_LBUTTONDOWN消息处理里面先判断Point是否在按钮的Rect中,如果是将按下状态的DC BitBlt到屏幕对应位置,WM_LBUTTONUP消息处理里面再BitBlt回来。

8基于Win32的界面运行效率比基于Net CF高,但是开发效率低,怎么办

Win32编程已经很古老、很“落后”了。但是在处理速度还不及奔三的Windows嵌入式设备上有时你不得不选择。把界面常用的功能代码封装成库(类库也可以),积累这样的资源可以提高团队的开发效率。C++泛型编程就是以牺牲编译时效率换取代码重用,但是不影响运行时效率,值得去深入学习下,而且有现成的库可用,比如STL。

还有其它的技术可供选择:DirectDraw(后面介绍的)、Direct3DM、OpenGL ES等。但是开发难度较高。

9如何使用GDI+(Native/Managed)

GDI+是GDI的下一个版本,它进行了很好的改进,并且易用性更好。GDI的一个好处就是你不必知道任何关于数据怎样在设备上渲染的细节,GDI+更好的实现了这个优点,也就是说,GDI是一个中低层API,你还可能要知道设备,而GDI+是一个高层的API,你不必知道设备。以下引用自MSDN文档:

"2-D vector graphics involves drawing primitives (such as lines, curves, and figures) that are specified by sets of points on a coordinate system

For example, the Rect class stores the location and size of a rectangle; the Pen class stores information about line color, line width, and line style; and the Graphics class has methods for drawing lines, rectangles, paths, and other figures There are also several Brush classes that store information about how closed figures and paths are to be filled with colors or patterns

Certain kinds of pictures are difficult or impossible to display with the techniques of vector graphics Imaging part will resolve this problem An example of such a class is CachedBitmap, which is used to store a bitmap in memory for fast access and display

Typography is concerned with the display of text in a variety of fonts, sizes, and styles One of the new features in GDI+ is subpixel antialiasing “

Windows CE/Windows Mobile下的GDI+仅仅是Windows桌面系统的一个很小的子集。

long factorial(int m) //用于求阶乘

{

if(m==0||m==1)

return 1;

else return mfactorial(m-1);

}

long forSum(int n) //用于求阶乘之和

{

int i=0;

long y=0;

for(i=1;i<=n;i++)

{

y+=factorial(i);

}

return y;

}

#include <stdioh>

int main()

{

long y=0;

int n=0;

printf("请输入一个 n:");

scanf("%d",&n);

printf("y=%d\n",forSum(n));

printf("n=%d\n",n);

return 0;

}

第二题:

int weiShu(int x) //用于判断数x是几位数

{

int flag=0;

do

{

x=x/10;

flag++;

}while(x!=0);

return flag;

}

#include <stdioh>

{

int flag=0,x=0,i=0;

int sum=0;

printf("请输入一个数 x=");

scanf("%d",&x);

flag=weiShu(x);

for(i=1;i<=flag;i++)

{

sum+=x%10;

x=x/10;

}

printf("%d各个位上数字之和是%d\n",x,sum);

}

不该学,了解即可

WIN API一般必学得有四类

user interface

system services

networking

graphics and multimedia

GDI属于第4类, 这类东西最没用, 里面像什么brush, clipping,lines and curves等等这些,基本就是鸡肋 绘图最好使用GDI+, GDI只要了解HDC的用法,和SetROP2,因为GDI+中没有SetROP

第1类UI是最重要的万物之基础

第2类编写系统工具, windows高手, 逆向等的第一步

第3类网络编程,比较重要

第4类绘图是最难的, 因为你要解决两个问题, 绘图本身的技术问题, 业务领域的问题, 绘图首先是需要用数学建模的, 如果你软件设计不是很精通, 那你 还得考虑架构问题

有机会读一下<<GDI+程序设计>>这本书,很好,里面内容很详细

edgar108是用单纯的钢笔画,如果你想要详细一点的话可以:

private void Form1_Paint(object sender, PaintEventArgs e)

{

Graphics g = eGraphics;

Bitmap bmp = new Bitmap("wukonggif");

//获取的分辩率等信息

//gDrawImage(bmp, 0, 0);

//ConsoleWriteLine("Screen resolution:" + gDpiX + "DPI");

//ConsoleWriteLine("Image resolution:" + bmpHorizontalResolution + "DPI");//HorizontalResolution水平分辩率

//ConsoleWriteLine("Image Width:" + bmpWidth);

//ConsoleWriteLine("Image Height:" + bmpHeight);

//SizeF s = new SizeF(bmpWidth (gDpiX / bmpHorizontalResolution), bmpHeight (gDpiY / bmpVerticalResolution));//VerticalResolution垂直分辩率

//ConsoleWriteLine("Display size of image:" + s);

//缩放,使之在指定的矩形内绘制

//Rectangle r = new Rectangle(0, 0, 200, 500);//将绘制在指定的矩形内

//gDrawImage(bmp, r);

//显示没有缩放的

//Rectangle r = new Rectangle(0, 0, bmpWidth, bmpHeight);

//gDrawImage(bmp, r, r, GraphicsUnitPixel);

//改变分辨率SetResolution

//bmpSetResolution(300f, 300f);//参数(X的分辨率,Y的分辨率).的高度和宽度为:Width=X象素/X分辨率,同理Y也是一样

//gDrawImage(bmp, 0, 0);

//bmpSetResolution(600f, 600f);//如原图象素为1024x768,这里的分辨率为600,600,则宽为1024/600英寸,宽为768/600英寸

//gDrawImage(bmp, 360, 0);

//修改质量InterpolationMode枚举(内含有四个属性值)

//gInterpolationMode = InterpolationModeNearestNeighbor;

//gDrawImage(bmp, thisClientRectangle);

//修剪

//Rectangle sr = new Rectangle(200, 200, 300, 300);//提取要剪切的图块的矩形

//Rectangle dr = new Rectangle(20, 20, 200, 200);//存储被剪切出来图块的矩形

//gDrawImage(bmp, dr, sr, GraphicsUnitPixel);//GraphicsUnitPixel指定给定数据的度量单位为pixel

//变形,即定义定义左上角,右上角,左下角的位置

//Point[] destinationPoints ={ new Point(0, 0), new Point(100, 0), new Point(50, 100) };//(左上角,右上角,左下角坐标)

//gDrawImage(bmp, destinationPoints);

//复制

//Rectangle r=new Rectangle (120,120,400,400);

//Bitmap bmp2 = bmpClone(r, SystemDrawingImagingPixelFormatDontCare);//SystemDrawingImagingPixelFormat用于指定每个象素颜色数据的格式,这里指定为DontCare

//获取缩略图GetThumbnailImage,注意:前提是先声明ThumbnailCallback方法,这里在Form1_Paint前面已经声明

//ImageGetThumbnailImageAbort thumbnailCallback = new ImageGetThumbnailImageAbort(ThumbnailCallback);//声明委托

//Image tn = bmpGetThumbnailImage(40, 40, thumbnailCallback, IntPtrZero);

//gDrawImage(tn, 0, 0, tnWidth, tnHeight);

}

注意:直接存在debug里面,不需写路径.

对于各种各样应用日益广泛的嵌入式系统而言,除了应用功能强大外,人机界面的美观也是吸引用户的重要方面。因此,越来越多的嵌入式系统开发人员希望:LCD上除了显示图案固定的菜单以外,再添加适量的动画,使得整个界面屏幕更加活泼可人。用于动画设计的程序设计语言有多种,并且有多种方法,根据是否需要借助于其他应用软件和程序,可以将这些方法分成两大类:第一类是只使用各种编程语言及开发环境中包含的文件和框架实现的设计方法;第二类则是安装相关软件(诸如Flash、Di-rectDraw等),在相关语言的开发环境中将这些软件的功能文件包含进去,来共同实现动画设计的方法。而嵌入式系统由于其极强的专用性、实时性要求,传统采用的开发语言并不是很多,虽然动画界面在嵌入式系统应用中并非高优先级的程序,但开发人员在选取其设计方法时,也应该辨明利弊,灵活使用,这样才能看到更加赏心悦目的界面,而不是被LCD上凌乱不堪的显示内容所困扰。

1不需安装第三方软件的动画设计方法分析

(1)Logo适用于简易的嵌入式设备的动画设计

Logo语言的设计方法最为简单。它内置一套(TurtleGraphics)系统,其本身就是一种绘画语言,理论上可以加载到嵌入式系统中作动画开发;然而,因为一个嵌入式系统会有很多别的软件设计部分,其他功能都采用Logo显然并不合适,而要在一个嵌入式系统中安装两种开发环境更加不现实。所以,若在嵌入式系统开发中选用这种方法制作动画,应该只适合用于儿童用的复杂程度同等的简易的嵌入式设备。

(2)最适合嵌入式系统使用的擦除法

C语言是嵌入式系统开发使用最多的语言,并且高中低档的系统都可以用,因而采用C语言的所有动画设计方法,理论上均适用于嵌入式系统的屏幕动画开发。然而,诸如利用动态开辟图视口方法、利用显示页和编辑页交替变化、利用画面存储再重放的方法,以及直接对图像动态存储器进行 *** 作的方法等程序比较复杂,且要对图像不断进行存取 *** 作,这需要耗费大量内存资源;而擦除法动画设计则可以解决上述问题。其设计原理是:利用同色原理,当图形色与背景色相同时人眼不能感知。在动画设计中,当在一个位置画了一张图像时,使图像色与背景色相异,然后再到另一个位置画一张图像并使图像色与背景色也相异,此时将先画的图像在原位置再画一张,并使图像色与背景色相同,这样人眼只能看到新画的一张图像而看不到先前画的图像,从而先前画的图像感觉被擦除了。

这样连续画多张图像并在每画一张新的图像时将原来的图像擦除,从而在观察者看来就实现了动画的效果。综上所述,从耗费资源较少且执行速度较快的角度出发,笔者认为,采用C语言设计动画的常用方法中,最适合嵌入式系统使用的是首选擦除法。

(3)CBuilder语言本身不太适合嵌入式开发

采用CBuilder语言设计动画,可以方便地利用现成的组件产生图像及控制时间,从而解决了动画设计中两个非常重要的问题。然而CBuilder语言本身不太适合嵌入式开发,因为嵌入式开发对空间、效率都要求较高,而CB是针对高层的应用程序开发的工具。但是,有两点值得注意:首先,现在很多公司做嵌入式开发多是自己搞一套系统,使其适合使用CB完全可以做到;另外,Borland公司正在开发嵌入式的C,可以期待。

(4)Java语言非常适合嵌入式系统的屏幕动画设计Java语言是嵌入式系统开发经常采用的语言,在手机中更是应用良多。Java语言的动画设计方法通过定义线程的方法来控制动画时间;而使图像动的平滑的双缓冲方法需要很大内存,因而更常用的消除画面闪烁的办法是重载upGlate()。

(5)C语言方法均可用于嵌入式系统动画设计

面向对象的C语言中,可供选择的动画设计方法很多:简单的动态图像(如不断闪烁的星星)可以采用底色覆盖法;在屏幕的固定位置显示动态图像时,可以选择多切换法;利用异或方式进行绘图不会发生全屏幕闪动,通常效果较好,但若反复使用,在所清除图像处会产生闪烁,仍不是很完美;像素 *** 作一般和其他动态图像实现方法(如底色覆盖)相结合使用;多缓冲技术是将图形绘制在不同的帧中,通过将屏幕在这些不同的帧之间进行切换,来达到动画效果;具体的帧数目可以根据实际动画的需要自行确定。这类似于C语言中的双缓冲技术原理,只不过双缓冲只绘制一份备用图像作为离屏图像,而多缓冲则将图形绘制在多个不同帧中,将屏幕在这些帧之间进行切换。

因为工业方面大多用C/C作为嵌入式系统的开发语言,所以这些方法都可用于嵌入式系统动画设计。在Nord-TecSoftWare开发的Nord-TecSnowFlakes屏幕保护程序中,逼真的雪花动画便是利用多缓冲技术实现的。

(6)绘制复杂风格线条的方法

在GIS(地理信息系统)类软件设计中,经常需要在绘图时使用一些相对固定但又频繁使用的一些用以代表地理状态的符号,如河流、铁路、海岸线等等。显然,这些基本符号图形一般都是相对复杂的线条,在MFC提供的基本类库中并未提供可以直接使用的相关函数;即使是在绘图功能比较强大的CDC中,也仅仅提供了LineTo()、Set-Pixel()等一些通用的最基本的绘图函数。使用这些函数来绘制GIS基本符号是效率比较低的一种办法,这在大量的绘图 *** 作中将会表现得比较明显,因此不宜提倡。但是,可以通过WindowsNT3.1中首次出现的Win32.API函数LineDDA,来解决这一绘制复杂风格线条的问题。

(7)使用VC实现高速平滑的简单动画的方法

许多软件(特别是游戏软件)的开发中,实现高速平滑的动画需要比较深的技术,如OpenGL、DirectX,并且可能还要开发人员有深厚的数学功底。但是,如果只是在开发嵌入式系统过程中,想为应用程序的界面实现一些动画效果,就可能不用以上这些技术了,更多的是用WindowsAPI提供或MFC封装后的GDI绘图函数来实现。虽然所需动画的复杂程度不高,但作为开发人员,并不能为此就降低对动画效果的要求。因此,需要了解如何用GDI函数来开发平滑无闪、高速的动画。

该技术的关键就是在内存中创建一个与显示动画的窗口区域一样大的位图,先用GDI函数绘制位图,然后在适当的时候从内存中显示出来。因为位图已经绘制好,不象平时编程那样边绘制边显示,所以,显示一帧图形时便减少了闪烁,从而实现平滑动画;同时,由于图形是从内存中直接显示到当前窗体的,所以速度很快,从而实现高速动画。如果再创建一个线程后台绘制图形,将会实现很多特殊效果的动画,使嵌入式系统的用户界面收到意想不到的效果。

在此基础上,还可以在显示位图时作优化显示。例如:不是将位图全部显示出来,而是显示其中动画的一部分,因为BitBlt函数作位传输很慢。这样更符合嵌入式系统重视效率的特点。

2需要安装第三方软件的动画设计方法分析

(1)为教学研究开发的嵌入式设备可使用Ubigraph

graphviz和Ubigraph都是图论生成软件,但Ubig-raph功能更强,利用它可以快速生成图论模型的图形和动态图像,直观地展示出各种图论模型的三维结构,演示各种图论算法的过程。因为可以嵌入到Java、C、C等语言中,所以当然适合用于嵌入式系统的动画设计,尤其是一些专门为教学研究开发的嵌入式设备。

(2)Flash对嵌入式系统而言太过华丽

Flash是一种功能强大的矢量动画软件,但是所用到的高级技术比较多,不过为了能够做出精美的**特技效果的动画,还是值得对其进行深入研究的。然而,对于嵌入式系统开发而言,它实在是太过华丽了;如果不是特别需要突出游戏或者动画的精致效果,一般开发者应该不会舍本逐末以此来牺牲系统的速度和容量。

(3)DirectDraw方法对嵌入式系统的适用度

DirectDraw使用页面切换的方法实现图像动态。它不仅可以访问系统内存,还可以访问显示内存,实现图像动态的同时不会使得画面闪烁,是一种“完美切换”技术;因此DirectDraw技术很受程序员青睐,尤其在虚拟现实技术中应用广泛。但是,显而易见,该方法需要占用很大内存,安装所需的开发文件同样需要较大硬盘空间,应用到一般的嵌入式系统中,对反应速度等的限制将会比较明显。

其实,用DirectDraw编程的核心要点即“几个表面之间拷来拷去”。在对界面的动画复杂程度要求不高的嵌入式系统中,可以采用C程序作为开发语言,并且在动画实现方法上,利用前述C程序设计中显示页和编辑页交替变化的方法,来代替几个表面交替拷贝的DirectDraw方法。然而,如果是大型的嵌入式系统,并且重视界面动画效果,采用DirectDraw方法和面向对象开发语言,仍然是更好的选择。

当然,若对美术工艺有特殊要求,可以尝试将更专业的技术(如颜色锁结及用于3D效果的Z排序与视差)引入到嵌入式系统软件设计中——这种系统本身也应该是专业的、功能专用的,否则只能停留在理论上,难以实现!

3可用于嵌入式系统开发的脚本语言

当动画应用于网络时,可以选择直接使用脚本语言设计,譬如JSP、PHP等。当今的很多嵌入式系统都有连接网络的需求和相应功能,虽然大多数系统的屏幕动画都不涉及对外发布的问题,但在联网嵌入式系统的开发中直接使用脚本语言编写动画,也不啻为一个新的思路。

Python可作为嵌入式系统的开发语言(在Nokia智能手机所采用的Symbian *** 作系统上已得到证明)。它最大的优势是能够很轻松地把使用其他语言制作的各种模块(尤其是C/C)轻松地联结在一起。由此,既可以直接使用Py-thon编写简单的界面动画,也可以将对速度要求更高的复杂动画使用C语言编写后嵌入到Python程序中。

以上就是关于如何使用Win32下的GDI等接口实现绚丽,高效的界面全部的内容,包括:如何使用Win32下的GDI等接口实现绚丽,高效的界面、高分悬赏visual c++编程题、我熟悉c++,但是完全不懂GDI。我看了那些简单应用程序,那里面都要用到GDI绘图技术。请问我该怎等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9998367.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存