自绘滑动按钮

自绘滑动按钮

 
首先描述下我要做的东西,一个带3D效果的滑动开关:
        
这个是基于Win32的SDK编程,代码不大,整个过程就不一一描述了,遇到的几个难点,觉得可以分享一下,在此贴出:
1. 消息如何抓获
有两种方法,一种就是使用windows 下现有的”BUTTON”窗口类,调用CreateWindow(“Button”, …),然后使用SetWindowsLong(m_hWnd, DWL_DLGPROC, pfnWinPorc);来设置窗口的消息处理函数。
还有种方法就是调用RegisterWindow注册一个自己的窗口类,在这个函数里面确定窗口的消息处理函数,然后CreateWindow创建窗口。
消息入口函数一旦确定了,那么后面的事也就顺利成章了。
 
2.  动画机制如何实现
动画实现主要是在WM_PAINT里面实现,通过每次改变图片的位置来实现动画效果,这里有两种方法,一个就是用在一个定时器里调用InvalidRect向窗口发WM_PAINT消息来连续绘图,另一个是在WM_PAINT里调用InvalidRect,注意这里的Invalid\Rect需要在BeginPaint后面调用,不然是没有什么效果的。
 
3.屏幕闪烁问题的处理
如果每次绘制时都对设备DC进行了多次绘制,动画显示的时候会有屏幕闪烁的问题,解决的办法就是申请一个内存DC作为缓冲,每次先写入内存DC,然后用BitBlt将内存DC中的内容复制到设备DC中,这样就OK了。
这里需要注意的是内存DC创建了以后并不能直接绘图,需要再申请一个内存控件,不然什么也画不出来,用CreateCompabileBitmap创建一个兼容的HBITMAP对象,然后选进内存DC就可以了,另外不要忘了使用SelectOjbect、DeleteObject 、DeleteDC来释放资源,不然就要出现内存泄漏哦。
 
4.带透明处理的png图片如何绘制
不知道你有没有发现,这里的按钮边缘是带有平滑效果的,而且是带有阴影的,如果使用BMP格式的原图来绘制的话是达不到这种效果的,所以原图是png的格式,png的图片用GDI的LoadBitmap是不好加载的,PC下用可以使用GDI+的Image类来绘制,而在Mobile下有个类似GDI+的Image库,调用Image::Draw就可以很方便的绘制 png图片了。但光靠这个函数还不够,它不能按你的要求对源图进行剪切,也不能改变左上角的位置,这里需要GDI里的BitBlt这个函数来对其进行剪切,另外还要使用一个独立的内存DC,代码如下:
 

     (void)BitBlt(hTempDC, 0, 0, (int)ImgInfo.Width, (int)ImgInfo.Height, hDestDC, xDest, yDest, SRCCOPY);
    CRect   rc(0, 0, (int)ImgInfo.Width, (int)ImgInfo.Height);
    (void)CImageProcess::DrawImage(hTempDC, &rc, pImg);
    (void)BitBlt(hDestDC, xDest, yDest, Width, Height, hTempDC, xSrc, ySrc, SRCCOPY);

 
注意两个BitBlt函数中表示位置的参数,通过这几参数的设定,就可以对图片位置和区域的进行改变了,不过这里牺牲了点内存,因为这里还需要申请一个临时的内存DC,以便Image::Draw进行绘制。
 
以上就是我编写这个控件时遇到的一些问题,虽然难度不大,但还是有所收获,现将其总结下,和大家分享下,以便交流,不足之处,请多指教!

你可能感兴趣的:(3D,控件,滑动,GDI+,自绘)