diff --git a/docs/changes.txt b/docs/changes.txt index 001e51a8b4..3e459193ac 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -198,6 +198,7 @@ wxMSW: - Don't send wxActivateEvent for minimized windows (bzcdr). - Return correct OS version under Windows 8.1 and later. - Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif). +- Notify shell about the changes done by wxMimeTypesManager (Maarten Bent). wxOSX/Cocoa: diff --git a/include/wx/msw/mimetype.h b/include/wx/msw/mimetype.h index 90a7013b6f..aa3880f2b2 100644 --- a/include/wx/msw/mimetype.h +++ b/include/wx/msw/mimetype.h @@ -5,7 +5,7 @@ // Modified by: // Created: 23.09.98 // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows licence (part of wxExtra library) +// Licence: wxWidgets licence (part of base library) ///////////////////////////////////////////////////////////////////////////// #ifndef _MIMETYPE_IMPL_H @@ -62,6 +62,20 @@ public: // this is called by Associate bool SetDescription (const wxString& desc); + // This is called by all our own methods modifying the registry to let the + // Windows Shell know about the changes. + // + // It is also called from Associate() and Unassociate() which suppress the + // internally generated notifications using the method below, which is why + // it has to be public. + void MSWNotifyShell(); + + // Call before/after performing several registry changes in a row to + // temporarily suppress multiple notifications that would be generated for + // them and generate a single one at the end using MSWNotifyShell() + // explicitly. + void MSWSuppressNotifications(bool supress); + private: // helper function: reads the command corresponding to the specified verb // from the registry (returns an empty string if not found) @@ -76,6 +90,7 @@ private: wxString m_strFileType, // may be empty m_ext; + bool m_suppressNotify; // these methods are not publicly accessible (as wxMimeTypesManager // doesn't know about them), and should only be called by Unassociate diff --git a/src/msw/mimetype.cpp b/src/msw/mimetype.cpp index 16dbb320a6..a94214c990 100644 --- a/src/msw/mimetype.cpp +++ b/src/msw/mimetype.cpp @@ -5,7 +5,7 @@ // Modified by: // Created: 23.09.98 // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows licence (part of wxExtra library) +// Licence: wxWidgets licence (part of base library) ///////////////////////////////////////////////////////////////////////////// // for compilers that support precompilation, includes "wx.h". @@ -40,6 +40,7 @@ #include "wx/msw/registry.h" #include "wx/msw/private.h" #include + #include // For MSVC we can link in the required library explicitly, for the other // compilers (e.g. MinGW) this needs to be done at makefiles level. @@ -146,6 +147,8 @@ void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext) if ( !strFileType ) { m_strFileType = m_ext.AfterFirst('.') + wxT("_auto_file"); } + + m_suppressNotify = false; } wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const @@ -210,6 +213,17 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs, return count; } +void wxFileTypeImpl::MSWNotifyShell() +{ + if (!m_suppressNotify) + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, NULL, NULL); +} + +void wxFileTypeImpl::MSWSuppressNotifications(bool supress) +{ + m_suppressNotify = supress; +} + // ---------------------------------------------------------------------------- // modify the registry database // ---------------------------------------------------------------------------- @@ -676,12 +690,15 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if (ft) { + ft->m_impl->MSWSuppressNotifications(true); if (! ftInfo.GetOpenCommand ().empty() ) ft->SetCommand (ftInfo.GetOpenCommand (), wxT("open" ) ); if (! ftInfo.GetPrintCommand().empty() ) ft->SetCommand (ftInfo.GetPrintCommand(), wxT("print" ) ); // chris: I don't like the ->m_impl-> here FIX this ?? if (! ftInfo.GetDescription ().empty() ) ft->m_impl->SetDescription (ftInfo.GetDescription ()) ; if (! ftInfo.GetIconFile().empty() ) ft->SetDefaultIcon (ftInfo.GetIconFile(), ftInfo.GetIconIndex() ); + ft->m_impl->MSWSuppressNotifications(false); + ft->m_impl->MSWNotifyShell(); } return ft; @@ -702,7 +719,12 @@ bool wxFileTypeImpl::SetCommand(const wxString& cmd, // TODO: // 1. translate '%s' to '%1' instead of always adding it // 2. create DDEExec value if needed (undo GetCommand) - return rkey.Create() && rkey.SetValue(wxEmptyString, cmd + wxT(" \"%1\"") ); + bool result = rkey.Create() && rkey.SetValue(wxEmptyString, cmd + wxT(" \"%1\"") ); + + if ( result ) + MSWNotifyShell(); + + return result; } bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index) @@ -718,9 +740,14 @@ bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index) wxRegKey rkey(wxRegKey::HKCU, CLASSES_ROOT_KEY + m_strFileType + wxT("\\DefaultIcon")); - return rkey.Create() && + bool result = rkey.Create() && rkey.SetValue(wxEmptyString, wxString::Format(wxT("%s,%d"), cmd.c_str(), index)); + + if ( result ) + MSWNotifyShell(); + + return result; } bool wxFileTypeImpl::SetDescription (const wxString& desc) @@ -743,6 +770,7 @@ bool wxFileTypeImpl::SetDescription (const wxString& desc) bool wxFileTypeImpl::Unassociate() { + MSWSuppressNotifications(true); bool result = true; if ( !RemoveOpenCommand() ) result = false; @@ -753,6 +781,9 @@ bool wxFileTypeImpl::Unassociate() if ( !RemoveDescription() ) result = false; + MSWSuppressNotifications(false); + MSWNotifyShell(); + return result; } @@ -769,7 +800,12 @@ bool wxFileTypeImpl::RemoveCommand(const wxString& verb) wxRegKey rkey(wxRegKey::HKCU, CLASSES_ROOT_KEY + GetVerbPath(verb)); // if the key already doesn't exist, it's a success - return !rkey.Exists() || rkey.DeleteSelf(); + bool result = !rkey.Exists() || rkey.DeleteSelf(); + + if ( result ) + MSWNotifyShell(); + + return result; } bool wxFileTypeImpl::RemoveMimeType() @@ -787,7 +823,12 @@ bool wxFileTypeImpl::RemoveDefaultIcon() wxRegKey rkey (wxRegKey::HKCU, CLASSES_ROOT_KEY + m_strFileType + wxT("\\DefaultIcon")); - return !rkey.Exists() || rkey.DeleteSelf(); + bool result = !rkey.Exists() || rkey.DeleteSelf(); + + if ( result ) + MSWNotifyShell(); + + return result; } bool wxFileTypeImpl::RemoveDescription()