使用派生的 DateTimePicker 类显示自定义日历下拉列表
我的目标是在 .NET 2.0 中创建自定义 DateTimePicker 类,它显示自定义日历下拉列表而不是 Windows 默认日历弹出窗口。
通过观察 Windows 消息(请参阅随附的代码),我能够在创建后找到并隐藏/关闭日历窗口。
然而,仍然存在一个问题:日历窗口关闭后,仍然有东西阻止鼠标输入。例如,如果您在以编程方式关闭日历下拉列表(附加代码)后尝试最大化自定义 DateTimePicker 控件的所有者窗体,则最大化按钮不会响应。只有下一次单击才起作用。有趣的是,“非功能性点击”会触发 DTN_CLOSEUP 通知,因此 WM_CLOSE 似乎没有正确关闭日历。
非常感谢任何有关如何完成我的任务的提示:)
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == (int)SYSMSG.WM_REFLECT + (int)SYSMSG.WM_NOTIFY)
{
NMHDR nmhdr = (NMHDR)m.GetLParam(typeof(NMHDR));
switch (nmhdr.code)
{
case DTN_DROPDOWN:
// Hide window
IntPtr calHandle = FindWindow("SysMonthCal32", null);
SendMessage(calHandle, (int)SYSMSG.WM_SIZE, 0, SP.Convert.MakeLong(0, 0));
this.BeginInvoke((MethodInvoker)delegate()
{
SendMessage(calHandle, (int)SYSMSG.WM_CLOSE, 0, 0);
});
break;
}
}
base.WndProc(ref m);
}
My goal is to create a custom DateTimePicker class in .NET 2.0, which shows a custom calendar dropdown instead of the Windows default calendar popup.
By observing Windows messages (see attached code), I am able to find and hide/close the calendar window after creation.
However, a problem remains: After the calendar window is closed, something is still blocking the mouse input. For example, if you try to maximise the owner form of the customised DateTimePicker control after the calendar dropdown has been closed programmatically (attached code), the maximise button does not respond. Only the next click works. Interestingly, the "non-functional click" fires the DTN_CLOSEUP notification, so it appears that the WM_CLOSE did not properly close the calendar.
Any hints on how to accomplish my task are highly appreciated :)
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == (int)SYSMSG.WM_REFLECT + (int)SYSMSG.WM_NOTIFY)
{
NMHDR nmhdr = (NMHDR)m.GetLParam(typeof(NMHDR));
switch (nmhdr.code)
{
case DTN_DROPDOWN:
// Hide window
IntPtr calHandle = FindWindow("SysMonthCal32", null);
SendMessage(calHandle, (int)SYSMSG.WM_SIZE, 0, SP.Convert.MakeLong(0, 0));
this.BeginInvoke((MethodInvoker)delegate()
{
SendMessage(calHandle, (int)SYSMSG.WM_CLOSE, 0, 0);
});
break;
}
}
base.WndProc(ref m);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否尝试过发送
DTM_CLOSEMONTHCAL
消息,而不是发送WM_CLOSE
消息?您可以将其发送到 DateTimePicker 本身的 HWND,而不是子窗口。根据文档, DateTime_CloseMonthCal 宏发送这条消息似乎是你想做的。我也不认为您需要使用 BeginInvoke 来发送它,除非在与下拉通知相同的调度中关闭它存在一些问题。
Instead of sending a
WM_CLOSE
have you tried sending aDTM_CLOSEMONTHCAL
message instead? You would send this to the HWND of the DateTimePicker itself and not the child window. According to the documentation, the DateTime_CloseMonthCal macro sends this message and it seems like what you want to do.I also don't think you'll need to use BeginInvoke to send it unless there's some problem with closing it in the same dispatch as a drop down notification.
我终于找到了这个完全可定制的 datePicker (monthCalendar 渲染是可重写的): Culture Aware Month Calendar 和CodeProject 上的日期选择器
I finally found this fully customisable datePicker (monthCalendar rendering is override-able) : Culture Aware Month Calendar and Datepicker on CodeProject