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:
@@ -77,10 +77,25 @@ public:
|
|||||||
static void CleanUp();
|
static void CleanUp();
|
||||||
|
|
||||||
static bool RegisterWindowClasses();
|
static bool RegisterWindowClasses();
|
||||||
|
|
||||||
// Convert Windows to argc, argv style
|
// Convert Windows to argc, argv style
|
||||||
void ConvertToStandardCommandArgs(char* p);
|
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();
|
virtual bool DoMessage();
|
||||||
|
|
||||||
|
// preprocess the message
|
||||||
virtual bool ProcessMessage(WXMSG* pMsg);
|
virtual bool ProcessMessage(WXMSG* pMsg);
|
||||||
|
|
||||||
|
// idle processing
|
||||||
|
// ---------------
|
||||||
|
|
||||||
void DeletePendingObjects();
|
void DeletePendingObjects();
|
||||||
bool ProcessIdle();
|
bool ProcessIdle();
|
||||||
|
|
||||||
|
@@ -957,16 +957,21 @@ bool wxApp::DoMessage()
|
|||||||
#endif // wxUSE_THREADS
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
// Process the message
|
// Process the message
|
||||||
if ( !ProcessMessage((WXMSG *)&s_currentMsg) )
|
DoMessage((WXMSG *)&s_currentMsg);
|
||||||
{
|
|
||||||
::TranslateMessage(&s_currentMsg);
|
|
||||||
::DispatchMessage(&s_currentMsg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxApp::DoMessage(WXMSG *pMsg)
|
||||||
|
{
|
||||||
|
if ( !ProcessMessage(pMsg) )
|
||||||
|
{
|
||||||
|
::TranslateMessage((MSG *)pMsg);
|
||||||
|
::DispatchMessage((MSG *)pMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep trying to process messages until WM_QUIT
|
* Keep trying to process messages until WM_QUIT
|
||||||
* received.
|
* received.
|
||||||
|
@@ -1484,6 +1484,23 @@ void wxWindow::GetCaretPos(int *x, int *y) const
|
|||||||
// popup menu
|
// 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)
|
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
menu->SetInvokingWindow(this);
|
menu->SetInvokingWindow(this);
|
||||||
@@ -1497,7 +1514,16 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
::ClientToScreen(hWnd, &point);
|
::ClientToScreen(hWnd, &point);
|
||||||
wxCurrentPopupMenu = menu;
|
wxCurrentPopupMenu = menu;
|
||||||
::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);
|
::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;
|
wxCurrentPopupMenu = NULL;
|
||||||
|
|
||||||
menu->SetInvokingWindow(NULL);
|
menu->SetInvokingWindow(NULL);
|
||||||
|
Reference in New Issue
Block a user