感谢评论!
原先的示例代码是在工作表中调用和显示日历窗体,思路是获取活动单元格的位置信息(单位是点,points),将该位置信息转化为像素坐标(单位是像素,pixels),然后将日历窗体移动到单元格所在位置。
在窗体的文本框上调用和显示日历窗体的思路是一样的:获取文本框的点位置,转化为像素坐标,再把日历窗体移动到该坐标即可。
只是,直接简单的这样做会有一个明显的小问题:日历没法实时跟着窗体移动。如果要让日历实时跟着窗体移动,还要子类化窗体,处理 WM_WINDOWPOSCHANGED 消息,这样处理完全能实现,没问题,但会使得简单问题复杂化。
因为原先的示例代码就是已经把日历控件放在了一个窗体上,以窗体作为容器,这个窗体上只有日历这一个控件。[窗体+日历控件]作为一个整体,显示在工作表上。当时这么做的目的主要就是不想子类化Excel工作簿,拖慢Excel的运行速度(虽然肉眼难以分辨),直接子类化窗体会方便和安全得多。
如果窗体上有很多控件,比如文本框、命令按钮、复选框、列表框等等,日历只是其中一个。那么,可以以[日历控件]作为一个整体,显示在窗体上,这种情况下日历控件就是窗体的一个子窗口(Child Window),日历控件可以实时跟着窗体移动。
要实现上述功能,原先的代码已不适用,为此我将日历控件的代码从整体代码中剥离出来,写成了一个单独的类,可以像添加文本框、命令按钮一样在窗体的代码里面添加,想加多少个就加多少个。完整示例代码请见附件。以下是运行效果预览:
运行效果-日历隐藏状态
运行效果-日历显示状态
示例代码中有个code文件夹,里面有两个模块: UserFormSubclass.bas 和 SysMonthCal32.cls 。在窗体的代码中调用的例子以及代码注释如下图所示:
调用示例(以及代码注释)
在之前的楼层以及示例代码中我提到的“这只是一个极简的例子,还有很多的可自定义的空间”,在此一并解释下:日历控件,包括很多其它的Windows提供的原生控件,都有很多样式可以选择。比如此例中,日历上方的星期几显示的缩写形式,也可以显示完整形式(“Mon”显示为“Monday”,“一” 显示为“星期一”等),还可以选择是否显示“今天”按钮和日期,点击“今天”按钮会跳转到当前日期。官网给的示例截图直接显示两个月的日历页面,还包含了当前周数,日历控件的大小包含了更多的空白部分(留白是平面设计上的一个常用技巧和基础设计原则):
官网给的示例截图
附件中的代码依旧是极简的例子,自定义样式我就留给使用者自己实现了。毕竟,萝卜白菜,各有所爱。
如果喜欢,可以送两朵花或者评论留言让我知道(花了半天时间写的代码是值得的)。祝好!
|