From bfbd6dc1921a17bd880d580dd660e8bc478a9391 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 25 Feb 2000 23:49:41 +0000 Subject: [PATCH] 1. cursor fixes: frame does have hand cursor in the controls sample now, modal dialogs don't have busy cursor even if wxIsBusy() 2. wxTextCtrl sets client data field in the generated events 3. added wxEnhMetaFile::SetClipboard() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6296 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/control.h | 3 ++ include/wx/msw/enhmeta.h | 7 +++- include/wx/msw/private.h | 7 ++++ src/common/ctrlcmn.cpp | 25 ++++++++++++- src/msw/app.cpp | 10 ------ src/msw/cursor.cpp | 50 ++++++++++++++++++++++---- src/msw/data.cpp | 7 ---- src/msw/dialog.cpp | 19 ++++++++-- src/msw/enhmeta.cpp | 8 +++++ src/msw/textctrl.cpp | 20 +++++------ src/msw/utils.cpp | 9 +++-- src/msw/window.cpp | 76 ++++++++++++++++++---------------------- 12 files changed, 159 insertions(+), 82 deletions(-) diff --git a/include/wx/control.h b/include/wx/control.h index 79adf0144f..7b1d491309 100644 --- a/include/wx/control.h +++ b/include/wx/control.h @@ -46,6 +46,9 @@ protected: // inherit colour and font settings from the parent window void InheritAttributes(); + + // initialize the common fields of wxCommandEvent + void InitCommandEvent(wxCommandEvent& event) const; }; // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/enhmeta.h b/include/wx/msw/enhmeta.h index a7f235453d..88f7cfa8a9 100644 --- a/include/wx/msw/enhmeta.h +++ b/include/wx/msw/enhmeta.h @@ -51,6 +51,11 @@ public: const wxString& GetFileName() const { return m_filename; } + // copy the metafile to the clipboard: the width and height parameters are + // for backwards compatibility (with wxMetaFile) only, they are ignored by + // this method + bool SetClipboard(int width = 0, int height = 0); + // implementation WXHANDLE GetHENHMETAFILE() const { return m_hMF; } void SetHENHMETAFILE(WXHANDLE hMF) { Free(); m_hMF = hMF; } @@ -96,7 +101,7 @@ private: #if wxUSE_DRAG_AND_DROP // notice that we want to support both CF_METAFILEPICT and CF_ENHMETAFILE and -// so we derive from and not from wxDataObjectSimple +// so we derive from wxDataObject and not from wxDataObjectSimple class WXDLLEXPORT wxEnhMetaFileDataObject : public wxDataObject { public: diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index c23c715266..6ed5fcb913 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -300,6 +300,9 @@ private: #define GetHmenu() ((HMENU)GetHMenu()) #define GetHmenuOf(menu) ((HMENU)menu->GetHMenu()) +#define GetHcursor() ((HCURSOR)GetHCURSOR()) +#define GetHcursorOf(cursor) ((HCURSOR)(cursor).GetHCURSOR()) + // --------------------------------------------------------------------------- // global data // --------------------------------------------------------------------------- @@ -326,6 +329,10 @@ WXDLLEXPORT void wxSetInstance(HINSTANCE hInst); #if wxUSE_GUI +// cursor stuff +extern HCURSOR wxGetCurrentBusyCursor(); // from msw/utils.cpp +extern const wxCursor *wxGetGlobalCursor(); // from msw/cursor.cpp + WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd); WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font); diff --git a/src/common/ctrlcmn.cpp b/src/common/ctrlcmn.cpp index 8e99dd0b17..479e92c1f5 100644 --- a/src/common/ctrlcmn.cpp +++ b/src/common/ctrlcmn.cpp @@ -68,5 +68,28 @@ void wxControlBase::InheritAttributes() void wxControlBase::Command(wxCommandEvent& event) { - (void)ProcessEvent(event); + (void)GetEventHandler()->ProcessEvent(event); } + +void wxControlBase::InitCommandEvent(wxCommandEvent& event) const +{ + event.SetEventObject((wxControlBase *)this); // const_cast + + // event.SetId(GetId()); -- this is usuall done in the event ctor + + switch ( m_clientDataType ) + { + case ClientData_Void: + event.SetClientData(GetClientData()); + break; + + case ClientData_Object: + event.SetClientObject(GetClientObject()); + break; + + case ClientData_None: + // nothing to do + ; + } +} + diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 94c9239a6d..903493b2f1 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -126,7 +126,6 @@ extern wxChar *wxOsVersion; extern wxList *wxWinHandleList; extern wxList WXDLLEXPORT wxPendingDelete; extern void wxSetKeyboardHook(bool doIt); -extern wxCursor *g_globalCursor; MSG s_currentMsg; wxApp *wxTheApp = NULL; @@ -228,8 +227,6 @@ bool wxApp::Initialize() Ctl3dAutoSubclass(wxhInstance); #endif - g_globalCursor = new wxCursor; - // VZ: these icons are not in wx.rc anyhow (but should they?)! #if 0 wxSTD_FRAME_ICON = LoadIcon(wxhInstance, wxT("wxSTD_FRAME")); @@ -497,13 +494,6 @@ void wxApp::CleanUp() // wxDefaultResourceTable->ClearTable(); #endif - // Indicate that the cursor can be freed, so that cursor won't be deleted - // by deleting the bitmap list before g_globalCursor goes out of scope - // (double deletion of the cursor). - wxSetCursor(wxNullCursor); - delete g_globalCursor; - g_globalCursor = NULL; - wxDeleteStockObjects(); // Destroy all GDI lists, etc. diff --git a/src/msw/cursor.cpp b/src/msw/cursor.cpp index e914dff561..1f76183f6e 100644 --- a/src/msw/cursor.cpp +++ b/src/msw/cursor.cpp @@ -49,7 +49,40 @@ // wxWin macros // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxCursorBase) +IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxCursorBase) + +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- + +// Current cursor, in order to hang on to cursor handle when setting the cursor +// globally +static wxCursor *gs_globalCursor = NULL; + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxCursorModule : public wxModule +{ +public: + virtual bool OnInit() + { + gs_globalCursor = new wxCursor; + + return TRUE; + } + + virtual void OnExit() + { + delete gs_globalCursor; + gs_globalCursor = (wxCursor *)NULL; + } +}; + +// ============================================================================ +// implementation +// ============================================================================ // ---------------------------------------------------------------------------- // wxCursorRefData @@ -278,16 +311,19 @@ wxCursor::~wxCursor() // Global cursor setting // ---------------------------------------------------------------------------- -void wxSetCursor(const wxCursor& cursor) +const wxCursor *wxGetGlobalCursor() { - extern wxCursor *g_globalCursor; + return gs_globalCursor; +} - if ( cursor.Ok() && cursor.GetHCURSOR() ) +void wxSetCursor(const wxCursor& cursor) +{ + if ( cursor.Ok() ) { - ::SetCursor((HCURSOR) cursor.GetHCURSOR()); + ::SetCursor(GetHcursorOf(cursor)); - if ( g_globalCursor ) - (*g_globalCursor) = cursor; + if ( gs_globalCursor ) + *gs_globalCursor = cursor; } } diff --git a/src/msw/data.cpp b/src/msw/data.cpp index 103f694ce0..1b24fc3e3a 100644 --- a/src/msw/data.cpp +++ b/src/msw/data.cpp @@ -37,13 +37,6 @@ wxWindowList wxTopLevelWindows; // List of windows pending deletion wxList WXDLLEXPORT wxPendingDelete; -// Current cursor, in order to hang on to -// cursor handle when setting the cursor globally -wxCursor *g_globalCursor = NULL; - -// Message Strings for Internationalization -char **wx_msg_str = (char**)NULL; - // Custom OS version, as optionally placed in wx.ini/.wxrc // Currently this can be Win95, Windows, Win32s, WinNT. // For some systems, you can't tell until run-time what services you diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 658003fe30..3463629b49 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -530,13 +530,28 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case WM_SETCURSOR: // we want to override the busy cursor for modal dialogs: // typically, wxBeginBusyCursor() is called and then a modal dialog - // is shown, but the modal dialog shouldn't have this cursor + // is shown, but the modal dialog shouldn't have hourglass cursor if ( wxIsBusy() ) { - rc = TRUE; + // set our cursor for all windows (but see below) + wxCursor cursor = m_cursor; + if ( !cursor.Ok() ) + cursor = wxCURSOR_ARROW; + ::SetCursor(GetHcursorOf(cursor)); + + // in any case, stop here and don't let wxWindow process this + // message (it would set the busy cursor) processed = TRUE; + + // but return FALSE to tell the child window (if the event + // comes from one of them and not from ourselves) that it can + // set its own cursor if it has one: thus, standard controls + // (e.g. text ctrl) still have correct cursors in a dialog + // invoked while wxIsBusy() + rc = FALSE; } + break; } if ( !processed ) diff --git a/src/msw/enhmeta.cpp b/src/msw/enhmeta.cpp index 189d2980b8..0fd8b2d9af 100644 --- a/src/msw/enhmeta.cpp +++ b/src/msw/enhmeta.cpp @@ -36,6 +36,7 @@ #endif //WX_PRECOMP #include "wx/metafile.h" +#include "wx/clipbrd.h" #include "wx/msw/private.h" @@ -161,6 +162,13 @@ wxSize wxEnhMetaFile::GetSize() const return size; } +bool wxEnhMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) +{ + wxCHECK_MSG( m_hMF, FALSE, _T("can't copy invalid metafile to clipboard") ); + + return wxTheClipboard->AddData(new wxEnhMetaFileDataObject(*this)); +} + // ---------------------------------------------------------------------------- // wxEnhMetaFileDC // ---------------------------------------------------------------------------- diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index c4969c9394..91ad453853 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: textctrl.cpp +// Name: msw/textctrl.cpp // Purpose: wxTextCtrl // Author: Julian Smart // Modified by: @@ -887,7 +887,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) if ( !(m_windowStyle & wxTE_MULTILINE) ) { wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId); - event.SetEventObject( this ); + InitCommandEvent(event); if ( GetEventHandler()->ProcessEvent(event) ) return; } @@ -934,9 +934,9 @@ bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) case EN_CHANGE: { wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); - event.SetEventObject( this ); - event.SetString( GetValue() ); - ProcessCommand( event ); + InitCommandEvent(event); + event.SetString(GetValue()); + ProcessCommand(event); } break; @@ -1016,27 +1016,27 @@ wxSize wxTextCtrl::DoGetBestSize() const // standard handlers for standard edit menu events // ---------------------------------------------------------------------------- -void wxTextCtrl::OnCut(wxCommandEvent& event) +void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event)) { Cut(); } -void wxTextCtrl::OnCopy(wxCommandEvent& event) +void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event)) { Copy(); } -void wxTextCtrl::OnPaste(wxCommandEvent& event) +void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event)) { Paste(); } -void wxTextCtrl::OnUndo(wxCommandEvent& event) +void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event)) { Undo(); } -void wxTextCtrl::OnRedo(wxCommandEvent& event) +void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event)) { Redo(); } diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 2f56096849..7126032d69 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -806,10 +806,15 @@ bool wxGetResource(const wxString& section, const wxString& entry, int *value, c // helper functions for showing a "busy" cursor // --------------------------------------------------------------------------- -HCURSOR gs_wxBusyCursor = 0; // new, busy cursor -HCURSOR gs_wxBusyCursorOld = 0; // old cursor +static HCURSOR gs_wxBusyCursor = 0; // new, busy cursor +static HCURSOR gs_wxBusyCursorOld = 0; // old cursor static int gs_wxBusyCursorCount = 0; +extern HCURSOR wxGetCurrentBusyCursor() +{ + return gs_wxBusyCursor; +} + // Set the cursor to the busy cursor for all windows void wxBeginBusyCursor(wxCursor *cursor) { diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 163a72e055..48cf53abc9 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -480,7 +480,7 @@ bool wxWindow::SetCursor(const wxCursor& cursor) ::GetWindowRect(hWnd, &rect); if ( ::PtInRect(&rect, point) && !wxIsBusy() ) - ::SetCursor((HCURSOR)m_cursor.GetHCURSOR()); + ::SetCursor(GetHcursorOf(m_cursor)); return TRUE; } @@ -2664,54 +2664,46 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd, short nHitTest, int WXUNUSED(mouseMsg)) { - // don't set cursor for other windows, only for this one: this prevents - // children of this window from getting the same cursor as the parent has - // (don't forget that this message is propagated by default up the window - // parent-child hierarchy) - if ( GetHWND() == hWnd ) - { - // don't set cursor when the mouse is not in the client part - if ( nHitTest == HTCLIENT || nHitTest == HTERROR ) - { - HCURSOR hcursor = 0; - if ( wxIsBusy() ) - { - // from msw\utils.cpp - extern HCURSOR gs_wxBusyCursor; - - hcursor = gs_wxBusyCursor; - } - else - { - wxCursor *cursor = NULL; - - if ( m_cursor.Ok() ) - { - cursor = &m_cursor; - } - else - { - // from msw\data.cpp - extern wxCursor *g_globalCursor; + // the logic is as follows: + // 1. if we have the cursor set it unless wxIsBusy() + // 2. if we're a top level window, set some cursor anyhow + // 3. if wxIsBusy(), set the busy cursor, otherwise the global one - if ( g_globalCursor && g_globalCursor->Ok() ) - cursor = g_globalCursor; - } - - if ( cursor ) - hcursor = (HCURSOR)cursor->GetHCURSOR(); - } + HCURSOR hcursor = 0; + bool isBusy = wxIsBusy(); + if ( m_cursor.Ok() ) + { + hcursor = GetHcursorOf(m_cursor); + } - if ( hcursor ) + if ( !GetParent() ) + { + if ( isBusy ) + { + hcursor = wxGetCurrentBusyCursor(); + } + else if ( !hcursor ) + { + const wxCursor *cursor = wxGetGlobalCursor(); + if ( cursor && cursor->Ok() ) { - ::SetCursor(hcursor); - - return TRUE; + hcursor = GetHcursorOf(*cursor); } } } - return FALSE; + if ( hcursor ) + { + ::SetCursor(hcursor); + + // cursor set, stop here + return TRUE; + } + else + { + // pass up the window chain + return FALSE; + } } // --------------------------------------------------------------------------- -- 2.45.2