windows图形编程 学习杂谈 之 高效率窗口背景

刚开始学习windows下的图形编程,只会用API创建窗口和最简单的消息函数。

总想给窗口画个背景图片,那么就开始吧。编程只看不动手是不会提高的。

开始从网上找资料,主要看的是GDI+_SDK参考手册。看了画图片的部分,很简单的嘛。

做了个最简单的OnPaint函数,在WM_WM_PAINT消息处理中调用。

void OnPaint(HWND hWnd)
{
	Bitmap bmp(TEXT("i:\\background.jpg"));  //用图片文件创建Bitmap对象
	HDC hdc(GetDC(hWnd));  //取得设备环境句柄

	RECT rect;
	GetClientRect(hWnd, &rect);   //获取窗口坐标
	UINT clientWidth = rect.right - rect.left;  //计算宽度
	UINT clientHeight = rect.bottom - rect.top; //计算高度
	
	Graphics gs(hdc); //创建Graphics对象
	gs.DrawImage(&bmp, 0, 0, clientWidth, clientHeight); //画图

	ReleaseDC(hWnd, hdc); //释放设备环境句柄
}

编译运行,效果还不错。好的开始是成功的第一步。

欣喜过后,发现了一些缺点:

1、重绘过程中有可能出现背景颜色的闪现(我的窗口用的是淡绿的眼睛保护色)

2、窗口放大缩小后,图片比例变形。这怎么可以,美女变胖妞。(绝对无法容忍)

3、加入一个计时器计算时间,1024X768绘图的FPS只有25。速度太慢。


好吧,开始优化,又找资料又查MSDN,发现网上几乎都是很简单的demo,只能自己想办法。

折腾了好几天,最终优化版出炉。

优化在以下几个方面:

1、图片要一次读取,不能每次OnPaint从文件读取,效率太低。把文件读取的代码放在窗口创建的消息处。

2、读取图片用gdi+容易,绘图用gdi更快。

3、图片的缩放在WM_SIZE消息下处理,这部分很花时间,OnPaint只负责画调整好的,就快多了。

4、添加WM_ERASEBKGND消息处理,简单的return 1就可以不让windows刷新背景(背景我自己画)。

5、采用缓冲机制,处理好的图片是放在内存中,OnPaint才刷到屏幕上。

6、OnPaint的时候,不画全部窗口,只画无效部分。

7、这些功能函数封装成一个类,便于使用。


设计了一个BackGroundBmp类,用于创建背景图片,调整图片尺寸,画到窗口中。

        Bitmap* m_pbmp;  //gdi+ 的Bitmap对象,用于从文件中读取各种类型的图片(gdi只能读bmp),并且用于缩放。
        HBITMAP m_membmp;  //gdi的内存图,是m_pbmp缩放处理后产生的。用于屏幕输出。
        int m_width;   //内存图宽
        int m_height; //内存图高

成员变量很简单,4个

类的重要函数有3个,分别是

        bool Create(const WCHAR* filename);
        bool FixSize(HWND hWnd, int cxWidth, int cxHeight);
        bool Paint(HDC hdc, const RECT& rect);

核心部分是FixSize,用gdi+对象实现缩放,画在gdi的内存图中。(完整代码最后附上)

简单解说一下这个函数的部分代码:

	double xscale = static_cast<double>(m_width) / bmpwidth;
	double yscale = static_cast<double>(m_height) / bmpheight;
bmpwidth、bmpheight是原图像的尺寸

m_width、m_height = 窗口客户区的尺寸

计算2种尺寸之间的比例关系。

下面就是缩放的关键代码&#x

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值