From 3723b7b1d8cbeebccef4f8ad7fe3884dfca9eca6 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Thu, 7 Sep 2000 09:43:05 +0000 Subject: [PATCH] Made wxContextHelp implementation generic and added wxFindWindowAtPointer, wxGetMousePosition functions git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8280 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/helpbase.h | 16 +-- include/wx/window.h | 9 +- src/common/helpbase.cpp | 280 +++++--------------------------------- src/gtk/window.cpp | 59 ++++++++ src/gtk1/window.cpp | 59 ++++++++ src/mac/carbon/window.cpp | 16 +++ src/mac/window.cpp | 16 +++ src/motif/window.cpp | 16 +++ src/msw/window.cpp | 45 ++++++ 9 files changed, 258 insertions(+), 258 deletions(-) diff --git a/include/wx/helpbase.h b/include/wx/helpbase.h index 5cfe17c0b2..d6d7ff83b5 100644 --- a/include/wx/helpbase.h +++ b/include/wx/helpbase.h @@ -93,25 +93,15 @@ public: bool BeginContextHelp(wxWindow* win); bool EndContextHelp(); - bool EventLoop(const wxCursor& cursor, wxWindow* win); + bool EventLoop(); bool DispatchEvent(wxWindow* win, const wxPoint& pt); -#ifdef __WXMSW__ - bool ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* win); -#endif - -#ifdef __WXGTK__ - void SetStatus(bool status, const wxPoint& pt) { m_status = status; m_mousePos = pt; } -#endif + void SetStatus(bool status) { m_status = status; } protected: bool m_inHelp; - -#ifdef __WXGTK__ - bool m_status; // The user left-clicked - wxPoint m_mousePos; -#endif + bool m_status; // TRUE if the user left-clicked }; #endif // wxUSE_HELP diff --git a/include/wx/window.h b/include/wx/window.h index 3410f7d3b5..e3ae2b4d99 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -885,11 +885,18 @@ inline wxWindow *wxWindowBase::GetGrandParent() const } // ---------------------------------------------------------------------------- -// global function +// global functions // ---------------------------------------------------------------------------- WXDLLEXPORT extern wxWindow* wxGetActiveWindow(); +// Find the wxWindow at the current mouse position, also returning the mouse +// position. +WXDLLEXPORT extern wxWindow* wxFindWindowAtPointer(wxPoint& pt); + +// Get the current mouse position. +WXDLLEXPORT extern wxPoint wxGetMousePosition(); + // deprecated (doesn't start with 'wx' prefix), use wxWindow::NewControlId() inline WXDLLEXPORT int NewControlId() { return wxWindowBase::NewControlId(); } diff --git a/src/common/helpbase.cpp b/src/common/helpbase.cpp index d07256a257..8696ad47aa 100644 --- a/src/common/helpbase.cpp +++ b/src/common/helpbase.cpp @@ -27,17 +27,6 @@ #include "wx/helpbase.h" #include "wx/app.h" -#ifdef __WXMSW__ -#include "wx/msw/private.h" -#endif - -#ifdef __WXGTK__ -#include -#include -#include "wx/gtk/win_gtk.h" -#include "wx/msgdlg.h" -#endif - #if wxUSE_HELP IMPLEMENT_CLASS(wxHelpControllerBase, wxObject) @@ -46,9 +35,8 @@ IMPLEMENT_CLASS(wxHelpControllerBase, wxObject) * Invokes context-sensitive help */ -#ifdef __WXGTK__ - // This class exists in order to eat events until the left mouse - // button is pressed +// This class exists in order to eat events until the left mouse +// button is pressed class wxContextHelpEvtHandler: public wxEvtHandler { public: @@ -62,7 +50,6 @@ public: //// Data wxContextHelp* m_contextHelp; }; -#endif IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject) @@ -80,123 +67,38 @@ wxContextHelp::~wxContextHelp() EndContextHelp(); } -#ifdef __WXGTK__ -wxWindow* wxFindWindowForGdkWindow(wxWindow* win, GdkWindow* gdkWindow) -{ - GdkWindow* thisGdkWindow1 = 0; - GdkWindow* thisGdkWindow2 = 0; - - if (win->m_wxwindow) - thisGdkWindow1 = GTK_PIZZA(win->m_wxwindow)->bin_window; - - thisGdkWindow2 = win->m_widget->window; - - if (gdkWindow == thisGdkWindow1 || gdkWindow == thisGdkWindow2) - return win; - - wxNode* node = win->GetChildren().First(); - while (node) - { - wxWindow* child = (wxWindow*) node->Data(); - wxWindow* found = wxFindWindowForGdkWindow(child, gdkWindow); - if (found) - return found; - - node = node->Next(); - } - return NULL; -} -#endif - +// Begin 'context help mode' bool wxContextHelp::BeginContextHelp(wxWindow* win) { if (!win) win = wxTheApp->GetTopWindow(); if (!win) return FALSE; -#ifdef __WXMSW__ + wxCursor cursor(wxCURSOR_QUESTION_ARROW); + wxCursor oldCursor = win->GetCursor(); + win->SetCursor(cursor); wxSetCursor(cursor); - win->CaptureMouse(); - - EventLoop(cursor, win); - - win->ReleaseMouse(); -#endif - -#ifdef __WXGTK__ - m_status = FALSE; - GdkCursor* query_cursor = gdk_cursor_new (GDK_QUESTION_ARROW); - - GdkWindow* gdkWindow = 0; - GtkWidget* gtkWidget = 0; - - if (win->m_wxwindow) - { - gtkWidget = win->m_wxwindow; - gdkWindow = GTK_PIZZA(win->m_wxwindow)->bin_window; - } - else - { - gtkWidget = win->m_widget; - gdkWindow = win->m_widget->window; - } - - gint failure = gdk_pointer_grab (gdkWindow, - FALSE, - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK, - NULL, - query_cursor, - GDK_CURRENT_TIME); - if (failure) - { - gdk_cursor_destroy (query_cursor); - query_cursor = NULL; - } - gdk_keyboard_grab (gdkWindow, FALSE, GDK_CURRENT_TIME); - gtk_grab_add (gtkWidget); - win->PushEventHandler(new wxContextHelpEvtHandler(this)); - // wxLogDebug("Entering loop."); + win->CaptureMouse(); - EventLoop(wxNullCursor, win); + EventLoop(); - // wxLogDebug("Exiting loop."); + win->ReleaseMouse(); win->PopEventHandler(TRUE); - gtk_grab_remove (gtkWidget); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); - if (query_cursor) - { - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_cursor_destroy (query_cursor); - query_cursor = NULL; - } + win->SetCursor(oldCursor); if (m_status) - { - //wxMessageBox("Left-clicked"); - //wxPoint screenPt = win->ClientToScreen(m_mousePos); - int x, y; - GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y); - if (windowAtPtr) - { - wxWindow* wxWinAtPtr = wxFindWindowForGdkWindow(win, windowAtPtr); - if (wxWinAtPtr) - { - DispatchEvent(wxWinAtPtr, wxPoint(x, y)); - } - } - } - else - { - //wxMessageBox("Cancelled"); - } -#endif + { + wxPoint pt; + wxWindow* winAtPtr = wxFindWindowAtPointer(pt); + if (winAtPtr) + DispatchEvent(winAtPtr, pt); + } return TRUE; } @@ -208,27 +110,8 @@ bool wxContextHelp::EndContextHelp() return TRUE; } -bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win) +bool wxContextHelp::EventLoop() { -#ifdef __WXMSW__ - m_inHelp = TRUE; - while ( m_inHelp ) - { - MSG msg; - if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) - { - if (!ProcessHelpMessage((WXMSG*) & msg, cursor, win)) - { - m_inHelp = FALSE; - } - } - else - { - wxTheApp->ProcessIdle(); - } - } - return TRUE; -#elif defined(__WXGTK__) m_inHelp = TRUE; while ( m_inHelp ) { @@ -242,131 +125,41 @@ bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win) } } return TRUE; -#else - return FALSE; -#endif } -// PROBLEM: If you click on the panel or other descendant of the -// given window, then it doesn't go to this handler, even though -// there's a grab. bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event) { - //wxLogDebug("Got event"); - - if (event.GetEventType() == wxEVT_LEFT_DOWN) + switch (event.GetEventType()) { - //wxLogDebug("Mouse event"); - wxMouseEvent& mouseEvent = (wxMouseEvent&) event; - m_contextHelp->SetStatus(TRUE, mouseEvent.GetPosition()); - m_contextHelp->EndContextHelp(); - } - // Don't know why these aren't being caught - else if (event.GetEventType() == wxEVT_CHAR || event.GetEventType() == wxEVT_KEY_DOWN) - { - //wxKeyEvent& keyEvent = (wxKeyEvent&) event; - if (TRUE) // keyEvent.GetKeyCode() == WXK_ESCAPE) + case wxEVT_LEFT_DOWN: { - m_contextHelp->SetStatus(FALSE, wxPoint(0, 0)); + wxMouseEvent& mouseEvent = (wxMouseEvent&) event; + m_contextHelp->SetStatus(TRUE); m_contextHelp->EndContextHelp(); + return TRUE; + break; } - } - - return TRUE; -} - -#ifdef __WXMSW__ -bool wxContextHelp::ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* winInQuestion) -{ - MSG& msg = * (MSG*) wxmsg; - - if (msg.message == WM_KEYDOWN || msg.wParam == VK_ESCAPE) - { - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - return FALSE; - } - - if (msg.message == WM_CAPTURECHANGED) - { - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - return FALSE; - } - - if (msg.message == WM_ACTIVATE) - { - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - return FALSE; - } - - if ((msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)) -// || (msg.message >= WM_NCMOUSEFIRST && msg.message <= WM_NCMOUSELAST)) - { - wxSetCursor(cursor); - - HWND hWndHit = ::WindowFromPoint(msg.pt); - - wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ; - HWND hWnd = hWndHit; - - // Try to find a window with a wxWindow associated with it - while (!win && (hWnd != 0)) - { - hWnd = ::GetParent(hWnd); - win = wxFindWinFromHandle((WXHWND) hWnd) ; - } - - if (win) + case wxEVT_CHAR: + case wxEVT_KEY_DOWN: + case wxEVT_ACTIVATE: + case wxEVT_MOUSE_CAPTURE_CHANGED: { - // It's a wxWindows window - if (msg.message != WM_LBUTTONDOWN) - { - // Hit one of our owned windows -- eat the message. - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - return TRUE; - } - int iHit = (int)::SendMessage(hWndHit, WM_NCHITTEST, 0, - MAKELONG(msg.pt.x, msg.pt.y)); - if (iHit == HTMENU || iHit == HTSYSMENU) - { - // Eat this message, send the event and return - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y)); - return FALSE; - } - else if (iHit == HTCLIENT) - { - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y)); - return FALSE; - } - else - { - PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); - return FALSE; - } + m_contextHelp->SetStatus(FALSE); + m_contextHelp->EndContextHelp(); + return TRUE; + break; } - else + case wxEVT_PAINT: + case wxEVT_ERASE_BACKGROUND: { - // Someone else's message - if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - return TRUE; + event.Skip(); + return FALSE; + break; } } - else - { - // allow all other messages to go through (capture still set) - if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE)) - DispatchMessage(&msg); - return TRUE; - } return TRUE; } -#endif // Dispatch the help event to the relevant window bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt) @@ -387,5 +180,4 @@ bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt) return eventProcessed; } - #endif // wxUSE_HELP diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 7d1eed6e42..15d638df75 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3753,3 +3753,62 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) } */ } + +// Helper for wxFindWindowAtPointer +wxWindow* wxFindWindowForGdkWindow(wxWindow* win, GdkWindow* gdkWindow) +{ + GdkWindow* thisGdkWindow1 = 0; + GdkWindow* thisGdkWindow2 = 0; + + if (win->m_wxwindow) + thisGdkWindow1 = GTK_PIZZA(win->m_wxwindow)->bin_window; + + thisGdkWindow2 = win->m_widget->window; + + if (gdkWindow == thisGdkWindow1 || gdkWindow == thisGdkWindow2) + return win; + + wxNode* node = win->GetChildren().First(); + while (node) + { + wxWindow* child = (wxWindow*) node->Data(); + wxWindow* found = wxFindWindowForGdkWindow(child, gdkWindow); + if (found) + return found; + + node = node->Next(); + } + return NULL; +} + +// Find the wxWindow at the current mouse position, also returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + int x, y; + GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y); + pt.x = x; + pt.y = y; + if (windowAtPtr) + { + wxNode* node = wxTopLevelWindows.First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + wxWindow* wxWinAtPtr = wxFindWindowForGdkWindow(win, windowAtPtr); + if (wxWinAtPtr) + return wxWinAtPtr; + node = node->Next(); + } + } + return NULL; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + int x, y; + GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y); + return wxPoint(x, y); +} + diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 7d1eed6e42..15d638df75 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -3753,3 +3753,62 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) } */ } + +// Helper for wxFindWindowAtPointer +wxWindow* wxFindWindowForGdkWindow(wxWindow* win, GdkWindow* gdkWindow) +{ + GdkWindow* thisGdkWindow1 = 0; + GdkWindow* thisGdkWindow2 = 0; + + if (win->m_wxwindow) + thisGdkWindow1 = GTK_PIZZA(win->m_wxwindow)->bin_window; + + thisGdkWindow2 = win->m_widget->window; + + if (gdkWindow == thisGdkWindow1 || gdkWindow == thisGdkWindow2) + return win; + + wxNode* node = win->GetChildren().First(); + while (node) + { + wxWindow* child = (wxWindow*) node->Data(); + wxWindow* found = wxFindWindowForGdkWindow(child, gdkWindow); + if (found) + return found; + + node = node->Next(); + } + return NULL; +} + +// Find the wxWindow at the current mouse position, also returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + int x, y; + GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y); + pt.x = x; + pt.y = y; + if (windowAtPtr) + { + wxNode* node = wxTopLevelWindows.First(); + while (node) + { + wxWindow* win = (wxWindow*) node->Data(); + wxWindow* wxWinAtPtr = wxFindWindowForGdkWindow(win, windowAtPtr); + if (wxWinAtPtr) + return wxWinAtPtr; + node = node->Next(); + } + } + return NULL; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + int x, y; + GdkWindow* windowAtPtr = gdk_window_at_pointer(& x, & y); + return wxPoint(x, y); +} + diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 8c14292b7d..ea685b9886 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -2356,3 +2356,19 @@ wxMacDrawingClientHelper::~wxMacDrawingClientHelper() if ( m_formerPort != m_currentPort ) SetPort( m_formerPort ) ; } + +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + wxFAIL_MSG(_("Not implemented")); + return NULL; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + wxFAIL_MSG(_("Not implemented")); + return wxPoint; +} + diff --git a/src/mac/window.cpp b/src/mac/window.cpp index 8c14292b7d..ea685b9886 100644 --- a/src/mac/window.cpp +++ b/src/mac/window.cpp @@ -2356,3 +2356,19 @@ wxMacDrawingClientHelper::~wxMacDrawingClientHelper() if ( m_formerPort != m_currentPort ) SetPort( m_formerPort ) ; } + +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + wxFAIL_MSG(_("Not implemented")); + return NULL; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + wxFAIL_MSG(_("Not implemented")); + return wxPoint; +} + diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 0f9a3f6986..53a0dd26e3 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -2984,9 +2984,25 @@ void wxWindow::ChangeFont(bool keepOriginalSize) wxWindow *wxGetActiveWindow() { // TODO + wxFAIL_MSG(_("Not implemented")); return NULL; } +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + wxFAIL_MSG(_("Not implemented")); + return NULL; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + wxFAIL_MSG(_("Not implemented")); + return wxPoint; +} + // ---------------------------------------------------------------------------- // wxNoOptimize: switch off size optimization // ---------------------------------------------------------------------------- diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 014c0747bb..2680a55bcd 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2390,6 +2390,23 @@ bool wxWindow::MSWCreate(int id, ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } +#if defined(__WIN95__) + // For some reason, the system menu is activated when we use the + // WS_EX_CONTEXTHELP style, so let's set a reasonable icon + if (extendedStyle & WS_EX_CONTEXTHELP) + { + if (wxTheApp->GetTopWindow() && (wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)))) + { + wxIcon icon = ((wxFrame*)wxTheApp->GetTopWindow())->GetIcon(); + if (icon.Ok()) + SendMessage(GetHwnd(), WM_SETICON, + (WPARAM)TRUE, (LPARAM)(HICON) icon.GetHICON()); + } + } +#endif // __WIN95__ + + + // JACS: is the following still necessary? The above seems to work. // ::SetWindowLong(GWL_EXSTYLE) doesn't work for the dialogs, so try // to take care of (at least some) extended style flags ourselves @@ -4367,3 +4384,31 @@ static TEXTMETRIC wxGetTextMetrics(const wxWindow *win) return tm; } + +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + // Use current message to find last mouse position + extern MSG s_currentMsg; + HWND hWndHit = ::WindowFromPoint(s_currentMsg.pt); + + wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ; + HWND hWnd = hWndHit; + + // Try to find a window with a wxWindow associated with it + while (!win && (hWnd != 0)) + { + hWnd = ::GetParent(hWnd); + win = wxFindWinFromHandle((WXHWND) hWnd) ; + } + return win; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + extern MSG s_currentMsg; + return wxPoint(s_currentMsg.pt.x, s_currentMsg.pt.y); +} + -- 2.47.2