From: Vadim Zeitlin <vadim@wxwidgets.org> Date: Sun, 14 Feb 1999 21:59:48 +0000 (+0000) Subject: made wxToolTip::Enable() and SetDelay() static (as in wxGTK) and added some X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/16f6dfd814b863ab5ca5b579eee7190fdb209771 made wxToolTip::Enable() and SetDelay() static (as in wxGTK) and added some code in the controls sample to test them git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1693 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/msw/dialog.h b/include/wx/msw/dialog.h index f55129ccf9..e5bd76e8cb 100644 --- a/include/wx/msw/dialog.h +++ b/include/wx/msw/dialog.h @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_DIALOG_H_ @@ -27,7 +27,7 @@ class WXDLLEXPORT wxDialog : public wxPanel public: wxDialog(); - + // Constructor with a modal flag, but no window id - the old convention wxDialog(wxWindow *parent, const wxString& title, bool modal, @@ -39,7 +39,7 @@ public: Create(parent, -1, title, wxPoint(x, y), wxSize(width, height), style | modalStyle, name); } - + // Constructor with no modal flag - the new convention. wxDialog(wxWindow *parent, wxWindowID id, const wxString& title, @@ -50,72 +50,82 @@ public: { Create(parent, id, title, pos, size, style, name); } - + bool Create(wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxDialogNameStr); - + ~wxDialog(); - + virtual bool Destroy(); - + virtual void SetClientSize(int width, int height); - + virtual void GetPosition(int *x, int *y) const; - + bool Show(bool show); bool IsShown() const; void Iconize(bool iconize); - + #if WXWIN_COMPATIBILITY bool Iconized() const { return IsIconized(); }; #endif - + virtual bool IsIconized() const; void Fit(); - + void SetTitle(const wxString& title); wxString GetTitle() const ; - + void OnSize(wxSizeEvent& event); bool OnClose(); void OnCharHook(wxKeyEvent& event); void OnPaint(wxPaintEvent& event); void OnCloseWindow(wxCloseEvent& event); - + void SetModal(bool flag); - + virtual void Centre(int direction = wxBOTH); virtual bool IsModal() const { return ((GetWindowStyleFlag() & wxDIALOG_MODAL) == wxDIALOG_MODAL); } - + // For now, same as Show(TRUE) but returns return code virtual int ShowModal(); virtual void EndModal(int retCode); - + // Standard buttons void OnOK(wxCommandEvent& event); void OnApply(wxCommandEvent& event); void OnCancel(wxCommandEvent& event); - + // Responds to colour changes void OnSysColourChanged(wxSysColourChangedEvent& event); - + // IMPLEMENTATION virtual bool MSWProcessMessage(WXMSG* pMsg); virtual bool MSWOnClose(); virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, WXUINT message, WXWPARAM wParam, WXLPARAM lParam); - + bool IsModalShowing() const { return m_modalShowing; } + // tooltip management +#if wxUSE_TOOLTIPS + WXHWND GetToolTipCtrl() const { return m_hwndToolTip; } + void SetToolTipCtrl(WXHWND hwndTT) { m_hwndToolTip = hwndTT; } +#endif // tooltips + protected: bool m_modalShowing; WXHWND m_hwndOldFocus; // the window which had focus before we were shown - + +#if wxUSE_TOOLTIPS + WXHWND m_hwndToolTip; +#endif // tooltips + DECLARE_EVENT_TABLE() }; diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index 9e976c896a..5f3870950d 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_FRAME_H_ @@ -43,9 +43,9 @@ public: { Create(parent, id, title, pos, size, style, name); } - + ~wxFrame(); - + bool Create(wxWindow *parent, wxWindowID id, const wxString& title, @@ -53,52 +53,52 @@ public: const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr); - + virtual bool Destroy(); - + void SetClientSize(int width, int height); void SetClientSize(const wxSize& sz) { wxWindow::SetClientSize(sz); } - + void GetClientSize(int *width, int *height) const; wxSize GetClientSize() const { return wxWindow::GetClientSize(); } - + void GetSize(int *width, int *height) const ; wxSize GetSize() const { return wxWindow::GetSize(); } - + void GetPosition(int *x, int *y) const ; wxPoint GetPosition() const { return wxWindow::GetPosition(); } - + virtual void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); - + virtual void ClientToScreen(int *x, int *y) const; - + virtual void ScreenToClient(int *x, int *y) const; - + void OnSize(wxSizeEvent& event); void OnMenuHighlight(wxMenuEvent& event); void OnActivate(wxActivateEvent& event); void OnIdle(wxIdleEvent& event); void OnCloseWindow(wxCloseEvent& event); - + bool Show(bool show); - + // Set menu bar void SetMenuBar(wxMenuBar *menu_bar); virtual wxMenuBar *GetMenuBar() const ; - + // Set title void SetTitle(const wxString& title); wxString GetTitle() const ; - + void Centre(int direction = wxBOTH); - + // Call this to simulate a menu command virtual void Command(int id); virtual void ProcessCommand(int id); - + // Set icon virtual void SetIcon(const wxIcon& icon); - + // Toolbar virtual wxToolBar* CreateToolBar(long style = wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT, wxWindowID id = -1, @@ -110,7 +110,7 @@ public: virtual wxToolBar *GetToolBar() const { return m_frameToolBar; } virtual void PositionToolBar(); - + // Status bar virtual wxStatusBar* CreateStatusBar(int number = 1, long style = wxST_SIZEGRIP, @@ -125,48 +125,48 @@ public: long style, wxWindowID id, const wxString& name); - + // Set status line text virtual void SetStatusText(const wxString& text, int number = 0); - + // Set status line widths virtual void SetStatusWidths(int n, const int widths_field[]); - + // Hint to tell framework which status bar to use // TODO: should this go into a wxFrameworkSettings class perhaps? static void UseNativeStatusBar(bool useNative) { m_useNativeStatusBar = useNative; }; static bool UsesNativeStatusBar() { return m_useNativeStatusBar; }; - + // Fit frame around subwindows virtual void Fit(); - + // Iconize virtual void Iconize(bool iconize); - + virtual bool IsIconized() const ; - + // Is it maximized? virtual bool IsMaximized() const ; - + // Compatibility bool Iconized() const { return IsIconized(); } - + virtual void Maximize(bool maximize); // virtual bool LoadAccelerators(const wxString& table); - + // Responds to colour changes void OnSysColourChanged(wxSysColourChangedEvent& event); - + // Query app for menu item updates (called from OnIdle) void DoMenuUpdates(); void DoMenuUpdates(wxMenu* menu); - + WXHMENU GetWinMenu() const ; - + // Returns the origin of client area (may be different from (0,0) if the // frame has a toolbar) virtual wxPoint GetClientAreaOrigin() const; - + // Implementation only from here // event handlers bool MSWOnPaint(); @@ -181,16 +181,16 @@ public: wxWindow *wx_win, const char *title, int x, int y, int width, int height, long style); - // tooltip management + // tooltip management #if wxUSE_TOOLTIPS - WXHWND GetToolTipCtrl() const { return m_hwndToolTip; } - void SetToolTipCtrl(WXHWND hwndTT) { m_hwndToolTip = hwndTT; } + WXHWND GetToolTipCtrl() const { return m_hwndToolTip; } + void SetToolTipCtrl(WXHWND hwndTT) { m_hwndToolTip = hwndTT; } #endif // tooltips protected: // propagate our state change to all child frames void IconizeChildFrames(bool bIconize); - + wxMenuBar * m_frameMenuBar; wxStatusBar * m_frameStatusBar; wxIcon m_icon; diff --git a/include/wx/msw/tooltip.h b/include/wx/msw/tooltip.h index d2ece32c85..8b7f805f1a 100644 --- a/include/wx/msw/tooltip.h +++ b/include/wx/msw/tooltip.h @@ -25,15 +25,11 @@ public: void SetWindow(wxWindow *win); wxWindow *GetWindow() const { return m_window; } - // controlling tooltip behaviour: under MSW, these functions change the - // behaviour of the tooltips for all controls in the same frame as this - // one (it is an implementation limitation). Also, these functions won't - // do anything before the tooltip control is associated with a window, so - // SetWindow() should be called first + // controlling tooltip behaviour: globally change tooltip parameters // enable or disable the tooltips globally - void Enable(bool flag); + static void Enable(bool flag); // set the delay after which the tooltip appears - void SetDelay(long milliseconds); + static void SetDelay(long milliseconds); // implementation void RelayEvent(WXMSG *msg); diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 2efdb4dcd4..a9e9360221 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -271,6 +271,7 @@ public: void SetToolTip(wxToolTip *tooltip); // get the current tooltip (may return NULL if none) wxToolTip* GetToolTip() const { return m_tooltip; } + #endif // wxUSE_TOOLTIPS // Accept files for dragging @@ -767,7 +768,7 @@ private: // the associated tooltip (may be NULL if none) #if wxUSE_TOOLTIPS wxToolTip *m_tooltip; -#endif +#endif // tooltips DECLARE_EVENT_TABLE() }; diff --git a/samples/controls/controls.cpp b/samples/controls/controls.cpp index da243509af..5d08805027 100644 --- a/samples/controls/controls.cpp +++ b/samples/controls/controls.cpp @@ -81,7 +81,7 @@ class MyPanel: public wxPanel public: MyPanel(wxFrame *frame, int x, int y, int w, int h); virtual ~MyPanel(); - + void OnSize( wxSizeEvent& event ); void OnListBox( wxCommandEvent &event ); void OnListBoxDoubleClick( wxCommandEvent &event ); @@ -100,7 +100,7 @@ public: void OnCopyToClipboard( wxCommandEvent &event ); void OnMoveToEndOfText( wxCommandEvent &event ); void OnMoveToEndOfEntry( wxCommandEvent &event ); - + wxListBox *m_listbox; wxChoice *m_choice; wxComboBox *m_combo; @@ -113,7 +113,7 @@ public: MyTextCtrl *m_multitext; MyTextCtrl *m_textentry; wxCheckBox *m_checkbox; - + wxTextCtrl *m_text; wxNotebook *m_notebook; @@ -128,6 +128,10 @@ public: void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); +#if wxUSE_TOOLTIPS + void OnSetTooltipDelay(wxCommandEvent& event); + void OnToggleTooltips(wxCommandEvent& event); +#endif // wxUSE_TOOLTIPS void OnIdle( wxIdleEvent& event ); void OnSize( wxSizeEvent& event ); @@ -145,9 +149,16 @@ IMPLEMENT_APP(MyApp) // MyApp //---------------------------------------------------------------------- -const int MINIMAL_QUIT = 100; -const int MINIMAL_TEXT = 101; -const int MINIMAL_ABOUT = 102; +enum +{ + MINIMAL_QUIT = 100, + MINIMAL_TEXT, + MINIMAL_ABOUT, + + // tooltip menu + MINIMAL_SET_TOOLTIP_DELAY = 200, + MINIMAL_ENABLE_TOOLTIPS +}; bool MyApp::OnInit() { @@ -163,11 +174,22 @@ bool MyApp::OnInit() frame->SetIcon( wxICON(mondrian) ); wxMenu *file_menu = new wxMenu; - file_menu->Append(MINIMAL_ABOUT, "&About"); file_menu->Append(MINIMAL_QUIT, "E&xit"); + wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, "&File"); + +#if wxUSE_TOOLTIPS + wxMenu *tooltip_menu = new wxMenu; + tooltip_menu->Append(MINIMAL_SET_TOOLTIP_DELAY, "Set &delay"); + tooltip_menu->AppendSeparator(); + tooltip_menu->Append(MINIMAL_ENABLE_TOOLTIPS, "&Toggle tooltips", + "enable/disable tooltips", TRUE); + tooltip_menu->Check(MINIMAL_ENABLE_TOOLTIPS, TRUE); + menu_bar->Append(tooltip_menu, "&Tooltips"); +#endif // wxUSE_TOOLTIPS + frame->SetMenuBar(menu_bar); frame->Show(TRUE); @@ -401,7 +423,7 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) m_listbox = new wxListBox( panel, ID_LISTBOX, wxPoint(10,10), wxSize(120,70), 5, choices ); #if wxUSE_TOOLTIPS m_listbox->SetToolTip( "This is a list box" ); -#endif +#endif // wxUSE_TOOLTIPS (void)new wxButton( panel, ID_LISTBOX_SEL_NUM, "Select #2", wxPoint(180,30), wxSize(140,30) ); (void)new wxButton( panel, ID_LISTBOX_SEL_STR, "Select 'This'", wxPoint(340,30), wxSize(140,30) ); @@ -411,13 +433,13 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) button = new wxButton( panel, ID_LISTBOX_FONT, "Set Italic font", wxPoint(340,130), wxSize(140,30) ); #if wxUSE_TOOLTIPS button->SetToolTip( "Press here to set italic font" ); -#endif +#endif // wxUSE_TOOLTIPS m_checkbox = new wxCheckBox( panel, ID_LISTBOX_ENABLE, "Disable", wxPoint(20,130), wxSize(140,30) ); m_checkbox->SetValue(FALSE); #if wxUSE_TOOLTIPS m_checkbox->SetToolTip( "Click here to disable the listbox" ); -#endif +#endif // wxUSE_TOOLTIPS m_notebook->AddPage(panel, "wxListBox", TRUE, Image_List); panel = new wxPanel(m_notebook); @@ -456,9 +478,13 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h ) m_multitext->SetInsertionPoint(0); m_multitext->WriteText( "Prepended. " ); m_multitext->AppendText( "\nPress function keys to test different \nwxTextCtrl functions." ); - + new MyTextCtrl( panel, -1, "This one is with wxTE_PROCESS_TAB style.", wxPoint(10,120), wxSize(320,70), wxTE_MULTILINE | wxTE_PROCESS_TAB); +#if wxUSE_TOOLTIPS + m_multitext->AppendText( "\nThis ctrl has a tooltip. " ); + m_multitext->SetToolTip("Press F1 here."); +#endif // wxUSE_TOOLTIPS (void)new wxStaticBox( panel, -1, "&Move cursor to the end of:", wxPoint(345, 0), wxSize(160, 100) ); (void)new wxButton( panel, ID_MOVE_END_ENTRY, "Text &entry", wxPoint(370, 20), wxSize(110, 30) ); @@ -541,7 +567,7 @@ void MyPanel::OnPasteFromClipboard( wxCommandEvent &WXUNUSED(event) ) if (wxTheClipboard->IsSupported( data.GetFormat() )) { *m_text << "Clipboard supports requested format.\n"; - + if (wxTheClipboard->GetData( &data )) { *m_text << "Successfully retrieved data from the clipboard.\n"; @@ -661,7 +687,7 @@ void MyPanel::OnListBoxButtons( wxCommandEvent &event ) cb->SetToolTip( "Click to enable listbox" ); else cb->SetToolTip( "Click to disable listbox" ); -#endif +#endif // wxUSE_TOOLTIPS m_listbox->Enable( event.GetInt() == 0 ); break; } @@ -864,6 +890,10 @@ MyPanel::~MyPanel() BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(MINIMAL_QUIT, MyFrame::OnQuit) EVT_MENU(MINIMAL_ABOUT, MyFrame::OnAbout) +#if wxUSE_TOOLTIPS + EVT_MENU(MINIMAL_SET_TOOLTIP_DELAY, MyFrame::OnSetTooltipDelay) + EVT_MENU(MINIMAL_ENABLE_TOOLTIPS, MyFrame::OnToggleTooltips) +#endif // wxUSE_TOOLTIPS EVT_SIZE(MyFrame::OnSize) EVT_IDLE(MyFrame::OnIdle) END_EVENT_TABLE() @@ -887,6 +917,40 @@ void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) ) dialog.ShowModal(); } +#if wxUSE_TOOLTIPS +void MyFrame::OnSetTooltipDelay(wxCommandEvent& event) +{ + static long s_delay = 5000; + + wxString delay; + delay.Printf("%ld", s_delay); + + delay = wxGetTextFromUser("Enter delay (in milliseconds)", + "Set tooltip delay", + delay, + this); + if ( !delay ) + return; // cancelled + + sscanf(delay, "%ld", &s_delay); + + wxToolTip::SetDelay(s_delay); + + wxLogStatus(this, "Tooltip delay set to %ld milliseconds", s_delay); +} + +void MyFrame::OnToggleTooltips(wxCommandEvent& event) +{ + static bool s_enabled = TRUE; + + s_enabled = !s_enabled; + + wxToolTip::Enable(s_enabled); + + wxLogStatus(this, "Tooltips %sabled", s_enabled ? "en" : "dis"); +} +#endif // tooltips + void MyFrame::OnSize( wxSizeEvent& event ) { wxString msg; diff --git a/src/msw/tooltip.cpp b/src/msw/tooltip.cpp index 281f8e45cb..7829ec50e9 100644 --- a/src/msw/tooltip.cpp +++ b/src/msw/tooltip.cpp @@ -69,28 +69,110 @@ inline LRESULT SendTooltipMessage(WXHWND hwnd, : 0; } +// send a message to all existing tooltip controls +static void SendTooltipMessageToAll(UINT msg, WPARAM wParam, LPARAM lParam) +{ + // NB: it might be somewhat easier to maintain a list of all existing + // wxToolTip controls (put them there in ctor, delete from the list + // in dtor) - may be it's worth doing it this way? OTOH, typical + // application won't have many top level windows, so iterating over all + // of them shouldnt' take much time neither... + + // iterate over all top level windows and send message to the tooltip + // control of each and every of them (or more precisely to all dialogs and + // frames) + wxDialog *dialog = NULL; + wxFrame *frame = NULL; + + wxNode *node = wxTopLevelWindows.First(); + while ( node ) + { + wxWindow *win = (wxWindow *)node->Data(); + + node = node->Next(); + + if ( win->IsKindOf(CLASSINFO(wxFrame)) ) + { + frame = (wxFrame *)win; + dialog = NULL; + } + else if ( win->IsKindOf(CLASSINFO(wxDialog)) ) + { + dialog = (wxDialog *)win; + frame = NULL; + } + else + { + // skip this strange top level window + continue; + } + + wxASSERT_MSG( dialog || frame, "logic error" ); + + WXHWND hwndTT = frame ? frame->GetToolTipCtrl() + : dialog->GetToolTipCtrl(); + if ( hwndTT ) + { + (void)SendTooltipMessage(hwndTT, msg, wParam, (void *)lParam); + } + } +} + // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- -// "semiglobal" functions - these methods work with the tooltip control which -// is shared among all the wxToolTips of the same frame +// static functions // ---------------------------------------------------------------------------- +void wxToolTip::Enable(bool flag) +{ + SendTooltipMessageToAll(TTM_ACTIVATE, flag, 0); +} + +void wxToolTip::SetDelay(long milliseconds) +{ + SendTooltipMessageToAll(TTM_SETDELAYTIME, TTDT_INITIAL, milliseconds); +} + +// --------------------------------------------------------------------------- +// implementation helpers +// --------------------------------------------------------------------------- + // create the tooltip ctrl for our parent frame if it doesn't exist yet WXHWND wxToolTip::GetToolTipCtrl() { + // find either parent dialog or parent frame - tooltip controls are managed + // by these 2 classes only (it doesn't make sense to create one tooltip per + // each and every wxWindow) + wxFrame *frame = NULL; + wxDialog *dialog = NULL; + wxWindow *parent = m_window; - while ( parent && !parent->IsKindOf(CLASSINFO(wxFrame)) ) + while ( parent ) { + if ( parent->IsKindOf(CLASSINFO(wxFrame)) ) + { + frame = (wxFrame *)parent; + + break; + } + else if ( parent->IsKindOf(CLASSINFO(wxDialog)) ) + { + dialog = (wxDialog *)parent; + + break; + } + parent = parent->GetParent(); } - wxCHECK_MSG( parent, 0, "can't create tooltip control outside a frame" ); + wxCHECK_MSG( frame || dialog, 0, + "can't create tooltip control outside a frame or a dialog" ); - wxFrame *frame = (wxFrame *)parent; - HWND hwndTT = (HWND)frame->GetToolTipCtrl(); + HWND hwndTT = (HWND)(frame ? frame->GetToolTipCtrl() + : dialog->GetToolTipCtrl()); if ( !hwndTT ) { hwndTT = ::CreateWindow(TOOLTIPS_CLASS, @@ -103,7 +185,10 @@ WXHWND wxToolTip::GetToolTipCtrl() if ( hwndTT ) { - frame->SetToolTipCtrl((WXHWND)hwndTT); + if ( frame ) + frame->SetToolTipCtrl((WXHWND)hwndTT); + else + dialog->SetToolTipCtrl((WXHWND)hwndTT); } else { @@ -114,22 +199,11 @@ WXHWND wxToolTip::GetToolTipCtrl() return (WXHWND)hwndTT; } -void wxToolTip::Enable(bool flag) -{ - (void)SendTooltipMessage(GetToolTipCtrl(), TTM_ACTIVATE, flag, 0); -} - void wxToolTip::RelayEvent(WXMSG *msg) { (void)SendTooltipMessage(GetToolTipCtrl(), TTM_RELAYEVENT, 0, msg); } -void wxToolTip::SetDelay(long milliseconds) -{ - (void)SendTooltipMessage(GetToolTipCtrl(), TTM_SETDELAYTIME, - TTDT_INITIAL, (void *)milliseconds); -} - // ---------------------------------------------------------------------------- // ctor & dtor // ----------------------------------------------------------------------------