views:

375

answers:

1

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);
}
A: 

Instead of sending a WM_CLOSE have you tried sending a DTM_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.

#define DTM_FIRST        0x1000
#define DTM_CLOSEMONTHCAL (DTM_FIRST + 13)
#define DateTime_CloseMonthCal(hdp) SNDMSG(hdp, DTM_CLOSEMONTHCAL, 0, 0)
Josh Einstein
Thanks for the hint, the message closes the calendar properly. However, the problem with the mouse capture remains, and "this.Capture=false" does not work.
Florian Schmitz