|
|
|
date: Mon, 9 Jun 2008 06:46:01 -0700,
group: microsoft.public.win32.programmer.ui
back
Modal dialog (MessageBox) in DTN_DATETIMECHANGE handler
I've now used several SysDateTimePick32 / date time picker common controls in
a classic C++/MFC app (developed under VC6). I've noticed that this problem
goes away when using Vista and the new look for the date time picker. However
I'm stuck trying to figure out a way around this.
Easily reproducible; I created a basic test app, which is an MFC dialog with
a single SysDateTimePick32 control on it. I have it using a member variable
that is the standard CDateTimeCtrl, though that is not necessary to the
problem.
When the date changes, I wanted to call a function, which may end up popping
up a MessageBox. In the test app, I simply call a message box in the
DTN_DATETIMECHANGE handler.
When I run the program and drop down the monthview, and change to the next
month, the event is hit and the messagebox is shown. At this point, I can
either hit OK on the messagebox, or I can even click the next month button on
the month view dropdown, which causes yet another messagebox to popup on top
of the other.
The bizarre thing is, when I eventually hit OK, the MonthView dropdown seems
to get in some loop where it is scrolling to the next month every half
second, generating a new event each time, and also another messagebox each
time. The program needs to be ended.
I've tried various things, such as explicitly disabling the control in the
message handler before displaying the message box, and also using
DTM_GETMONTHCAL to get the monthview dropdown HWND and disabling that, but
I've been unable to resolve this issue.
Perhaps posting a message to the parent dialog and handling it could work,
but I would prefer not to do so, since I would like this to be eventually
handled within a derived class of CDateTimeCtrl. Ideally I would want to
handle this within the OnChange handler itself! I've tried even using a
static or member variable to prevent reentrancy, but the case of the runaway
monthview still remains unsolved.
Since this is such a core component of a windows application, I would
imagine others have run into this problem and resolved it, but I have had no
luck finding any discussion on it. Although I did find some discussion about
duplicate/redundant DTN_DATETIMECHANGE notifications.
Some debugging with WinDbg and symbols seems to point to an internal timer
being fired in the common control which helps explain the regular intervals
of the month scrolling. I've personally been able to reproduce this on
several different machines, but still I am at a loss for a resolution.
Perhaps entering the modal loop of the MessageBox in the OnChange handler
must be avoided, but I feel like there has never been a bug or strange
behaviour with windows that has not been worked around somehow. Any help or
insight would be greatly appreciated.
--
Adzm
date: Mon, 9 Jun 2008 06:46:01 -0700
author: Adzm
RE: Modal dialog (MessageBox) in DTN_DATETIMECHANGE handler
For the benefit of future readers of this message, I've solved and worked
around this problem. It may not be the best, but it is working well enough.
If anyone has better ideas, I would be quite interested to see them.
I created a derived class from CDateTimeCtrl, and defined a new message
called WM_DATETIMECHANGEEVENT.
The class has one extra member variable, a BOOLean m_bSendingNotify
initialized to FALSE. The class handles DTN_DATETIMECHANGE via
ON_NOTIFY_REFLECT_EX. In the notify handler, the first thing we do is check
m_bSendingNotify and return FALSE if it is true. Otherwise, we can use the
DateTime_GetMonthCal macro to get the HWND of the dropped down monthview. The
monthview is created and destroyed as it is dropped down or closed up, so the
HWND's validity is an accurate reflection of the dropdown state. If it is not
dropped down, we can return FALSE and have the parent handle it like normal.
However if it is TRUE, we need to get out of this immediate message loop to
prevent this bug. We do this by posting our custom message. When we handle
this in the derived class, we set the m_bSendingNotify member to TRUE, setup
our own NMDATETIMECHANGE structure, SendMessage our generated WM_NOTIFY to
the parent, the OnChange handler is called but sees the m_bSendingNotify flag
is set so the parent handles it, then when SendMessage returns we reset
m_bSendingNotify to FALSE.
It's working great! I hope this provides some help for others who may
stumble across this issue.
--
Adzm
"Adzm" wrote:
> I've now used several SysDateTimePick32 / date time picker common controls in
> a classic C++/MFC app (developed under VC6). I've noticed that this problem
> goes away when using Vista and the new look for the date time picker. However
> I'm stuck trying to figure out a way around this.
>
> Easily reproducible; I created a basic test app, which is an MFC dialog with
> a single SysDateTimePick32 control on it. I have it using a member variable
> that is the standard CDateTimeCtrl, though that is not necessary to the
> problem.
>
> When the date changes, I wanted to call a function, which may end up popping
> up a MessageBox. In the test app, I simply call a message box in the
> DTN_DATETIMECHANGE handler.
>
> When I run the program and drop down the monthview, and change to the next
> month, the event is hit and the messagebox is shown. At this point, I can
> either hit OK on the messagebox, or I can even click the next month button on
> the month view dropdown, which causes yet another messagebox to popup on top
> of the other.
>
> The bizarre thing is, when I eventually hit OK, the MonthView dropdown seems
> to get in some loop where it is scrolling to the next month every half
> second, generating a new event each time, and also another messagebox each
> time. The program needs to be ended.
>
> I've tried various things, such as explicitly disabling the control in the
> message handler before displaying the message box, and also using
> DTM_GETMONTHCAL to get the monthview dropdown HWND and disabling that, but
> I've been unable to resolve this issue.
>
> Perhaps posting a message to the parent dialog and handling it could work,
> but I would prefer not to do so, since I would like this to be eventually
> handled within a derived class of CDateTimeCtrl. Ideally I would want to
> handle this within the OnChange handler itself! I've tried even using a
> static or member variable to prevent reentrancy, but the case of the runaway
> monthview still remains unsolved.
>
> Since this is such a core component of a windows application, I would
> imagine others have run into this problem and resolved it, but I have had no
> luck finding any discussion on it. Although I did find some discussion about
> duplicate/redundant DTN_DATETIMECHANGE notifications.
>
> Some debugging with WinDbg and symbols seems to point to an internal timer
> being fired in the common control which helps explain the regular intervals
> of the month scrolling. I've personally been able to reproduce this on
> several different machines, but still I am at a loss for a resolution.
> Perhaps entering the modal loop of the MessageBox in the OnChange handler
> must be avoided, but I feel like there has never been a bug or strange
> behaviour with windows that has not been worked around somehow. Any help or
> insight would be greatly appreciated.
>
> --
> Adzm
date: Mon, 9 Jun 2008 09:07:44 -0700
author: Adzm
|
|