收藏 分享(赏)

在VC中如何使用Static控件来显示图像.doc

上传人:dreamzhangning 文档编号:2528748 上传时间:2018-09-20 格式:DOC 页数:9 大小:324.50KB
下载 相关 举报
在VC中如何使用Static控件来显示图像.doc_第1页
第1页 / 共9页
在VC中如何使用Static控件来显示图像.doc_第2页
第2页 / 共9页
在VC中如何使用Static控件来显示图像.doc_第3页
第3页 / 共9页
在VC中如何使用Static控件来显示图像.doc_第4页
第4页 / 共9页
在VC中如何使用Static控件来显示图像.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、怎么样在 VC 中使用 Static 控件来显示图像?在使用 MFC 编写程序时,经常需要显示图像;根据 GDI 的要求,需要一个 DC(设备内容)作为显示的基础;实际上任何 Windows 的窗口都可以作为一个 DC,我们可以通过 API 或 MFC的函数来得到,例如:HDC GetDC (HWND);-这里的 HWND 是窗口的句柄CDC * CWnd:GetDC ();-这里的 CWnd 实际上是任何从 CWnd 的类当我们使用 MFC 的单文档或多文档框架时,我们可以使用 CView 作为图像显示的 DC,这个时候我们将绘制图像的操作放在 OnDraw 中就可以了;当窗口无效或更新的时

2、候,框架会自动调用该函数来重新绘制图像;这里没有什么问题,我们主要来谈谈另外一种模式:当你需要在一个基于 Dialog 程序或一个 CDialog 控件中显示图像的问题。实际上什么控件都可以作为图像显示的 DC,他们可以是按钮、图片控件、Static 控件等,只要有窗口的控件都可以得到 DC。这里仅以 Static 控件作为图像显示的控件来介绍。首先看我程序的基本逻辑:源文件后面的按钮是用来选择位图文件的;而下面的图像显示区域是用来显示图像的Static 控件;当设置好要显示的图像文件以后,图像就自动在 Static 中画出来。 第一次一开始,我在 CDialog 对应的按钮处理程序中调用显示

3、图像的代码,代码如下(IDC_PICVIEW 为 Static 的 ID):然后在 CImageCntDlg:OnPaint 中也调用 ShowImage(TRUE);然后编译运行。一开始还可以,选择 BMP 文件之后也可以正确选择,但当激活另一个程序(也就是隐藏了该窗口),然后再激活这个程序,这个时候发现 Static 中图像显示闪烁一下后变成灰色的背景。到底什么发生了? 到底什么发生了?上面的现象告诉我们,即使我们将 ShowImage 放在 CDialog 的 WM_PAINT 处理消息中,在某些情况下仍然不能正确的处理。从现象看,我们的图像应该是先画出来了,但然后又被清除了;感觉是 P

4、AINT 的消息处理不正确。没有办法,自己想不同那么就使用工具。VC 自带的 Spy+是个很好的工具,打开Spy+;运行程序,然后打开某个图像,这个时候在 Spy+中找到对应的窗口,然后观察与该窗口相关的消息;如图:这个时候我们切换程序窗口,先让其被覆盖,然后再显示;观察 Spy+的结果,发现这样几条记录:可以看到在 WM_PAINT 消息之后,窗口又收到了很多 WM_CTLCOLORBTN 和WM_CTLCOLORSTATIC 等多条消息,查询 MSDN 知道这些是主窗体收到的绘制窗口上空间的消息;实际上,主窗体在处理 WM_PAINT 消息的时候也需要绘制发送消息给各个控件有机会绘制自己;

5、而对应的消息是控件本身的 WM_PAINT 消息。好了,终于找到原因了,我们在 CDialog 的 OnPaint 中调用 ShowImage 之后不久,OnPaint 也主动通知各控件重绘,结果这个时候 Static 上的图像给覆盖了。 定义自己的 Static 控件知道原因就好办了,只需要将 ShowImage 放到适当的地方就可以了。这里需要自己从CStatic 继承一个自己的类,然后重写其 OnPaint 函数,在其中显示图像。代码如下:void CImageWnd:OnPaint()HDC hDC = :GetDC(m_hWnd);PAINTSTRUCT paintStruct;:B

6、eginPaint(m_hWnd,DrawImage(m_strImageName);TRACE(“CImageWnd OnPaint!n“);:EndPaint(m_hWnd,void CImageWnd:DrawImage(CString imageName)if(imageName = “) return ; m_hBitmap = NULL;m_hBitmap =(HBITMAP):LoadImage (NULL,imageName.GetBuffer(),IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_LOADFROMFILE);if(m_hBitm

7、ap = NULL) return ;CDC * pDC = GetDC();CDC cdc;cdc.CreateCompatibleDC(pDC);cdc.SelectObject(m_hBitmap);int startLeft = 0,startTop = 0;BITMAP bmpInfo;GetObject(m_hBitmap, sizeof(BITMAP), GetClientRect(startLeft = (m_picViewRect.right-bmpInfo.bmWidth)/2;if(startLeft BitBlt(startLeft,startTop,m_picView

8、Rect.right-startLeft,m_picViewRect.bottom-startTop,另外 CImageWnd 头文件如此定义:class CImageWnd : public CStaticDECLARE_DYNAMIC(CImageWnd)public:CImageWnd();virtual CImageWnd();void ShowImage(CString imageName)SetImageName(imageName);DrawImage(imageName);void DrawImage(CString imageName);void SetImageName(C

9、String imageName)m_strImageName = imageName;protected:afx_msg void OnPaint();DECLARE_MESSAGE_MAP()protected:HBITMAP m_hBitmap;RECT m_picViewRect;CString m_strImageName;在原来调用 ShowImage(TRUE)的地方这样调用 m_picView.ShowImage(filename);(m_picView 是 Static 对应的 CImageWnd 类型成员)。好了,编译测试。这次发现切换没有问题了;但当我们打开文件选择对话框

10、,然后在窗口上面覆盖 Static左右拖动的时候发现,一会以后图像不在显示了。那么这次又为什么 ?实际上上面的写法有问题的,只是赶时间随手写的。 追踪最后的凶手没有办法,我插入了许多日志来观察变量的设置情况,结果发现 DrawImage 中的m_hBitmap 变量在一段时间后变成 0 了,那么肯定显示不了图像了。想了想,GDI 资源中 HANDLE 有一定的数目限制,这里只创建 HANDLE,而从没有释放过,所以一段时间之后 HANDLE 的上限达到,而不能再创建新的 HANDLE 了。那么就删除不用的 HANDLE 吧。 最后的代码1 void CImageWnd:DrawImage(CS

11、tring imageName)2 3 if(imageName = “) return ;4 TRACE(“Begin CImageWnd:DrawImage1 imageName= %s!n“,imageName.GetBuffer();5 if(m_hBitmap9 m_hBitmap = NULL;10 m_hBitmap =(HBITMAP):LoadImage(NULL,imageName.GetBuffer(),11 IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_LOADFROMFILE);12 13 TRACE(“Begin CImageWn

12、d:DrawImage2 m_hBitmap=%d!n“,m_hBitmap);14 if(m_hBitmap = NULL) return ;15 TRACE(“Begin CImageWnd:DrawImage3!n“);1617 CDC * pDC = GetDC();18 CDC cdc;19 cdc.CreateCompatibleDC(pDC);20 cdc.SelectObject(m_hBitmap);21 int startLeft = 0,startTop = 0;22 BITMAP bmpInfo;23 GetObject(m_hBitmap, sizeof(BITMAP

13、), 24 GetClientRect(25 startLeft = (m_picViewRect.right-bmpInfo.bmWidth)/2;26 if(startLeft BitBlt(startLeft,startTop,31 m_picViewRect.right-startLeft,32 m_picViewRect.bottom-startTop,33 TRACE(“End of CImageWnd:ShowImage!n“);34 /DeleteObject(m_hBitmap);35 /m_hBitmap = NULL;36 好了,在编译运行。这次一切正常。通过这个例子,我们了解几个问题:1 CDialog 首先画自己,然后再画控件2 选择合适的时候重绘图像3 GDI 对象的有限的,达到一定数目之后就不能创建了,所有需要释放,以免资源浪费

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报