replaced wxYield() call in PopupMenu() by a much safer wxYieldForCommandsOnly() - fixes tree ctrl bug

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10455 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-06-08 01:47:15 +00:00
parent 58b24a564c
commit ed45e26357
3 changed files with 52 additions and 6 deletions

View File

@ -77,10 +77,25 @@ public:
static void CleanUp();
static bool RegisterWindowClasses();
// Convert Windows to argc, argv style
void ConvertToStandardCommandArgs(char* p);
// message processing
// ------------------
// process the given message
virtual void DoMessage(WXMSG *pMsg);
// retrieve the next message from the queue and process it
virtual bool DoMessage();
// preprocess the message
virtual bool ProcessMessage(WXMSG* pMsg);
// idle processing
// ---------------
void DeletePendingObjects();
bool ProcessIdle();

View File

@ -957,16 +957,21 @@ bool wxApp::DoMessage()
#endif // wxUSE_THREADS
// Process the message
if ( !ProcessMessage((WXMSG *)&s_currentMsg) )
{
::TranslateMessage(&s_currentMsg);
::DispatchMessage(&s_currentMsg);
}
DoMessage((WXMSG *)&s_currentMsg);
}
return TRUE;
}
void wxApp::DoMessage(WXMSG *pMsg)
{
if ( !ProcessMessage(pMsg) )
{
::TranslateMessage((MSG *)pMsg);
::DispatchMessage((MSG *)pMsg);
}
}
/*
* Keep trying to process messages until WM_QUIT
* received.

View File

@ -1484,6 +1484,23 @@ void wxWindow::GetCaretPos(int *x, int *y) const
// popup menu
// ---------------------------------------------------------------------------
// yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue
// immediately, without waiting for the next event loop iteration
//
// NB: this function should probably be made public later as it can almost
// surely replace wxYield() elsewhere as well
static void wxYieldForCommandsOnly()
{
// peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
// want to process it here)
MSG msg;
while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
&& msg.message != WM_QUIT )
{
wxTheApp->DoMessage((WXMSG *)&msg);
}
}
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
{
menu->SetInvokingWindow(this);
@ -1497,7 +1514,16 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
::ClientToScreen(hWnd, &point);
wxCurrentPopupMenu = menu;
::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);
wxYieldIfNeeded();
// we need to do it righ now as otherwise the events are never going to be
// sent to wxCurrentPopupMenu from HandleCommand()
//
// note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
// help and we'd still need wxYieldForCommandsOnly() as the menu may be
// destroyed as soon as we return (it can be a local variable in the caller
// for example) and so we do need to process the event immediately
wxYieldForCommandsOnly();
wxCurrentPopupMenu = NULL;
menu->SetInvokingWindow(NULL);