]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxHelpEvent, wxContextHelp (MSW only so far), modified help sample
authorJulian Smart <julian@anthemion.co.uk>
Wed, 6 Sep 2000 09:45:24 +0000 (09:45 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Wed, 6 Sep 2000 09:45:24 +0000 (09:45 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8271 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
docs/latex/wx/listctrl.tex
include/wx/defs.h
include/wx/event.h
include/wx/helpbase.h
samples/help/demo.cpp
src/common/event.cpp
src/common/helpbase.cpp
src/generic/splash.cpp
src/msw/cursor.cpp
src/msw/dialog.cpp
src/msw/frame.cpp
src/msw/window.cpp

index 02eaefa92b6dcf585ad3184d54a282b42e21b851..a275fe865f165499690e19b91b0719dcbdccdd23 100644 (file)
@@ -39,6 +39,8 @@ the list wraps, unlike a wxListBox.}
 \twocolitem{\windowstyle{wxLC\_SINGLE\_SEL}}{Single selection.}
 \twocolitem{\windowstyle{wxLC\_SORT\_ASCENDING}}{Sort in ascending order (must still supply a comparison callback in SortItems.}
 \twocolitem{\windowstyle{wxLC\_SORT\_DESCENDING}}{Sort in descending order (must still supply a comparison callback in SortItems.}
+\twocolitem{\windowstyle{wxLC\_HRULES}}{Draws light horizontal rules between rows in report mode.}
+\twocolitem{\windowstyle{wxLC\_VRULES}}{Draws light vertical rules between columns in report mode.}
 \end{twocollist}
 
 See also \helpref{window styles overview}{windowstyles}.
index 8743441215e127ffd86654fe77d9d50cad7983c3..3e690ec0b57672f0383ceb31d1991ef4b6d4bc9b 100644 (file)
@@ -917,6 +917,10 @@ enum wxStretch
 // Add for normal Windows frame behaviour
 #define wxFRAME_FLOAT_ON_PARENT 0x0020
 
+// Context-sensitive help
+#define wxFRAME_EX_CONTEXTHELP  0x00000004
+#define wxDIALOG_EX_CONTEXTHELP 0x00000004
+
 /*
  * MDI parent frame style flags
  * Can overlap with some of the above.
index aaa172a39c2f5edee478a1f1c990470c2310d19b..6a2a9f46c7079d3bf1ee31976623bcc7bcece092 100644 (file)
@@ -291,6 +291,9 @@ enum
     wxEVT_PLOT_END_TITLE_EDIT = wxEVT_FIRST + 1025,
     wxEVT_PLOT_AREA_CREATE = wxEVT_FIRST + 1026,
 
+    /* Help events */
+    wxEVT_HELP = wxEVT_FIRST + 1050,
+
     wxEVT_USER_FIRST = wxEVT_FIRST + 2000
 };
 
@@ -1400,6 +1403,26 @@ public:
     wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
 };
 
+/*
+ wxEVT_HELP
+ Sent when the user clicks on a window in context-help mode.
+ The cursor position is in screen coordinates.
+ */
+
+class WXDLLEXPORT wxHelpEvent : public wxCommandEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxHelpEvent)
+
+public:
+  wxHelpEvent(wxEventType type = wxEVT_NULL, wxWindowID id = 0, const wxPoint& pt = wxPoint(0, 0))
+      { m_eventType = type; m_id = id; m_pos = pt; }
+
+  const wxPoint& GetPosition() const { return m_pos; }
+  void SetPosition(const wxPoint& pos) { m_pos = pos; }
+
+  wxPoint   m_pos;
+};
+
 #endif // wxUSE_GUI
 
 // Idle event
@@ -1603,6 +1626,7 @@ typedef void (wxEvtHandler::*wxWindowCreateEventFunction)(wxWindowCreateEvent&);
 typedef void (wxEvtHandler::*wxWindowDestroyEventFunction)(wxWindowDestroyEvent&);
 typedef void (wxEvtHandler::*wxSetCursorEventFunction)(wxSetCursorEvent&);
 typedef void (wxEvtHandler::*wxNotifyEventFunction)(wxNotifyEvent&);
+typedef void (wxEvtHandler::*wxHelpEventFunction)(wxHelpEvent&);
 #endif // wxUSE_GUI
 
 // N.B. In GNU-WIN32, you *have* to take the address of a member function
@@ -1818,6 +1842,13 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_UPDATE_UI_RANGE(id1, id2, func) \
  { wxEVT_UPDATE_UI, id1, id2, (wxObjectEventFunction)(wxEventFunction)(wxUpdateUIEventFunction)&func, (wxObject *) NULL },
 
+// Help events
+#define EVT_HELP(id, func) \
+ { wxEVT_HELP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxHelpEventFunction) & func, (wxObject *) NULL },
+
+#define EVT_HELP_RANGE(id1, id2, func) \
+ { wxEVT_HELP, id1, id2, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxHelpEventFunction) & func, (wxObject *) NULL },
+
 // ----------------------------------------------------------------------------
 // Global data
 // ----------------------------------------------------------------------------
index c35b3b0cb125427f9bc607798007d3c4c0278034..97e42f6e9a43d9d803173822ad3653d6085ebe91 100644 (file)
@@ -76,6 +76,35 @@ public:
     virtual void OnQuit(void) {};
 };
 
+/*
+ * wxContextHelp
+ * Invokes context-sensitive help. When the user
+ * clicks on a window, a wxEVT_HELP event will be sent to that
+ * window for the application to display help for.
+ */
+
+class WXDLLEXPORT wxContextHelp: public wxObject
+{
+    DECLARE_DYNAMIC_CLASS(wxContextHelp)
+public:
+    wxContextHelp(wxWindow* win = NULL, bool beginHelp = TRUE);
+    ~wxContextHelp();
+
+    bool BeginContextHelp(wxWindow* win);
+    bool EndContextHelp();
+
+    bool EventLoop(const wxCursor& cursor, wxWindow* win);
+    bool DispatchEvent(wxWindow* win, const wxPoint& pt);
+
+#ifdef __WXMSW__
+    bool ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* win);
+#endif
+
+protected:
+
+    bool    m_inHelp;
+};
+
 #endif // wxUSE_HELP
 #endif
 // _WX_HELPBASEH__
index ed5eb84f1dea8de94bb7962f1e8156cfda734df0..210283ab9574b2844acc5c2cb5e20f8f2cd709ae 100644 (file)
@@ -113,6 +113,9 @@ public:
     void OnAdvancedHtmlHelp(wxCommandEvent& event);
     void OnMSHtmlHelp(wxCommandEvent& event);
 
+    void OnContextHelp(wxHelpEvent& event);
+    void OnShowContextHelp(wxCommandEvent& event);
+
     void ShowHelp(int commandId, wxHelpControllerBase& helpController);
 
 private:
@@ -147,6 +150,7 @@ enum
     HelpDemo_Help_Functions,
     HelpDemo_Help_Help,
     HelpDemo_Help_Search,
+    HelpDemo_Help_ContextHelp,
 
     HelpDemo_Html_Help_Index,
     HelpDemo_Html_Help_Classes,
@@ -187,6 +191,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(HelpDemo_Help_Functions, MyFrame::OnHelp)
     EVT_MENU(HelpDemo_Help_Help, MyFrame::OnHelp)
     EVT_MENU(HelpDemo_Help_Search, MyFrame::OnHelp)
+    EVT_MENU(HelpDemo_Help_ContextHelp, MyFrame::OnShowContextHelp)
+
+    EVT_HELP(-1, MyFrame::OnContextHelp)
 
     EVT_MENU(HelpDemo_Html_Help_Index, MyFrame::OnHtmlHelp)
     EVT_MENU(HelpDemo_Html_Help_Classes, MyFrame::OnHtmlHelp)
@@ -310,6 +317,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
     menuFile->Append(HelpDemo_Help_Index, "&Help Index...");
     menuFile->Append(HelpDemo_Help_Classes, "&Help on Classes...");
     menuFile->Append(HelpDemo_Help_Functions, "&Help on Functions...");
+    menuFile->Append(HelpDemo_Help_ContextHelp, "&Context Help...");
     menuFile->Append(HelpDemo_Help_Help, "&About Help Demo...");
     menuFile->Append(HelpDemo_Help_Search, "&Search help...");
 #if USE_HTML_HELP
@@ -384,6 +392,21 @@ void MyFrame::OnHelp(wxCommandEvent& event)
     ShowHelp(event.GetId(), m_help);
 }
 
+void MyFrame::OnShowContextHelp(wxCommandEvent& event)
+{
+    // This starts context help mode, then the user
+    // clicks on a window to send a help message
+    wxContextHelp contextHelp(this);
+}
+
+void MyFrame::OnContextHelp(wxHelpEvent& event)
+{
+    // In a real app, if we didn't recognise this ID, we should call event.Skip()
+    wxString msg;
+    msg.Printf(wxT("We should now display help for window %d"), event.GetId());
+    wxMessageBox(msg);
+}
+
 void MyFrame::OnHtmlHelp(wxCommandEvent& event)
 {
 #if USE_HTML_HELP && USE_OLD_HTML_HELP
index 3ace246251136bc2af953944ede28d1f2c09eb7a..87eda81fdb0ab43f4b79f2295cd6924a26967241 100644 (file)
@@ -82,6 +82,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent)
+    IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent, wxCommandEvent)
 #endif // wxUSE_GUI
 
 const wxEventTable *wxEvtHandler::GetEventTable() const
index 94d808ac5b11aea9a6814247fb642e56830bcd12..2a1b47943c5e28a2d82c43e3a16dc170c097f95b 100644 (file)
 
 #include "wx/helpbase.h"
 
+#ifdef __WXMSW__
+#include "wx/msw/private.h"
+#endif
+
 #if wxUSE_HELP
 
 IMPLEMENT_CLASS(wxHelpControllerBase, wxObject)
 
+/*
+ * Invokes context-sensitive help
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
+
+wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
+{
+    m_inHelp = FALSE;
+
+    if (beginHelp)
+        BeginContextHelp(win);
+}
+
+wxContextHelp::~wxContextHelp()
+{
+    if (m_inHelp)
+        EndContextHelp();
+}
+
+bool wxContextHelp::BeginContextHelp(wxWindow* win)
+{
+    if (!win)
+        win = wxTheApp->GetTopWindow();
+    if (!win)
+        return FALSE;
+
+    wxCursor cursor(wxCURSOR_QUESTION_ARROW);
+    wxSetCursor(cursor);
+
+    win->CaptureMouse();
+
+    EventLoop(cursor, win);
+
+    win->ReleaseMouse();
+
+    return TRUE;
+}
+
+bool wxContextHelp::EndContextHelp()
+{
+    m_inHelp = FALSE;
+
+    return TRUE;
+}
+
+bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win)
+{
+#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;
+#else
+    return FALSE;
+#endif
+}
+
+#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)
+        {
+            // 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;
+                       }
+        }
+        else
+        {
+            // Someone else's message
+                   if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
+            {
+                ::TranslateMessage(&msg);
+                ::DispatchMessage(&msg);
+            }
+            return TRUE;
+        }
+    }
+    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)
+{
+    wxWindow* subjectOfHelp = win;
+    bool eventProcessed = FALSE;
+    while (subjectOfHelp && !eventProcessed)
+    {
+        wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
+        helpEvent.SetEventObject(this);
+        eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
+        
+        // Go up the window hierarchy until the event is handled (or not).
+        // I.e. keep submitting ancestor windows until one is recognised
+        // by the app code that processes the ids and displays help.
+        subjectOfHelp = subjectOfHelp->GetParent();
+    }
+    return eventProcessed;
+}
+
+
 #endif // wxUSE_HELP
index 9cb2778415c5405b425999bea037894f372820bf..a407dd1653ff7586e93575324fe97de2ea7340dc 100644 (file)
@@ -46,7 +46,14 @@ wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int mil
 
     m_window = new wxSplashScreenWindow(bitmap, this, -1, pos, size, wxNO_BORDER);
 
-    SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
+    // For some reason, we need to make the client size a couple of pixels
+    // bigger for all of the bitmap to show.
+#ifdef __WXMSW__
+    int fudge = 2;
+#else
+    int fudge = 0;
+#endif
+    SetClientSize(bitmap.GetWidth()+fudge, bitmap.GetHeight()+fudge);
 
     if (m_splashStyle & wxSPLASH_CENTRE_ON_PARENT)
         CentreOnParent();
index b715483ccb9dd00ac85014ea89a211138fc9c724..0f7ce4ac2a91da7e1a7c7fbd0fc2ce18c882dddf 100644 (file)
@@ -289,6 +289,7 @@ wxCursor::wxCursor(int cursor_type)
     }
     case wxCURSOR_QUESTION_ARROW:
     {
+//      refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
       refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
       break;
     }
index 23ea6b6d81a05f6c247523558a34c94412408f0c..8df2875db1cd37c1726361e0a6c0d1d8156e9092 100644 (file)
@@ -152,6 +152,8 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
     WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle);
     if (m_windowStyle & wxSTAY_ON_TOP)
         extendedStyle |= WS_EX_TOPMOST;
+    if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
+        extendedStyle |= WS_EX_CONTEXTHELP;
 
     // Allows creation of dialogs with & without captions under MSWindows,
     // resizeable or not (but a resizeable dialog always has caption -
index fb57117e5013024332cc4414bfbd8b3d03333689..7d187c42200e5f0f87ec7f110b5409a6eaf82d59 100644 (file)
@@ -680,6 +680,9 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow
   if (style & wxSTAY_ON_TOP)
     extendedStyle |= WS_EX_TOPMOST;
 
+  if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
+    extendedStyle |= WS_EX_CONTEXTHELP;
+
   m_iconized = FALSE;
   if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
          msflags, NULL, extendedStyle) )
index 84786c91e83def6f73a81a34e947f547bed14171..dbac074afc5ae9c05d817f5a74cf7baf809bfb37 100644 (file)
@@ -2170,6 +2170,36 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                 rc.result = TRUE;
             }
             break;
+#ifdef __WIN32__
+        case WM_HELP:
+        {
+            HELPINFO* info = (HELPINFO*) lParam;
+            // Don't yet process menu help events, just windows
+            if (info->iContextType == HELPINFO_WINDOW)
+            {
+                wxWindow* subjectOfHelp = this;
+                bool eventProcessed = FALSE;
+                while (subjectOfHelp && !eventProcessed)
+                {
+                    wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), wxPoint(info->MousePos.x, info->MousePos.y) ) ; // info->iCtrlId);
+                    helpEvent.SetEventObject(this);
+                    eventProcessed = GetEventHandler()->ProcessEvent(helpEvent);
+
+                    // Go up the window hierarchy until the event is handled (or not)
+                    subjectOfHelp = subjectOfHelp->GetParent();
+                }
+                processed = eventProcessed;
+            }
+            else if (info->iContextType == HELPINFO_MENUITEM)
+            {
+                wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId) ;
+                helpEvent.SetEventObject(this);
+                processed = GetEventHandler()->ProcessEvent(helpEvent);
+            }
+            else processed = FALSE;
+            break;
+        }
+#endif
     }
 
     if ( !processed )
@@ -3173,7 +3203,7 @@ void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags)
     event.m_leftDown = ((flags & MK_LBUTTON) != 0);
     event.m_middleDown = ((flags & MK_MBUTTON) != 0);
     event.m_rightDown = ((flags & MK_RBUTTON) != 0);
-    event.m_altDown = ::GetKeyState(VK_MENU) & 0x80000000;
+    event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
     event.SetTimestamp(s_currentMsg.time);
     event.m_eventObject = this;