首 页 行业热点 新车 试驾评测 养车用车 车型库

GDI+编程,如何定义Image类的对象数组

发布网友 发布时间:2022-04-19 20:19

我来回答

1个回答

热心网友 时间:2023-10-04 00:54

GIF动画文件含有多个图像数据帧,GDI没有直接提供对GIF文件的支持。在GDI+中,通过Image对象可以很容易的操作GIF文件。

多页图像是指图像中包含有多个图形页。每页可以看作图像帧。这些图像帧通过连续的显示就形成了一副动画。比如GIF文件。

GDI+的Image对象提供了直接的对GIF、TIF文件格式的支持。调用Image对象的成员函数GetFrameDimensionsCount可以得到Image对象的Dimension数。每个Dimension通过一个GUID标示。函数GetFrameDimensionsList可以返回所有Dimension的GUID值。第一个GUID值保存在函数参数pDimensionsIDs数组的索引0处。GetFrameCount可以得到每个Dimension里有多少个Frame。简单示例代码:
Image* image = new Image(L"Multiframe.gif");
UINT count = 0;
count = image->GetFrameDimensionsCount();
GUID *pDimensionIDs=(GUID*)new GUID[count];
image->GetFrameDimensionsList(pDimensionIDs, count);
WCHAR strGuid[39];
StringFromGUID2(pDimensionIDs[0], strGuid, 39);
UINT frameCount=image->GetFrameCount(&pDimensionIDs[0]);

delete []pDimensionIDs;
并不是所有的GIF文件都是含有多帧的,所以我们在显示GIF的时候可以通过上面的代码根据frameCount的值判断这个GIF文件是否有多个帧。

在确认有多个帧的图像以后,还要得到每帧图像显示的间隔时间。GDI+的Image对象提供了 GetPropertyItem获取图像的属性。GetPropertyItem函数需要用户传递数据返回缓冲区和大小。所以在使用前先用GetPropertyItemSize得到需要的缓冲区大小,分配空间后再取得属性数据。

GDI对象

在讨论设备描述表时,已经多次涉及到GDI对象。这里,需强调一下:GDI对象要选入Windows 设备描述表后才能使用;用毕,要恢复设备描述表的原GDI对象,并删除该GDI对象。
一般按如下步骤使用GDI对象:
Create or get a GDI OBJECT hNewGdi;

hOldGdi = ::SelectObject(hdc, hNewGdi)
……
::SelectObject(hdc, hOldGdi)
::DeleteObject(hNewGdi)

先创建或得到一个GDI对象,然后把它选入设备描述表并保存它原来的GDI对象;用毕恢复设备描述表原来的GDI对象并删除新创建的GDI对象。
需要指出的是,如果hNewGdi是一个Stock GDI对象,可以不删除(删除也可以)。通过
HGDIOBJ GetStockObject(int fnObject); // type of stock object
来获取Stock GDI对象。

(1) MFC GDI对象
MFC用一些类封装了Windows GDI对象和相关函数,层次结构如图2-4所示:

CGdiObject封装了Windows GDI Object共有的特性。其派生类在继承的基础上,主要封装了各类GDI的创建函数以及和具体GDI对象相关的操作。

CGdiObject的构造函数仅仅让m_hObject为空。如果m_hObject不空,其析构函数将删除对应的Windows GDI对象。MFC GDI对象和Windows GDI对象的关系如图2-5所示。

(2) 使用MFC GDI类的使用
首先创建GDI对象,可分一步或两步创建。一步创建就是构造MFC对象和Windows GDI对象一步完成;两步创建则先构造MFC对象,接着创建Windows GDI对象。然后,把新创建的GDI对象选进设备描述表,取代原GDI对象并保存。最后,恢复原GDI对象。例如:
void CMyView::OnDraw(CDC *pDC)
{

CPen penBlack; //构造MFC CPen对象
if (penBlack.CreatePen(PS_SOLID, RGB(0, 0, 0)))
{
CPen *pOldPen = pDC->SelectObject(&penBlack)); //选进设备表,保存原笔

pDC->SelectObject(pOldPen); //恢复原笔
}else
{

}

}

和在SDK下有一点不同的是:这里没有DeleteObject。因为执行完OnDraw后,栈中的penBlack被销毁,它的析构函数被调用,导致DeleteObject的调用。

还有一点要说明:
pDC->SelectObject(&penBlack)返回了一个CPen *指针,也就是说,它根据原来PEN的句柄创建了一个MFC CPen对象。这个对象是否需要删除呢?不必要,因为它是一个临时对象,MFC框架会自动地删除它。当然,在本函数执行完毕把控制权返回给主消息循环之前,该对象是有效的。

关于临时对象及MFC处理它们的内部机制,将在后续章节详细讨论。
至此,Windows编程的核心概念:窗口、GDI界面(设备描述表、GDI对象等)已经陈述清楚,特别揭示了MFC对这些概念的封装机制,并简明讲述了与这些Windows Object对应的MFC类的使用方法。还有其他Windows概念,可以参见SDK开发文档。在MFC的实现上,基本上仅仅是对和这些概念相关的Win32函数的封装。如果明白了MFC的窗口、GDI界面的封装机制,其他就不难了。
参考资料:http://www.shps.com.cn/developweb/webSchool/LJJvcjc/02_04.htm

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com