关于Windows CE 界面编程
学习Windows CE 是从Windows CE 6.0 开发者参考开始的,以前一直在学习Linux下面的东西,突然转移到Windows CE上来还是挺不习惯的,废话不多说了,下面进入正题。
这本书前五章都是介绍界面编程的,包括WinCE的消息处理机制,绘图,窗口,控件和对话框。具体的就不多说了,书上的东西都能看到。但是在学习这几章的时候,一直有一个疑问,Windows CE下的各种控件和窗口有什么区别了?
其实Windows CE的一个控件其实也就是一个窗口,这样在编程的时候就不会造成一些困惑了。我们可以用CreateWindows()这个函数来直接创建它,在MSDN的帮助文档中可以看到这个函数的详细介绍,帮助文档的最下面,就介绍了可以通过一些特殊的名字来创建相应的窗口,比如我们创建一个按钮,就可以在WM_CREAT消息中直接使用:
CreateWindow (TEXT ("BUTTON"), TEXT ("SET"),
BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
550, 380, 60, 25,
hWnd, (HMENU)IDC_SETBTN, hInst, NULL);
这样的形式来直接创建。
还有一点,关于模态对话框和非模态对话框。模态对话框在对话框关闭之前不允许用户操作应用程序,而非模态对话框可以与应用程序交互的使用。关闭他们的函数式不一样的,在早期我写程序的时候就犯了这个错误,请一定要注意。
在学习完这些API和整个流程之后,自己就可以写一些小程序来试验一下自己的学习过程了,这也是非常有成就感的事情。我写了一个时钟界面,就是在一个界面上显示一个时钟,可以设置时间和设置闹钟,虽然这么一个小程序,但是自己在实际当中还是遇到了不少问题。下面一一来介绍:
最开始的想法很简单,就是自己画一个圆,然后获取系统时间,算出终点坐标,通过PloyLine()函数来画时针。那么就有了一个问题了,如何来定时的更新这个界面了?用定时器是一个不错的方法,也没创建线程那么复杂。这样效果大概是做出来了,但是界面十分闪烁。这是由于界面更新造成的,那么换一种方法,我不去更新整个界面,而是自己来更新部门界面,只更新时针显示的那个界面,方法有了,然后自己去做,效果还不是很理想,虽然闪烁得没以前厉害了,但是还是有闪烁的问题。
OK,在CSDN(上面的人还是很热情的,欢迎大家积极上CSDN,广告时间!)上问了几次这个问题,终于有了一个解决方法,那就是双缓冲来实现,双缓冲的原理我就不讲了,大家可以在网上搜索一下,直接贴代码:
/***********************************************************************************************
*Function: clockDraw
*Description: 绘制背景的双缓冲处理函数,这样避免了
* 屏幕闪烁的问题。
**********************************************************************************************/
void clockDraw()
{
HDC hdcMem, hdcMemBuf;
RECT rt;
HBITMAP hBitmap;
SYSTEMTIME sys;
GetLocalTime(&sys);
//创建第一个内存DC
hdcMem = CreateCompatibleDC(NULL);
//创建缓冲位图,先把图画到这张空白位图上,小心!
//第一个参数是用目的DC 才能创建彩色位图,否则只是单色!
hBitmap = CreateCompatibleBitmap( hdc, 638, 429);
//创建第二个内存DC
hdcMemBuf = CreateCompatibleDC(NULL );
//将空白位图选进第一缓冲区
HBITMAP hOldBmp1 = ( HBITMAP )SelectObject( hdcMem, hBitmap );
//用背景色刷一下
GetClientRect(hWnd, &rt);
FillRect( hdcMem, &rt, NULL );
//将要贴上去的图选进第二缓冲区
HBITMAP hOldBmp2 = ( HBITMAP )SelectObject( hdcMemBuf, hBitmap2);
//加入if条件判断,减少资源浪费,解决了指针停顿的问题(这个判断最开始我没加,指针总是会每间隔几秒会停顿一下,估计是由于刷新频率的问题)
if ( clockOldSecond != sys.wSecond)
{
//将第二个内存DC传给第一内存DC
BitBlt( hdcMem, 0, 0, 638, 429, hdcMemBuf, 0, 0, SRCCOPY );
//画线,用了一个函数实现
DrawLine(hdcMem);
//最后画到目的DC 上
BitBlt( hdc, 0, 0, 638, 429, hdcMem, 0, 0, SRCCOPY );
}
//保存这一次的系统时间,作为下一次刷屏的判断
clockOldSecond = sys.wSecond;
//结束操作
SelectObject( hdcMem, hOldBmp1 ); // 选出
SelectObject( hdcMemBuf, hOldBmp2 ); // 选出
DeleteDC( hdcMemBuf );
DeleteObject( hBitmap );
DeleteDC( hdcMem );
}
整个流程就设计完了,但是明显感觉使用双缓冲后,界面的相应速度下降了很多,有利就有弊啊,还有需要注意的一点就是,使用双缓冲后,不能让系统自己去刷屏,必须自己实现。
ps:程序我放到了我的资源里,有兴趣的可以去看看,http://download.csdn.net/source/1678392由于我是新手,有什么问题和建议可以发到我邮箱:luocan1358@126.com Thanks in advance!