数字时钟

这个题目是从书本做的笔记,是一个很好的程序,书本写的不算太仔细,在这里做详细记录。程序实现的功能如下:

功能细节非常多,包含如下:

一、窗口总是居在所有窗口的最前端
二、窗口没有标题栏等等
三、可以用鼠标拖动客户区移动,(一般来说,是通过移动标题栏移动)
四、(由于没有标题栏)鼠标右键可以弹出菜单,选择退出结束程序
五、获取系统时间
六、设置时钟
七、如何分段读取一幅位图的某个局部部分。
八、双缓冲技术

下面对各个技术进行详细记录(不分先后)

获取系统时间:
通过函数GetLocalTime(LPSYSTEMTIME lpSystemTime),参数为SYSTEMTIME类型的指针,这个SYSTEMTIME可以通过定义看到,分别为年,月,日,时分秒之类的成员变量,GetLocalTime将获取的系统时间放在这个变量中,再通过这个变量可以得到各种时间参数。

书本采用的是MFC类库中CTime类,也一样可以得到时间,省略。

设置时钟:这个比较简易,可以参看【时钟】,省略。

窗口居于最前端和窗口没有标题栏等等设置:

窗口风格改变:采用的方法是,先获取窗口的相关信息,然后再将这些信息进行处理,最后设置窗口属性。

  DWORD   dwStyle;
   dwStyle = GetWindowLong( hWnd, GWL_STYLE );
   dwStyle &= ~(WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_BORDER | WS_SIZEBOX );//去掉窗口的大部分特征
   SetWindowLong( hWnd, GWL_STYLE, dwStyle );

这一部分内容从字面上来看,逻辑是容易理解的,但细节还是有点繁杂,暂时留在这!

窗口居于最前端:通过SetWindowPos函数实现,这个函数的细节也很多,可以自定义查看。

鼠标拖动客户区移动:鼠标左键按下时,获取鼠标位置,然后将这个位置再通过消息发送给窗口过程,再通过DefWindowProc()函数处理,很有一点”伪装“的意思。
逆向思考一下,假如一个正常的带标题栏的窗口,我们用鼠标拖动它的标题栏进行移动时,此时会产生一个WM_NCLBUTTONDOWN消息。我们移动了标题栏,整个窗口就被跟着移动,到底是谁把窗口移动了呢?回调函数并没有写WM_NCLBUTTONDOWN的处理,那就是默认窗口函数处理了。

这个信息中的wParam和lParam参数意义如下:

wParam:含有被消息WM_NCHITTEST返回的代码
lParam:含有一个POINT数据结构(光标所在的X和Y坐标)

接着再来追踪WM_NCHITTEST这个消息的意义,它的意思是当窗口移动,某一鼠标按钮被按下或释放时,此消息发送到鼠标下面的窗口,如果鼠标正被一个窗口捕获,则该消息将发送到捕捉了鼠标的窗口。其中的选项很多,表明鼠标热点所在地。
完整的看一下鼠标左键按下时发送的消息:

PostMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));

其中,HTCAPTION表示:鼠标正处于标题条内....这样分析下来,就可以这样理解:
当鼠标左键点击客户区时,我们发送一条WM_NCLBUTTONDOWN信息告诉窗口回调函数,我不是点击客户区,而是在点击标题栏,鼠标坐标等等相关信息一并告诉你。这样默认窗口处理函数就会处理之后的事情。

参数最后的MAKELPARAM是一个宏,将两个值合并成一个LPARAM类型,作为消息参数传递!

读取位图操作:首先看位图的形状:

首先将这个位图载入,采用直接从硬盘读取的方式,(参见【位图】),获取一个位图句柄。当每获得一个时间值(单个的)时,就把相对应的位图块“剪切”出来。由于字符的宽度最大为28,所以每次DC中的X坐标以28为单位增长。

原文地址:https://www.cnblogs.com/tinaluo/p/5419655.html