]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/mimetype.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/mimetype.cpp 
   3 // Purpose:     classes and functions to manage MIME types 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
   9 // Licence:     wxWindows licence (part of wxExtra library) 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "mimetype.h" 
  16 // for compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  26     #include "wx/string.h" 
  29         #include "wx/msgdlg.h" 
  35 #include "wx/iconloc.h" 
  37 #include "wx/dynarray.h" 
  38 #include "wx/confbase.h" 
  41     #include "wx/msw/registry.h" 
  42     #include "wx/msw/private.h" 
  45 #include "wx/msw/mimetype.h" 
  47 // other standard headers 
  50 // in case we're compiling in non-GUI mode 
  51 class WXDLLEXPORT wxIcon
; 
  53 // These classes use Windows registry to retrieve the required information. 
  55 // Keys used (not all of them are documented, so it might actually stop working 
  56 // in future versions of Windows...): 
  57 //  1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME 
  58 //     types, each key has a string value "Extension" which gives (dot preceded) 
  59 //     extension for the files of this MIME type. 
  61 //  2. "HKCR\.ext" contains 
  62 //   a) unnamed value containing the "filetype" 
  63 //   b) value "Content Type" containing the MIME type 
  65 // 3. "HKCR\filetype" contains 
  66 //   a) unnamed value containing the description 
  67 //   b) subkey "DefaultIcon" with single unnamed value giving the icon index in 
  69 //   c) shell\open\command and shell\open\print subkeys containing the commands 
  70 //      to open/print the file (the positional parameters are introduced by %1, 
  71 //      %2, ... in these strings, we change them to %s ourselves) 
  73 // although I don't know of any official documentation which mentions this 
  74 // location, uses it, so it isn't likely to change 
  75 static const wxChar 
*MIME_DATABASE_KEY 
= wxT("MIME\\Database\\Content Type\\"); 
  77 // this function replaces Microsoft %1 with Unix-like %s 
  78 static bool CanonicalizeParams(wxString
& command
) 
  80     // transform it from '%1' to '%s' style format string (now also test for %L 
  81     // as apparently MS started using it as well for the same purpose) 
  83     // NB: we don't make any attempt to verify that the string is valid, i.e. 
  84     //     doesn't contain %2, or second %1 or .... But we do make sure that we 
  85     //     return a string with _exactly_ one '%s'! 
  86     bool foundFilename 
= false; 
  87     size_t len 
= command
.length(); 
  88     for ( size_t n 
= 0; (n 
< len
) && !foundFilename
; n
++ ) 
  90         if ( command
[n
] == wxT('%') && 
  92                 (command
[n 
+ 1] == wxT('1') || command
[n 
+ 1] == wxT('L')) ) 
  94             // replace it with '%s' 
  95             command
[n 
+ 1] = wxT('s'); 
 101     return foundFilename
; 
 104 void wxFileTypeImpl::Init(const wxString
& strFileType
, const wxString
& ext
) 
 106     // VZ: does it? (FIXME) 
 107     wxCHECK_RET( !ext
.IsEmpty(), _T("needs an extension") ); 
 109     if ( ext
[0u] != wxT('.') ) { 
 114     m_strFileType 
= strFileType
; 
 115     if ( !strFileType 
) { 
 116         m_strFileType 
= m_ext
.AfterFirst('.') + _T("_auto_file"); 
 120 wxString 
wxFileTypeImpl::GetVerbPath(const wxString
& verb
) const 
 123     path 
<< m_strFileType 
<< _T("\\shell\\") << verb 
<< _T("\\command"); 
 127 size_t wxFileTypeImpl::GetAllCommands(wxArrayString 
*verbs
, 
 128                                       wxArrayString 
*commands
, 
 129                                       const wxFileType::MessageParameters
& params
) const 
 131     wxCHECK_MSG( !m_ext
.IsEmpty(), 0, _T("GetAllCommands() needs an extension") ); 
 133     if ( m_strFileType
.IsEmpty() ) 
 135         // get it from the registry 
 136         wxFileTypeImpl 
*self 
= wxConstCast(this, wxFileTypeImpl
); 
 137         wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 138         if ( !rkey
.Exists() || !rkey
.QueryValue(wxEmptyString
, self
->m_strFileType
) ) 
 140             wxLogDebug(_T("Can't get the filetype for extension '%s'."), 
 147     // enum all subkeys of HKCR\filetype\shell 
 149     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType  
+ _T("\\shell")); 
 152     bool ok 
= rkey
.GetFirstKey(verb
, dummy
); 
 155         wxString command 
= wxFileType::ExpandCommand(GetCommand(verb
), params
); 
 157         // we want the open bverb to eb always the first 
 159         if ( verb
.CmpNoCase(_T("open")) == 0 ) 
 162                 verbs
->Insert(verb
, 0); 
 164                 commands
->Insert(command
, 0); 
 166         else // anything else than "open" 
 171                 commands
->Add(command
); 
 176         ok 
= rkey
.GetNextKey(verb
, dummy
); 
 182 // ---------------------------------------------------------------------------- 
 183 // modify the registry database 
 184 // ---------------------------------------------------------------------------- 
 186 bool wxFileTypeImpl::EnsureExtKeyExists() 
 188     wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 189     if ( !rkey
.Exists() ) 
 191         if ( !rkey
.Create() || !rkey
.SetValue(wxEmptyString
, m_strFileType
) ) 
 193             wxLogError(_("Failed to create registry entry for '%s' files."), 
 202 // ---------------------------------------------------------------------------- 
 203 // get the command to use 
 204 // ---------------------------------------------------------------------------- 
 206 wxString 
wxFileTypeImpl::GetCommand(const wxChar 
*verb
) const 
 208     // suppress possible error messages 
 212     if ( wxRegKey(wxRegKey::HKCR
, m_ext 
+ _T("\\shell")).Exists() ) 
 214     if ( wxRegKey(wxRegKey::HKCR
, m_strFileType 
+ _T("\\shell")).Exists() ) 
 215         strKey 
= m_strFileType
; 
 220         return wxEmptyString
; 
 223     strKey 
<< wxT("\\shell\\") << verb
; 
 224     wxRegKey 
key(wxRegKey::HKCR
, strKey 
+ _T("\\command")); 
 227         // it's the default value of the key 
 228         if ( key
.QueryValue(wxEmptyString
, command
) ) { 
 229             bool foundFilename 
= CanonicalizeParams(command
); 
 232             // look whether we must issue some DDE requests to the application 
 233             // (and not just launch it) 
 234             strKey 
+= _T("\\DDEExec"); 
 235             wxRegKey 
keyDDE(wxRegKey::HKCR
, strKey
); 
 236             if ( keyDDE
.Open() ) { 
 237                 wxString ddeCommand
, ddeServer
, ddeTopic
; 
 238                 keyDDE
.QueryValue(wxEmptyString
, ddeCommand
); 
 239                 ddeCommand
.Replace(_T("%1"), _T("%s")); 
 241                 wxRegKey(wxRegKey::HKCR
, strKey 
+ _T("\\Application")). 
 242                     QueryValue(wxEmptyString
, ddeServer
); 
 243                 wxRegKey(wxRegKey::HKCR
, strKey 
+ _T("\\Topic")). 
 244                     QueryValue(wxEmptyString
, ddeTopic
); 
 246                 if (ddeTopic
.IsEmpty()) 
 247                     ddeTopic 
= wxT("System"); 
 249                 // HACK: we use a special feature of wxExecute which exists 
 250                 //       just because we need it here: it will establish DDE 
 251                 //       conversation with the program it just launched 
 252                 command
.Prepend(_T("WX_DDE#")); 
 253                 command 
<< _T('#') << ddeServer
 
 254                         << _T('#') << ddeTopic
 
 255                         << _T('#') << ddeCommand
; 
 259             if ( !foundFilename 
) 
 261                 // we didn't find any '%1' - the application doesn't know which 
 262                 // file to open (note that we only do it if there is no DDEExec 
 265                 // HACK: append the filename at the end, hope that it will do 
 266                 command 
<< wxT(" %s"); 
 270     //else: no such file type or no value, will return empty string 
 276 wxFileTypeImpl::GetOpenCommand(wxString 
*openCmd
, 
 277                                const wxFileType::MessageParameters
& params
) 
 280     wxString cmd 
= GetCommand(wxT("open")); 
 282     *openCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 284     return !openCmd
->IsEmpty(); 
 288 wxFileTypeImpl::GetPrintCommand(wxString 
*printCmd
, 
 289                                 const wxFileType::MessageParameters
& params
) 
 292     wxString cmd 
= GetCommand(wxT("print")); 
 294     *printCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 296     return !printCmd
->IsEmpty(); 
 299 // ---------------------------------------------------------------------------- 
 300 // getting other stuff 
 301 // ---------------------------------------------------------------------------- 
 303 // TODO this function is half implemented 
 304 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
) 
 306     if ( m_ext
.IsEmpty() ) { 
 307         // the only way to get the list of extensions from the file type is to 
 308         // scan through all extensions in the registry - too slow... 
 313         extensions
.Add(m_ext
); 
 315         // it's a lie too, we don't return _all_ extensions... 
 320 bool wxFileTypeImpl::GetMimeType(wxString 
*mimeType
) const 
 322     // suppress possible error messages 
 324     wxRegKey 
key(wxRegKey::HKCR
, m_ext
); 
 326     return key
.Open() && key
.QueryValue(wxT("Content Type"), *mimeType
); 
 329 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const 
 333     if ( !GetMimeType(&s
) ) 
 344 bool wxFileTypeImpl::GetIcon(wxIconLocation 
*iconLoc
) const 
 347     strIconKey 
<< m_strFileType 
<< wxT("\\DefaultIcon"); 
 349     // suppress possible error messages 
 351     wxRegKey 
key(wxRegKey::HKCR
, strIconKey
); 
 355         // it's the default value of the key 
 356         if ( key
.QueryValue(wxEmptyString
, strIcon
) ) { 
 357             // the format is the following: <full path to file>, <icon index> 
 358             // NB: icon index may be negative as well as positive and the full 
 359             //     path may contain the environment variables inside '%' 
 360             wxString strFullPath 
= strIcon
.BeforeLast(wxT(',')), 
 361             strIndex 
= strIcon
.AfterLast(wxT(',')); 
 363             // index may be omitted, in which case BeforeLast(',') is empty and 
 364             // AfterLast(',') is the whole string 
 365             if ( strFullPath
.IsEmpty() ) { 
 366                 strFullPath 
= strIndex
; 
 372                 iconLoc
->SetFileName(wxExpandEnvVars(strFullPath
)); 
 374                 iconLoc
->SetIndex(wxAtoi(strIndex
)); 
 381     // no such file type or no value or incorrect icon entry 
 385 bool wxFileTypeImpl::GetDescription(wxString 
*desc
) const 
 387     // suppress possible error messages 
 389     wxRegKey 
key(wxRegKey::HKCR
, m_strFileType
); 
 392         // it's the default value of the key 
 393         if ( key
.QueryValue(wxEmptyString
, *desc
) ) { 
 403 wxMimeTypesManagerImpl::CreateFileType(const wxString
& filetype
, const wxString
& ext
) 
 405     wxFileType 
*fileType 
= new wxFileType
; 
 406     fileType
->m_impl
->Init(filetype
, ext
); 
 410 // extension -> file type 
 412 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
) 
 414     // add the leading point if necessary 
 416     if ( ext
[0u] != wxT('.') ) { 
 421     // suppress possible error messages 
 424     bool knownExtension 
= FALSE
; 
 426     wxString strFileType
; 
 427     wxRegKey 
key(wxRegKey::HKCR
, str
); 
 429         // it's the default value of the key 
 430         if ( key
.QueryValue(wxEmptyString
, strFileType
) ) { 
 431             // create the new wxFileType object 
 432             return CreateFileType(strFileType
, ext
); 
 435             // this extension doesn't have a filetype, but it's known to the 
 436             // system and may be has some other useful keys (open command or 
 437             // content-type), so still return a file type object for it 
 438             knownExtension 
= TRUE
; 
 442     if ( !knownExtension 
) 
 448     return CreateFileType(wxEmptyString
, ext
); 
 453 wxMimeTypesManagerImpl::GetOrAllocateFileTypeFromExtension(const wxString& ext) 
 455     wxFileType *fileType = GetFileTypeFromExtension(ext); 
 458         fileType = CreateFileType(wxEmptyString, ext); 
 465 // MIME type -> extension -> file type 
 467 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
) 
 469     wxString strKey 
= MIME_DATABASE_KEY
; 
 472     // suppress possible error messages 
 476     wxRegKey 
key(wxRegKey::HKCR
, strKey
); 
 478         if ( key
.QueryValue(wxT("Extension"), ext
) ) { 
 479             return GetFileTypeFromExtension(ext
); 
 487 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& mimetypes
) 
 489     // enumerate all keys under MIME_DATABASE_KEY 
 490     wxRegKey 
key(wxRegKey::HKCR
, MIME_DATABASE_KEY
); 
 494     bool cont 
= key
.GetFirstKey(type
, cookie
); 
 499         cont 
= key
.GetNextKey(type
, cookie
); 
 502     return mimetypes
.GetCount(); 
 505 // ---------------------------------------------------------------------------- 
 506 // create a new association 
 507 // ---------------------------------------------------------------------------- 
 509 wxFileType 
*wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo
& ftInfo
) 
 511     wxCHECK_MSG( !ftInfo
.GetExtensions().IsEmpty(), NULL
, 
 512                  _T("Associate() needs extension") ); 
 519     wxString ext 
= ftInfo
.GetExtensions()[iExtCount
]; 
 521     wxCHECK_MSG( !ext
.empty(), NULL
, 
 522                  _T("Associate() needs non empty extension") ); 
 524     if ( ext
[0u] != _T('.') ) 
 525         extWithDot 
= _T('.'); 
 528     // start by setting the HKCR\\.ext entries 
 529     // default is filetype; content type is mimetype 
 530     const wxString
& filetypeOrig 
= ftInfo
.GetShortDesc(); 
 532     wxRegKey 
key(wxRegKey::HKCR
, extWithDot
); 
 535         // create the mapping from the extension to the filetype 
 540             if ( filetypeOrig
.empty() ) 
 542                 // make it up from the extension 
 543                 filetype 
<< extWithDot
.c_str() + 1 << _T("_file"); 
 547                 // just use the provided one 
 548                 filetype 
= filetypeOrig
; 
 551             key
.SetValue(wxEmptyString
, filetype
); 
 556             // key already exists, maybe we want to change it ?? 
 557             if (!filetypeOrig
.empty()) 
 559                     filetype 
= filetypeOrig
; 
 560                     key
.SetValue(wxEmptyString
, filetype
); 
 564                     key
.QueryValue(wxEmptyString
, filetype
); 
 567         // now set a mimetypeif we have it, but ignore it if none 
 568         const wxString
& mimetype 
= ftInfo
.GetMimeType(); 
 569         if ( !mimetype
.empty() ) 
 572             ok 
= key
.SetValue(_T("Content Type"), mimetype
); 
 576                 // create the MIME key 
 577                 wxString strKey 
= MIME_DATABASE_KEY
; 
 579                 wxRegKey 
keyMIME(wxRegKey::HKCR
, strKey
); 
 580                 ok 
= keyMIME
.Create(); 
 584                     // and provide a back link to the extension 
 585                     keyMIME
.SetValue(_T("Extension"), extWithDot
); 
 591     // now make other extensions have the same filetype 
 593     for (iExtCount
=1; iExtCount 
< ftInfo
.GetExtensionsCount(); iExtCount
++ ) 
 595             ext 
= ftInfo
.GetExtensions()[iExtCount
]; 
 596             if ( ext
[0u] != _T('.') ) 
 597                extWithDot 
= _T('.'); 
 600             wxRegKey 
key(wxRegKey::HKCR
, extWithDot
); 
 601             if ( !key
.Exists() ) key
.Create(); 
 602             key
.SetValue(wxEmptyString
, filetype
); 
 604         // now set any mimetypes we may have, but ignore it if none 
 605         const wxString
& mimetype 
= ftInfo
.GetMimeType(); 
 606         if ( !mimetype
.empty() ) 
 609             ok 
= key
.SetValue(_T("Content Type"), mimetype
); 
 613                 // create the MIME key 
 614                 wxString strKey 
= MIME_DATABASE_KEY
; 
 616                 wxRegKey 
keyMIME(wxRegKey::HKCR
, strKey
); 
 617                 ok 
= keyMIME
.Create(); 
 621                     // and provide a back link to the extension 
 622                     keyMIME
.SetValue(_T("Extension"), extWithDot
); 
 628     } // end of for loop; all extensions now point to HKCR\.ext\Default 
 630     // create the filetype key itself (it will be empty for now, but 
 631     // SetCommand(), SetDefaultIcon() &c will use it later) 
 632     wxRegKey 
keyFT(wxRegKey::HKCR
, filetype
); 
 635     wxFileType 
*ft 
= CreateFileType(filetype
, extWithDot
); 
 639             if (! ftInfo
.GetOpenCommand ().IsEmpty() ) ft
->SetCommand (ftInfo
.GetOpenCommand (), wxT("open"  ) ); 
 640             if (! ftInfo
.GetPrintCommand().IsEmpty() ) ft
->SetCommand (ftInfo
.GetPrintCommand(), wxT("print" ) ); 
 641             // chris: I don't like the ->m_impl-> here FIX this ?? 
 642             if (! ftInfo
.GetDescription ().IsEmpty() ) ft
->m_impl
->SetDescription (ftInfo
.GetDescription ()) ; 
 643             if (! ftInfo
.GetIconFile().IsEmpty() ) ft
->SetDefaultIcon (ftInfo
.GetIconFile(), ftInfo
.GetIconIndex() ); 
 649 bool wxFileTypeImpl::SetCommand(const wxString
& cmd
, 
 650                                 const wxString
& verb
, 
 651                                 bool WXUNUSED(overwriteprompt
)) 
 653     wxCHECK_MSG( !m_ext
.IsEmpty() && !verb
.IsEmpty(), FALSE
, 
 654                  _T("SetCommand() needs an extension and a verb") ); 
 656     if ( !EnsureExtKeyExists() ) 
 659     wxRegKey 
rkey(wxRegKey::HKCR
, GetVerbPath(verb
)); 
 661     if ( rkey
.Exists() && overwriteprompt 
) 
 665         rkey
.QueryValue(wxEmptyString
, old
); 
 669                     _("Do you want to overwrite the command used to %s " 
 670                       "files with extension \"%s\" ?\nCurrent value is \n%s, " 
 671                       "\nNew value is \n%s %1"), // bug here FIX need %1 ?? 
 676                 _("Confirm registry update"), 
 677                 wxYES_NO 
| wxICON_QUESTION
 
 687     // 1. translate '%s' to '%1' instead of always adding it 
 688     // 2. create DDEExec value if needed (undo GetCommand) 
 689     return rkey
.Create() && rkey
.SetValue(wxEmptyString
, cmd 
+ _T(" \"%1\"") ); 
 693 bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig) 
 695     wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("SetMimeType() needs extension") ); 
 697     if ( !EnsureExtKeyExists() ) 
 700     // VZ: is this really useful? (FIXME) 
 704         // make up a default value for it 
 706         wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL); 
 707         mimeType << _T("application/x-") << cmd; 
 711         mimeType = mimeTypeOrig; 
 714     wxRegKey rkey(wxRegKey::HKCR, m_ext); 
 715     return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType); 
 719 bool wxFileTypeImpl::SetDefaultIcon(const wxString
& cmd
, int index
) 
 721     wxCHECK_MSG( !m_ext
.IsEmpty(), FALSE
, _T("SetDefaultIcon() needs extension") ); 
 722     wxCHECK_MSG( !m_strFileType
.IsEmpty(), FALSE
, _T("File key not found") ); 
 723 //    the next line fails on a SMBshare, I think because it is case mangled 
 724 //    wxCHECK_MSG( !wxFileExists(cmd), FALSE, _T("Icon file not found.") ); 
 726     if ( !EnsureExtKeyExists() ) 
 729     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType 
+ _T("\\DefaultIcon")); 
 731     return rkey
.Create() && 
 732            rkey
.SetValue(wxEmptyString
, 
 733                          wxString::Format(_T("%s,%d"), cmd
.c_str(), index
)); 
 736 bool wxFileTypeImpl::SetDescription (const wxString
& desc
) 
 738     wxCHECK_MSG( !m_strFileType
.IsEmpty(), FALSE
, _T("File key not found") ); 
 739     wxCHECK_MSG( !desc
.IsEmpty(), FALSE
, _T("No file description supplied") ); 
 741     if ( !EnsureExtKeyExists() ) 
 744     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType 
); 
 746     return rkey
.Create() && 
 747            rkey
.SetValue(wxEmptyString
, desc
); 
 750 // ---------------------------------------------------------------------------- 
 751 // remove file association 
 752 // ---------------------------------------------------------------------------- 
 754 bool wxFileTypeImpl::Unassociate() 
 757     if ( !RemoveOpenCommand() ) 
 759     if ( !RemoveDefaultIcon() ) 
 761     if ( !RemoveMimeType() ) 
 763    if ( !RemoveDescription() ) 
 767     //this might hold other keys, eg some have CSLID keys 
 770         // delete the root key 
 771         wxRegKey key(wxRegKey::HKCR, m_ext); 
 773             result = key.DeleteSelf(); 
 779 bool wxFileTypeImpl::RemoveOpenCommand() 
 781    return RemoveCommand(_T("open")); 
 784 bool wxFileTypeImpl::RemoveCommand(const wxString
& verb
) 
 786     wxCHECK_MSG( !m_ext
.IsEmpty() && !verb
.IsEmpty(), FALSE
, 
 787                  _T("RemoveCommand() needs an extension and a verb") ); 
 789     wxString  sKey 
= m_strFileType
; 
 790     wxRegKey 
rkey(wxRegKey::HKCR
, GetVerbPath(verb
)); 
 792     // if the key already doesn't exist, it's a success 
 793     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 796 bool wxFileTypeImpl::RemoveMimeType() 
 798     wxCHECK_MSG( !m_ext
.IsEmpty(), FALSE
, _T("RemoveMimeType() needs extension") ); 
 800     wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 801     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 804 bool wxFileTypeImpl::RemoveDefaultIcon() 
 806     wxCHECK_MSG( !m_ext
.IsEmpty(), FALSE
, 
 807                  _T("RemoveDefaultIcon() needs extension") ); 
 809     wxRegKey 
rkey (wxRegKey::HKCR
, m_strFileType  
+ _T("\\DefaultIcon")); 
 810     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 813 bool wxFileTypeImpl::RemoveDescription() 
 815     wxCHECK_MSG( !m_ext
.IsEmpty(), FALSE
, 
 816                  _T("RemoveDescription() needs extension") ); 
 818     wxRegKey 
rkey (wxRegKey::HKCR
, m_strFileType 
); 
 819     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 822 #endif // wxUSE_MIMETYPE