CDateTimeCtrl 重载中的注意事项,以及边框的修改。

本文介绍如何去除 CDateTimeCtrl 的默认边框并调整其背景颜色,涉及 ModifyStyleEx 函数的使用及 OnEraseBkgnd 方法的重载技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于关于 CDateTimeCtrl 的用法,在MSDN 和百度、谷歌上已经很多很多,这里就不在啰嗦 。

    因为CDateTimeCtrl本身没有border 属性,所以不能像 其他 控件那样直接,勾选掉,就能去掉边框。

    而且重载的时候问题多多。

 

1. 如果想要改变 CDateTimeCtrl 的边框

                介绍一个函数,

virtual BOOL ModifyStyleEx(
   DWORD dwRemove,
   DWORD dwAdd,
   UINT nFlags 
);

第一个参数是移除的属性,第二参数是增加的属性。

最后一个是标志:

SWP_ASYNCWINDOWPOS:如果调用进程不拥有窗口,系统会向拥有窗口的线程发出需求。这就防止调用线程在其他线程处理需求的时候发生死锁。
SWP_DEFERERASE           :防止产生WM_SYNCPAINT消息。
SWP_DRAWFRAME           :在窗口周围画一个边框(定义在 窗口类描述中)。
SWP_FRAMECHANGED    :给窗口发送WM_NCCALCSIZE消息,即使窗口尺寸没有改变也会发送该消息。如果未指定这个标志,只有在改变了窗口尺寸时才发送WM_NCCALCSIZE。
SWP_HIDEWINDOW          :隐藏窗口。
SWP_NOACTIVATE          :不激活窗口。如果未设置标志,则窗口被激活,并被设置到其他最高级窗口或非最高级组的顶部(根据参数hWndlnsertAfter设置)。
SWP_NOCOPYBITS         :清除客户区的所有内容。如果未设置该标志,客户区的有效内容被保存并且在窗口尺寸更新和重定位后拷贝回客户区。
SWP_NOMOVE                 :维持当前位置(忽略X和Y参数)。
SWP_NOOWNERZORDER:不改变z序中的所有者窗口的位置。
SWP_NOREDRAW             :不重画改变的内容。如果设置了这个标志,则不发生任何重画动作。适用于客户区和非客户区(包括标题栏和滚动条)和任何由于窗回移动而露出的父窗口的所有部分。如果设置了这个标志, 应用程序必须明确地使窗口无效并区重画窗口的任何部分和父窗口需要重画的部分。
SWP_NOREPOSITION     :与SWP_NOOWNERZORDER标志相同。
SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。
SWP_NOSIZE                    :维持当前尺寸(忽略cx和Cy参数)。
SWP_NOZORDER             :维持当前Z序(忽略hWndlnsertAfter参数)。
SWP_SHOWWINDOW      :显示窗口。
 
然后 创建 CDateTimeCtrl 之后,调用   此函数 进行 修改 边框。
     
 
在说一个小的知识点 :
  

WS_BORDER Creates a window that has a border.创建一个有边界的窗口。


WS_EX_CLIENTEDGE Specifies that a window has a 3D look — that is, a border with a sunken edge.指定窗口具有3D外观,也即是一个下沉的边缘 

    

 

 MFC  创建  CDateTimeCtrl  的时候给与 其 的是 WS_EX_CLIENTEDGE  属性,所以这里需要去掉 WS_EX_CLIENTEDGE  属性才能 去掉边框 。

 

 

调用函数 :

            ModifyStyleEx (WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME);

            这里还有一个知识点 ,  很多人在调用 这个函数之后,窗口风格并没有改变,而必须在之后调用 setwindowpos 才行,那是因为你没有  为 ModifyStyleEx 的第三个参数添加 风格。这里 添加的 是  SWP_DRAWFRAME 风格。

 

一边 调用过次函数之后,就能去掉 CDateTimeCtrl  的3D边框 。

 

 

2. 改变之后,很多人发现,CDateTimeCtrl 的背景色 并不能 于自己当前的 窗口 格调一致 。于是想要修改 其 背景色。但是 CDateTimeCtrl  想要修改其背景色,就必须要进行重载了,在主函数的 OnCtlColor 中 和 PreTranslateMessage 中并不能修改其 颜色。

 

重载 需要注意的 :

       如果只是修改背景色,那么只需要重载 CDateTimeCtrl 函数的  OnEraseBkgnd 函数,其余的不动。也就是说,整个重载函数中,只有

afx_msg BOOL OnEraseBkgnd(CDC* pDC);  和  构造 、析构 函数而已。

      千万不要在 OnCtlColor中 进行  setbkcolour  settextcolour 类似这样的操作,虽然 这样也能修改背景色,但是你会发现如果改变日期,字体就会重叠,而且鼠标双击会有阴影,这个时候进行强制刷新也没有实质的效果。

      千万不要重载 OnPaint 函数,如果你只想修改其背景色的话 。 如果重载,那么你就要实现一下,CDateTimeCtrl 日期  的 显示。

       修改 背景色 的代码 :

CBrush bBrush(RGB(255, 255, 255));

CBrush* pOldBrush = pDC->SelectObject(&bBrush);

CRect rect;
pDC->GetClipBox(&rect);    

pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);

注意一下,下面三个函数的区别。

GetClipBox 该函数得到一个能够完整包含当前可见区域的最小矩形的大小。

GetWindowRect获取窗口的整个区域,包括菜单,标题栏,边界。

GetClientRect获取的窗口的客户区,这里是在用于给用户作图用的。 

 

这样应该就能修改 CDateTimeCtrl  的背景色。

 

3.  其实 很多人 在去掉边框之后 发现 很丑 ,和整个窗口 并不能 想融合,这个时候 就需要 在 整个 CDateTimeCtrl  控件之外 添加一个边框 ,当然  添加边框,就直接加载一张图片 就行了 ,这个就比较容易了,图片中间全透明,可以使用 GDI+ 的 BMP 图片进行加载,也可以使用 ATL 里面的 CImage 类 进行加载,方法太多,就不说了,实现起来也比较容易,这里搞出来一张,我做出来的效果,大家做个参考 。

 

 

 

 

 

 

 

 

 
 
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值