ID Number: Q74736
3.00
WINDOWS
Summary:
SYMPTOMS
When running an application under the debugging version of Windows
3.0, USER fatal exits with error code 0x0140 when accessing a menu.
CAUSE
The TranslateAccelerator function is not re-entrant in Windows
version 3.0 and, if re-entered, is likely to cause a FatalExit
(RIP) 0x0140 when a menu is accessed.
Applications may use a separate message loop to perform background
processing for a process, such as repaginating a large document or
recalculating a large table. Often this process is started in
response to a particular WM_COMMAND message that may be generated
by a menu selection or a keyboard accelerator.
Inside this secondary message loop, the application may again call
TranslateAccelerator. When this process terminates and the original
WM_COMMAND message is completely processed, the menu will have been
destroyed.
RESOLUTION
To avoid this situation, an application should post a message to
itself to begin the processing. This allows TranslateAccelerator to
finish before the processing begins and the secondary message loop
is entered.
More Information:
When TranslateAccelerator detects a keystroke that is present in the
accelerator table, it sets a flag in the internal menu structure and
sends a WM_COMMAND message to the application. The flag set in the
structure indicates that TranslateAccelerator is in a SendMessage
state.
When this SendMessage call returns, TranslateAccelerator clears this
flag if it is set, or destroys the menu if it is clear. A menu must
only be destroyed when an accelerator caused a menu to be displayed.
This does not occur when an application is running in a normal or
maximized state.
If TranslateAccelerator is called a second time from within the
processing of the first WM_COMMAND message, it will clear the flag set
in the menu structure. When the first call to TranslateAccelerator
returns from its SendMessage, the cleared flag causes the
application's top-level menu to be destroyed. The next time the menu
is accessed, USER will RIP with code 0x0140: Invalid Local Handle
because the menu handle was invalidated with DestroyMenu.
By posting a message in response to the first WM_COMMAND message, the
application allows TranslateAccelerator to return from SendMessage and
exit, which ensures the menu state is properly maintained.