Notify Windows shell about file associations changes
This is documented as being required in the MSDN and, in practice, is necessary for Windows to update the icon cache and show the new icon. Closes https://github.com/wxWidgets/wxWidgets/pull/195
This commit is contained in:
committed by
Vadim Zeitlin
parent
948126a375
commit
90386df305
@@ -198,6 +198,7 @@ wxMSW:
|
|||||||
- Don't send wxActivateEvent for minimized windows (bzcdr).
|
- Don't send wxActivateEvent for minimized windows (bzcdr).
|
||||||
- Return correct OS version under Windows 8.1 and later.
|
- Return correct OS version under Windows 8.1 and later.
|
||||||
- Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif).
|
- Fix crash in wxD2DContext when using non-MSVC compiler (iwbnwif).
|
||||||
|
- Notify shell about the changes done by wxMimeTypesManager (Maarten Bent).
|
||||||
|
|
||||||
wxOSX/Cocoa:
|
wxOSX/Cocoa:
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// Modified by:
|
// Modified by:
|
||||||
// Created: 23.09.98
|
// Created: 23.09.98
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
// Licence: wxWindows licence (part of wxExtra library)
|
// Licence: wxWidgets licence (part of base library)
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef _MIMETYPE_IMPL_H
|
#ifndef _MIMETYPE_IMPL_H
|
||||||
@@ -62,6 +62,20 @@ public:
|
|||||||
// this is called by Associate
|
// this is called by Associate
|
||||||
bool SetDescription (const wxString& desc);
|
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:
|
private:
|
||||||
// helper function: reads the command corresponding to the specified verb
|
// helper function: reads the command corresponding to the specified verb
|
||||||
// from the registry (returns an empty string if not found)
|
// from the registry (returns an empty string if not found)
|
||||||
@@ -76,6 +90,7 @@ private:
|
|||||||
|
|
||||||
wxString m_strFileType, // may be empty
|
wxString m_strFileType, // may be empty
|
||||||
m_ext;
|
m_ext;
|
||||||
|
bool m_suppressNotify;
|
||||||
|
|
||||||
// these methods are not publicly accessible (as wxMimeTypesManager
|
// these methods are not publicly accessible (as wxMimeTypesManager
|
||||||
// doesn't know about them), and should only be called by Unassociate
|
// doesn't know about them), and should only be called by Unassociate
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// Modified by:
|
// Modified by:
|
||||||
// Created: 23.09.98
|
// Created: 23.09.98
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
// Licence: wxWindows licence (part of wxExtra library)
|
// Licence: wxWidgets licence (part of base library)
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// for compilers that support precompilation, includes "wx.h".
|
// for compilers that support precompilation, includes "wx.h".
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "wx/msw/registry.h"
|
#include "wx/msw/registry.h"
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
|
||||||
// For MSVC we can link in the required library explicitly, for the other
|
// 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.
|
// 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 ) {
|
if ( !strFileType ) {
|
||||||
m_strFileType = m_ext.AfterFirst('.') + wxT("_auto_file");
|
m_strFileType = m_ext.AfterFirst('.') + wxT("_auto_file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_suppressNotify = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const
|
wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const
|
||||||
@@ -210,6 +213,17 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,
|
|||||||
return count;
|
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
|
// modify the registry database
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -676,12 +690,15 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo)
|
|||||||
|
|
||||||
if (ft)
|
if (ft)
|
||||||
{
|
{
|
||||||
|
ft->m_impl->MSWSuppressNotifications(true);
|
||||||
if (! ftInfo.GetOpenCommand ().empty() ) ft->SetCommand (ftInfo.GetOpenCommand (), wxT("open" ) );
|
if (! ftInfo.GetOpenCommand ().empty() ) ft->SetCommand (ftInfo.GetOpenCommand (), wxT("open" ) );
|
||||||
if (! ftInfo.GetPrintCommand().empty() ) ft->SetCommand (ftInfo.GetPrintCommand(), wxT("print" ) );
|
if (! ftInfo.GetPrintCommand().empty() ) ft->SetCommand (ftInfo.GetPrintCommand(), wxT("print" ) );
|
||||||
// chris: I don't like the ->m_impl-> here FIX this ??
|
// chris: I don't like the ->m_impl-> here FIX this ??
|
||||||
if (! ftInfo.GetDescription ().empty() ) ft->m_impl->SetDescription (ftInfo.GetDescription ()) ;
|
if (! ftInfo.GetDescription ().empty() ) ft->m_impl->SetDescription (ftInfo.GetDescription ()) ;
|
||||||
if (! ftInfo.GetIconFile().empty() ) ft->SetDefaultIcon (ftInfo.GetIconFile(), ftInfo.GetIconIndex() );
|
if (! ftInfo.GetIconFile().empty() ) ft->SetDefaultIcon (ftInfo.GetIconFile(), ftInfo.GetIconIndex() );
|
||||||
|
|
||||||
|
ft->m_impl->MSWSuppressNotifications(false);
|
||||||
|
ft->m_impl->MSWNotifyShell();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ft;
|
return ft;
|
||||||
@@ -702,7 +719,12 @@ bool wxFileTypeImpl::SetCommand(const wxString& cmd,
|
|||||||
// TODO:
|
// TODO:
|
||||||
// 1. translate '%s' to '%1' instead of always adding it
|
// 1. translate '%s' to '%1' instead of always adding it
|
||||||
// 2. create DDEExec value if needed (undo GetCommand)
|
// 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)
|
bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index)
|
||||||
@@ -718,9 +740,14 @@ bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index)
|
|||||||
wxRegKey rkey(wxRegKey::HKCU,
|
wxRegKey rkey(wxRegKey::HKCU,
|
||||||
CLASSES_ROOT_KEY + m_strFileType + wxT("\\DefaultIcon"));
|
CLASSES_ROOT_KEY + m_strFileType + wxT("\\DefaultIcon"));
|
||||||
|
|
||||||
return rkey.Create() &&
|
bool result = rkey.Create() &&
|
||||||
rkey.SetValue(wxEmptyString,
|
rkey.SetValue(wxEmptyString,
|
||||||
wxString::Format(wxT("%s,%d"), cmd.c_str(), index));
|
wxString::Format(wxT("%s,%d"), cmd.c_str(), index));
|
||||||
|
|
||||||
|
if ( result )
|
||||||
|
MSWNotifyShell();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFileTypeImpl::SetDescription (const wxString& desc)
|
bool wxFileTypeImpl::SetDescription (const wxString& desc)
|
||||||
@@ -743,6 +770,7 @@ bool wxFileTypeImpl::SetDescription (const wxString& desc)
|
|||||||
|
|
||||||
bool wxFileTypeImpl::Unassociate()
|
bool wxFileTypeImpl::Unassociate()
|
||||||
{
|
{
|
||||||
|
MSWSuppressNotifications(true);
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if ( !RemoveOpenCommand() )
|
if ( !RemoveOpenCommand() )
|
||||||
result = false;
|
result = false;
|
||||||
@@ -753,6 +781,9 @@ bool wxFileTypeImpl::Unassociate()
|
|||||||
if ( !RemoveDescription() )
|
if ( !RemoveDescription() )
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
|
MSWSuppressNotifications(false);
|
||||||
|
MSWNotifyShell();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,7 +800,12 @@ bool wxFileTypeImpl::RemoveCommand(const wxString& verb)
|
|||||||
wxRegKey rkey(wxRegKey::HKCU, CLASSES_ROOT_KEY + GetVerbPath(verb));
|
wxRegKey rkey(wxRegKey::HKCU, CLASSES_ROOT_KEY + GetVerbPath(verb));
|
||||||
|
|
||||||
// if the key already doesn't exist, it's a success
|
// 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()
|
bool wxFileTypeImpl::RemoveMimeType()
|
||||||
@@ -787,7 +823,12 @@ bool wxFileTypeImpl::RemoveDefaultIcon()
|
|||||||
|
|
||||||
wxRegKey rkey (wxRegKey::HKCU,
|
wxRegKey rkey (wxRegKey::HKCU,
|
||||||
CLASSES_ROOT_KEY + m_strFileType + wxT("\\DefaultIcon"));
|
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()
|
bool wxFileTypeImpl::RemoveDescription()
|
||||||
|
Reference in New Issue
Block a user