VC6.0实用小技巧 联系客服

发布时间 : 星期日 文章VC6.0实用小技巧更新完毕开始阅读

1、隐藏鼠标

int i = ShowCursor(FALSE); for ( i; i >= 0 ;i-- ) {

ShowCursor(FALSE); }

2、显示鼠标

int i = ShowCursor(TRUE); for ( i;i<= 0;i++ ) {

ShowCursor(TRUE); }

在MFC程序中显示JPG/GIF图像

如果你是一个使用VB编程的程序员,要在程序中显示JPG或者GIF图像简直易如反掌,将图像控件拖到Form中,分分钟即可搞掂。但是C++程序员要显示同样的图形却没有那么轻松,那么是不是要自己编写JPG解压缩代码呢?当然不用那么复杂啦!本文将针对这个问题讨论如何在MFC中显示JPG或者GIF图像。

用VB写图像显示程序之所以如此轻松,完全是利用了琳琅满目的图像处理控件,把你想要做的事情都一一搞掂。而C++程序员为了实现相同的功能必须忙乎半天。其实,C/C++程序员也能使用那些VB程序员所用的(或者说几乎一样的)图像控件。VB用的图像控件实际上都基于一个系统级COM类——IPicture。下面是有关 IPicture 的方法描述:

方法 get_Handle get_Hpal get_Type get_Width get_Height Render 描述 返回图像对象的Windows GDI句柄 返回图像对象当前使用的调色板拷贝 返回当前图像对象的的图像类型 返回当前图像对象的图像宽度 返回当前图像对象的图像高度 在指定的位置、指定的设备上下文上绘制指定的图像部分 set_Hpal get_CurDC SelectPicture 设置当前图像的调色板 返回当前选中这个图像的设备上下文 将一个位图图像选入给定的设备上下文,返回选中图像的设备上下文和图像的GDI句柄 返回图像对象KeepOriginalFormat 属性的当前值 get_KeepOriginalForma put_KeepOriginalFormat 设置图像对象的KeepOriginalFormat 属性 PictureChanged SaveAsFile get_Attributes 通知图像对象它的图像资源改变了 将图像数据存储到流中,格式与存成文件格式相同 返回图像位属性当前的设置 从上面这个表可以看出,IPicture操纵着图像对象及其属性。图像对象提供对位图的抽象,而Windows负责BMP、JPG和GIF位图的标准实现。程序员要做的只是实例化IPicture,然后调用其Render函数。与通常使用接口的方式不同,这里实例的创建我们不用CoCreateInstance函数,而是用一个专门的函数OleLoadPicture。

IStream* pstm = // 需要一个流(stream) IPicture* pIPicture;

hr = OleLoadPicture(pstm, 0, FALSE, IID_IPicture, (void**)&pIPicture);

OleLoadPicture从流中加载图像并创建一个可用来显示图像的新IPicture对象。

rc = // 显示图像的矩形 // 将rc 转换为 HIMETRIC

spIPicture->Render(pDC, rc);

IPicture 负责处理所有琐事,以便确定图形之格式,如 Windows 位图、JPEG或者GIF文件——甚至是图标和元文件(metafiles)。当然啦,所有这些的实现细节是需要技巧的,为此我写了一个Demo程序Myimgapp(如图二)来示范这些IPicture的使用方法。

图一 Myimgapp的运行画面

Myimgapp是个典型的MFC文档/视图程序,在编写这个程序之前,我首先对 IPicture COM接口进行封装,之所以要这么做,主要是考虑到并不是每一个程序员都能熟练运用COM接口进行编程,另外将IPicture的主要功能封装在C++类中可以使我们的问题更容易解决,我封装的这个C++类名字叫做CPicture。它的定义和实现细节请参考本文提供的源代码。 我在这个类中将复杂而陌生的COM风格的参数映射成MFC程序员更为熟悉的类型。例如,CPicture可以让你直接从文件名加载一幅图像,CFile或者CArchive,而不用去处理流,CPicture::Render替你完成了IPicture中所有令人讨厌的但又是必须的HIMETRIC平滑转换工作。CPicture甚至具备了一个Load函数,它可以从资源数据中加载图像,所以你只要用下面的代码就可以显示资源中的图像:

CPicture pic(ID_MYPIC); // 加载图像 CRect rc(0,0,0,0); // 使用缺省的rc pic.Render(pDC, rc); // 显示图像

CPicture::Render提供一个显示图片的矩形。IPicture 对图像进行延伸处理。如果传递一个空矩形,则CPicture用图像本身的大小--不进行延伸处理。对于图像本身而言,CPicture查找\类型的资源,所以在资源文件中你必须要加入下面的代码:

IDR_MYPIC IMAGE MOVEABLE PURE \

CPicture是个很棒的傻瓜类,它具备一个 ATL 智能指针CComQIPtr指向IPicture接口,通过调用OleLoadPicture来初始化不同的Load函数。CPicture提供了常用的打包函数来调用底层的IPicture。CPicture只封装了那些在Demo例子程序中要用到的方法。如果你需要调用IPicture::get_Handle或其它一些很少用到的IPicture方法,你可以自己尝试编写相应的打包代码。 另外,在编写完CPicture之后,我发现了一个现成的MFC类——CPictureHolder,这个类的功能几乎与CPicture完全一样,你可以在afxctl.h文件中找到它的定义。 前面说过,Demo例子是个典型的MFC文档/视图应用程序,因此它肯定少不了与文档和视图类相对应的CPictureDoc 和CPictureView:

CPictureDoc类没有什么特别的处理代码,它用CPicture对象存储图像:

class CPictureDoc : public CDocument { protected:

CPicture m_pict; // the picture };

并且CPictureDoc::Serialize 调用CPicture::Load 从MFC存档的数据中读取图像。

void CPictureDoc::Serialize(CArchive& ar) {

if (ar.IsLoading()) { m_pict.Load(ar); } }

为了使Myimgapp程序更实用,CPictureDoc::OnNewDocument从程序资源数据加载了一幅图像。为了显示这幅图像,CPictureView::OnDraw要调用CPicture::Render。这样程序一启动便会显示一幅默认的图像。

void CPictureView::OnDraw(CDC* pDC) {

CPictureDoc* pDoc = GetDocument(); CPicture* ppic = pDoc->GetPicture(); CRect rc;