]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/mimetype.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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 ///////////////////////////////////////////////////////////////////////////// 
  12 // for compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  21 #include "wx/msw/mimetype.h" 
  24     #include "wx/dynarray.h" 
  25     #include "wx/string.h" 
  30         #include "wx/msgdlg.h" 
  35 #include "wx/iconloc.h" 
  36 #include "wx/confbase.h" 
  39     #include "wx/msw/registry.h" 
  40     #include "wx/msw/private.h" 
  43 // other standard headers 
  46 // in case we're compiling in non-GUI mode 
  47 class WXDLLEXPORT wxIcon
; 
  49 // These classes use Windows registry to retrieve the required information. 
  51 // Keys used (not all of them are documented, so it might actually stop working 
  52 // in future versions of Windows...): 
  53 //  1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME 
  54 //     types, each key has a string value "Extension" which gives (dot preceded) 
  55 //     extension for the files of this MIME type. 
  57 //  2. "HKCR\.ext" contains 
  58 //   a) unnamed value containing the "filetype" 
  59 //   b) value "Content Type" containing the MIME type 
  61 // 3. "HKCR\filetype" contains 
  62 //   a) unnamed value containing the description 
  63 //   b) subkey "DefaultIcon" with single unnamed value giving the icon index in 
  65 //   c) shell\open\command and shell\open\print subkeys containing the commands 
  66 //      to open/print the file (the positional parameters are introduced by %1, 
  67 //      %2, ... in these strings, we change them to %s ourselves) 
  69 // although I don't know of any official documentation which mentions this 
  70 // location, uses it, so it isn't likely to change 
  71 static const wxChar 
*MIME_DATABASE_KEY 
= wxT("MIME\\Database\\Content Type\\"); 
  73 // this function replaces Microsoft %1 with Unix-like %s 
  74 static bool CanonicalizeParams(wxString
& command
) 
  76     // transform it from '%1' to '%s' style format string (now also test for %L 
  77     // as apparently MS started using it as well for the same purpose) 
  79     // NB: we don't make any attempt to verify that the string is valid, i.e. 
  80     //     doesn't contain %2, or second %1 or .... But we do make sure that we 
  81     //     return a string with _exactly_ one '%s'! 
  82     bool foundFilename 
= false; 
  83     size_t len 
= command
.length(); 
  84     for ( size_t n 
= 0; (n 
< len
) && !foundFilename
; n
++ ) 
  86         if ( command
[n
] == wxT('%') && 
  88                 (command
[n 
+ 1] == wxT('1') || command
[n 
+ 1] == wxT('L')) ) 
  90             // replace it with '%s' 
  91             command
[n 
+ 1] = wxT('s'); 
 100 void wxFileTypeImpl::Init(const wxString
& strFileType
, const wxString
& ext
) 
 102     // VZ: does it? (FIXME) 
 103     wxCHECK_RET( !ext
.empty(), _T("needs an extension") ); 
 105     if ( ext
[0u] != wxT('.') ) { 
 110     m_strFileType 
= strFileType
; 
 111     if ( !strFileType 
) { 
 112         m_strFileType 
= m_ext
.AfterFirst('.') + _T("_auto_file"); 
 116 wxString 
wxFileTypeImpl::GetVerbPath(const wxString
& verb
) const 
 119     path 
<< m_strFileType 
<< _T("\\shell\\") << verb 
<< _T("\\command"); 
 123 size_t wxFileTypeImpl::GetAllCommands(wxArrayString 
*verbs
, 
 124                                       wxArrayString 
*commands
, 
 125                                       const wxFileType::MessageParameters
& params
) const 
 127     wxCHECK_MSG( !m_ext
.empty(), 0, _T("GetAllCommands() needs an extension") ); 
 129     if ( m_strFileType
.empty() ) 
 131         // get it from the registry 
 132         wxFileTypeImpl 
*self 
= wxConstCast(this, wxFileTypeImpl
); 
 133         wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 134         if ( !rkey
.Exists() || !rkey
.QueryValue(wxEmptyString
, self
->m_strFileType
) ) 
 136             wxLogDebug(_T("Can't get the filetype for extension '%s'."), 
 143     // enum all subkeys of HKCR\filetype\shell 
 145     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType  
+ _T("\\shell")); 
 148     bool ok 
= rkey
.GetFirstKey(verb
, dummy
); 
 151         wxString command 
= wxFileType::ExpandCommand(GetCommand(verb
), params
); 
 153         // we want the open bverb to eb always the first 
 155         if ( verb
.CmpNoCase(_T("open")) == 0 ) 
 158                 verbs
->Insert(verb
, 0); 
 160                 commands
->Insert(command
, 0); 
 162         else // anything else than "open" 
 167                 commands
->Add(command
); 
 172         ok 
= rkey
.GetNextKey(verb
, dummy
); 
 178 // ---------------------------------------------------------------------------- 
 179 // modify the registry database 
 180 // ---------------------------------------------------------------------------- 
 182 bool wxFileTypeImpl::EnsureExtKeyExists() 
 184     wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 185     if ( !rkey
.Exists() ) 
 187         if ( !rkey
.Create() || !rkey
.SetValue(wxEmptyString
, m_strFileType
) ) 
 189             wxLogError(_("Failed to create registry entry for '%s' files."), 
 198 // ---------------------------------------------------------------------------- 
 199 // get the command to use 
 200 // ---------------------------------------------------------------------------- 
 202 wxString 
wxFileTypeImpl::GetCommand(const wxChar 
*verb
) const 
 204     // suppress possible error messages 
 208     if ( wxRegKey(wxRegKey::HKCR
, m_ext 
+ _T("\\shell")).Exists() ) 
 210     if ( wxRegKey(wxRegKey::HKCR
, m_strFileType 
+ _T("\\shell")).Exists() ) 
 211         strKey 
= m_strFileType
; 
 216         return wxEmptyString
; 
 219     strKey 
<< wxT("\\shell\\") << verb
; 
 220     wxRegKey 
key(wxRegKey::HKCR
, strKey 
+ _T("\\command")); 
 222     if ( key
.Open(wxRegKey::Read
) ) { 
 223         // it's the default value of the key 
 224         if ( key
.QueryValue(wxEmptyString
, command
) ) { 
 225             bool foundFilename 
= CanonicalizeParams(command
); 
 228             // look whether we must issue some DDE requests to the application 
 229             // (and not just launch it) 
 230             strKey 
+= _T("\\DDEExec"); 
 231             wxRegKey 
keyDDE(wxRegKey::HKCR
, strKey
); 
 232             if ( keyDDE
.Open(wxRegKey::Read
) ) { 
 233                 wxString ddeCommand
, ddeServer
, ddeTopic
; 
 234                 keyDDE
.QueryValue(wxEmptyString
, ddeCommand
); 
 235                 ddeCommand
.Replace(_T("%1"), _T("%s")); 
 237                 wxRegKey 
keyServer(wxRegKey::HKCR
, strKey 
+ _T("\\Application")); 
 238                 keyServer
.QueryValue(wxEmptyString
, ddeServer
); 
 239                 wxRegKey 
keyTopic(wxRegKey::HKCR
, strKey 
+ _T("\\Topic")); 
 240                 keyTopic
.QueryValue(wxEmptyString
, ddeTopic
); 
 242                 if (ddeTopic
.empty()) 
 243                     ddeTopic 
= wxT("System"); 
 245                 // HACK: we use a special feature of wxExecute which exists 
 246                 //       just because we need it here: it will establish DDE 
 247                 //       conversation with the program it just launched 
 248                 command
.Prepend(_T("WX_DDE#")); 
 249                 command 
<< _T('#') << ddeServer
 
 250                         << _T('#') << ddeTopic
 
 251                         << _T('#') << ddeCommand
; 
 255             if ( !foundFilename 
) 
 257                 // we didn't find any '%1' - the application doesn't know which 
 258                 // file to open (note that we only do it if there is no DDEExec 
 261                 // HACK: append the filename at the end, hope that it will do 
 262                 command 
<< wxT(" %s"); 
 266     //else: no such file type or no value, will return empty string 
 272 wxFileTypeImpl::GetOpenCommand(wxString 
*openCmd
, 
 273                                const wxFileType::MessageParameters
& params
) 
 276     wxString cmd 
= GetCommand(wxT("open")); 
 278     *openCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 280     return !openCmd
->empty(); 
 284 wxFileTypeImpl::GetPrintCommand(wxString 
*printCmd
, 
 285                                 const wxFileType::MessageParameters
& params
) 
 288     wxString cmd 
= GetCommand(wxT("print")); 
 290     *printCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 292     return !printCmd
->empty(); 
 295 // ---------------------------------------------------------------------------- 
 296 // getting other stuff 
 297 // ---------------------------------------------------------------------------- 
 299 // TODO this function is half implemented 
 300 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
) 
 302     if ( m_ext
.empty() ) { 
 303         // the only way to get the list of extensions from the file type is to 
 304         // scan through all extensions in the registry - too slow... 
 309         extensions
.Add(m_ext
); 
 311         // it's a lie too, we don't return _all_ extensions... 
 316 bool wxFileTypeImpl::GetMimeType(wxString 
*mimeType
) const 
 318     // suppress possible error messages 
 320     wxRegKey 
key(wxRegKey::HKCR
, m_ext
); 
 322     return key
.Open(wxRegKey::Read
) && 
 323                 key
.QueryValue(wxT("Content Type"), *mimeType
); 
 326 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const 
 330     if ( !GetMimeType(&s
) ) 
 341 bool wxFileTypeImpl::GetIcon(wxIconLocation 
*iconLoc
) const 
 344     strIconKey 
<< m_strFileType 
<< wxT("\\DefaultIcon"); 
 346     // suppress possible error messages 
 348     wxRegKey 
key(wxRegKey::HKCR
, strIconKey
); 
 350     if ( key
.Open(wxRegKey::Read
) ) { 
 352         // it's the default value of the key 
 353         if ( key
.QueryValue(wxEmptyString
, strIcon
) ) { 
 354             // the format is the following: <full path to file>, <icon index> 
 355             // NB: icon index may be negative as well as positive and the full 
 356             //     path may contain the environment variables inside '%' 
 357             wxString strFullPath 
= strIcon
.BeforeLast(wxT(',')), 
 358             strIndex 
= strIcon
.AfterLast(wxT(',')); 
 360             // index may be omitted, in which case BeforeLast(',') is empty and 
 361             // AfterLast(',') is the whole string 
 362             if ( strFullPath
.empty() ) { 
 363                 strFullPath 
= strIndex
; 
 369                 iconLoc
->SetFileName(wxExpandEnvVars(strFullPath
)); 
 371                 iconLoc
->SetIndex(wxAtoi(strIndex
)); 
 378     // no such file type or no value or incorrect icon entry 
 382 bool wxFileTypeImpl::GetDescription(wxString 
*desc
) const 
 384     // suppress possible error messages 
 386     wxRegKey 
key(wxRegKey::HKCR
, m_strFileType
); 
 388     if ( key
.Open(wxRegKey::Read
) ) { 
 389         // it's the default value of the key 
 390         if ( key
.QueryValue(wxEmptyString
, *desc
) ) { 
 400 wxMimeTypesManagerImpl::CreateFileType(const wxString
& filetype
, const wxString
& ext
) 
 402     wxFileType 
*fileType 
= new wxFileType
; 
 403     fileType
->m_impl
->Init(filetype
, ext
); 
 407 // extension -> file type 
 409 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
) 
 411     // add the leading point if necessary 
 413     if ( ext
[0u] != wxT('.') ) { 
 418     // suppress possible error messages 
 421     bool knownExtension 
= false; 
 423     wxString strFileType
; 
 424     wxRegKey 
key(wxRegKey::HKCR
, str
); 
 425     if ( key
.Open(wxRegKey::Read
) ) { 
 426         // it's the default value of the key 
 427         if ( key
.QueryValue(wxEmptyString
, strFileType
) ) { 
 428             // create the new wxFileType object 
 429             return CreateFileType(strFileType
, ext
); 
 432             // this extension doesn't have a filetype, but it's known to the 
 433             // system and may be has some other useful keys (open command or 
 434             // content-type), so still return a file type object for it 
 435             knownExtension 
= true; 
 439     if ( !knownExtension 
) 
 445     return CreateFileType(wxEmptyString
, ext
); 
 450 wxMimeTypesManagerImpl::GetOrAllocateFileTypeFromExtension(const wxString& ext) 
 452     wxFileType *fileType = GetFileTypeFromExtension(ext); 
 455         fileType = CreateFileType(wxEmptyString, ext); 
 462 // MIME type -> extension -> file type 
 464 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
) 
 466     wxString strKey 
= MIME_DATABASE_KEY
; 
 469     // suppress possible error messages 
 473     wxRegKey 
key(wxRegKey::HKCR
, strKey
); 
 474     if ( key
.Open(wxRegKey::Read
) ) { 
 475         if ( key
.QueryValue(wxT("Extension"), ext
) ) { 
 476             return GetFileTypeFromExtension(ext
); 
 484 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& mimetypes
) 
 486     // enumerate all keys under MIME_DATABASE_KEY 
 487     wxRegKey 
key(wxRegKey::HKCR
, MIME_DATABASE_KEY
); 
 491     bool cont 
= key
.GetFirstKey(type
, cookie
); 
 496         cont 
= key
.GetNextKey(type
, cookie
); 
 499     return mimetypes
.GetCount(); 
 502 // ---------------------------------------------------------------------------- 
 503 // create a new association 
 504 // ---------------------------------------------------------------------------- 
 506 wxFileType 
*wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo
& ftInfo
) 
 508     wxCHECK_MSG( !ftInfo
.GetExtensions().empty(), NULL
, 
 509                  _T("Associate() needs extension") ); 
 512     size_t iExtCount 
= 0; 
 516     wxString ext 
= ftInfo
.GetExtensions()[iExtCount
]; 
 518     wxCHECK_MSG( !ext
.empty(), NULL
, 
 519                  _T("Associate() needs non empty extension") ); 
 521     if ( ext
[0u] != _T('.') ) 
 522         extWithDot 
= _T('.'); 
 525     // start by setting the HKCR\\.ext entries 
 526     // default is filetype; content type is mimetype 
 527     const wxString
& filetypeOrig 
= ftInfo
.GetShortDesc(); 
 529     wxRegKey 
key(wxRegKey::HKCR
, extWithDot
); 
 532         // create the mapping from the extension to the filetype 
 537             if ( filetypeOrig
.empty() ) 
 539                 // make it up from the extension 
 540                 filetype 
<< extWithDot
.c_str() + 1 << _T("_file"); 
 544                 // just use the provided one 
 545                 filetype 
= filetypeOrig
; 
 548             key
.SetValue(wxEmptyString
, filetype
); 
 553         // key already exists, maybe we want to change it ?? 
 554         if (!filetypeOrig
.empty()) 
 556             filetype 
= filetypeOrig
; 
 557             key
.SetValue(wxEmptyString
, filetype
); 
 561             key
.QueryValue(wxEmptyString
, filetype
); 
 565     // now set a mimetypeif we have it, but ignore it if none 
 566     const wxString
& mimetype 
= ftInfo
.GetMimeType(); 
 567     if ( !mimetype
.empty() ) 
 570         ok 
= key
.SetValue(_T("Content Type"), mimetype
); 
 574             // create the MIME key 
 575             wxString strKey 
= MIME_DATABASE_KEY
; 
 577             wxRegKey 
keyMIME(wxRegKey::HKCR
, strKey
); 
 578             ok 
= keyMIME
.Create(); 
 582                 // and provide a back link to the extension 
 583                 keyMIME
.SetValue(_T("Extension"), extWithDot
); 
 589     // now make other extensions have the same filetype 
 591     for (iExtCount
=1; iExtCount 
< ftInfo
.GetExtensionsCount(); iExtCount
++ ) 
 593         ext 
= ftInfo
.GetExtensions()[iExtCount
]; 
 594         if ( ext
[0u] != _T('.') ) 
 595            extWithDot 
= _T('.'); 
 598         wxRegKey 
key(wxRegKey::HKCR
, extWithDot
); 
 599         if ( !key
.Exists() ) key
.Create(); 
 600         key
.SetValue(wxEmptyString
, filetype
); 
 602         // now set any mimetypes we may have, but ignore it if none 
 603         const wxString
& mimetype 
= ftInfo
.GetMimeType(); 
 604         if ( !mimetype
.empty() ) 
 607             ok 
= key
.SetValue(_T("Content Type"), mimetype
); 
 611                 // create the MIME key 
 612                 wxString strKey 
= MIME_DATABASE_KEY
; 
 614                 wxRegKey 
keyMIME(wxRegKey::HKCR
, strKey
); 
 615                 ok 
= keyMIME
.Create(); 
 619                     // and provide a back link to the extension 
 620                     keyMIME
.SetValue(_T("Extension"), extWithDot
); 
 625     } // end of for loop; all extensions now point to HKCR\.ext\Default 
 627     // create the filetype key itself (it will be empty for now, but 
 628     // SetCommand(), SetDefaultIcon() &c will use it later) 
 629     wxRegKey 
keyFT(wxRegKey::HKCR
, filetype
); 
 632     wxFileType 
*ft 
= CreateFileType(filetype
, extWithDot
); 
 636         if (! ftInfo
.GetOpenCommand ().empty() ) ft
->SetCommand (ftInfo
.GetOpenCommand (), wxT("open"  ) ); 
 637         if (! ftInfo
.GetPrintCommand().empty() ) ft
->SetCommand (ftInfo
.GetPrintCommand(), wxT("print" ) ); 
 638         // chris: I don't like the ->m_impl-> here FIX this ?? 
 639         if (! ftInfo
.GetDescription ().empty() ) ft
->m_impl
->SetDescription (ftInfo
.GetDescription ()) ; 
 640         if (! ftInfo
.GetIconFile().empty() ) ft
->SetDefaultIcon (ftInfo
.GetIconFile(), ftInfo
.GetIconIndex() ); 
 647 bool wxFileTypeImpl::SetCommand(const wxString
& cmd
, 
 648                                 const wxString
& verb
, 
 649                                 bool WXUNUSED(overwriteprompt
)) 
 651     wxCHECK_MSG( !m_ext
.empty() && !verb
.empty(), false, 
 652                  _T("SetCommand() needs an extension and a verb") ); 
 654     if ( !EnsureExtKeyExists() ) 
 657     wxRegKey 
rkey(wxRegKey::HKCR
, GetVerbPath(verb
)); 
 659     if ( rkey
.Exists() && overwriteprompt 
) 
 663         rkey
.QueryValue(wxEmptyString
, old
); 
 667                     _("Do you want to overwrite the command used to %s " 
 668                       "files with extension \"%s\" ?\nCurrent value is \n%s, " 
 669                       "\nNew value is \n%s %1"), // bug here FIX need %1 ?? 
 674                 _("Confirm registry update"), 
 675                 wxYES_NO 
| wxICON_QUESTION
 
 685     // 1. translate '%s' to '%1' instead of always adding it 
 686     // 2. create DDEExec value if needed (undo GetCommand) 
 687     return rkey
.Create() && rkey
.SetValue(wxEmptyString
, cmd 
+ _T(" \"%1\"") ); 
 691 bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig) 
 693     wxCHECK_MSG( !m_ext.empty(), false, _T("SetMimeType() needs extension") ); 
 695     if ( !EnsureExtKeyExists() ) 
 698     // VZ: is this really useful? (FIXME) 
 702         // make up a default value for it 
 704         wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL); 
 705         mimeType << _T("application/x-") << cmd; 
 709         mimeType = mimeTypeOrig; 
 712     wxRegKey rkey(wxRegKey::HKCR, m_ext); 
 713     return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType); 
 717 bool wxFileTypeImpl::SetDefaultIcon(const wxString
& cmd
, int index
) 
 719     wxCHECK_MSG( !m_ext
.empty(), false, _T("SetDefaultIcon() needs extension") ); 
 720     wxCHECK_MSG( !m_strFileType
.empty(), false, _T("File key not found") ); 
 721 //    the next line fails on a SMBshare, I think because it is case mangled 
 722 //    wxCHECK_MSG( !wxFileExists(cmd), false, _T("Icon file not found.") ); 
 724     if ( !EnsureExtKeyExists() ) 
 727     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType 
+ _T("\\DefaultIcon")); 
 729     return rkey
.Create() && 
 730            rkey
.SetValue(wxEmptyString
, 
 731                          wxString::Format(_T("%s,%d"), cmd
.c_str(), index
)); 
 734 bool wxFileTypeImpl::SetDescription (const wxString
& desc
) 
 736     wxCHECK_MSG( !m_strFileType
.empty(), false, _T("File key not found") ); 
 737     wxCHECK_MSG( !desc
.empty(), false, _T("No file description supplied") ); 
 739     if ( !EnsureExtKeyExists() ) 
 742     wxRegKey 
rkey(wxRegKey::HKCR
, m_strFileType 
); 
 744     return rkey
.Create() && 
 745            rkey
.SetValue(wxEmptyString
, desc
); 
 748 // ---------------------------------------------------------------------------- 
 749 // remove file association 
 750 // ---------------------------------------------------------------------------- 
 752 bool wxFileTypeImpl::Unassociate() 
 755     if ( !RemoveOpenCommand() ) 
 757     if ( !RemoveDefaultIcon() ) 
 759     if ( !RemoveMimeType() ) 
 761     if ( !RemoveDescription() ) 
 765     //this might hold other keys, eg some have CSLID keys 
 768         // delete the root key 
 769         wxRegKey key(wxRegKey::HKCR, m_ext); 
 771             result = key.DeleteSelf(); 
 777 bool wxFileTypeImpl::RemoveOpenCommand() 
 779    return RemoveCommand(_T("open")); 
 782 bool wxFileTypeImpl::RemoveCommand(const wxString
& verb
) 
 784     wxCHECK_MSG( !m_ext
.empty() && !verb
.empty(), false, 
 785                  _T("RemoveCommand() needs an extension and a verb") ); 
 787     wxRegKey 
rkey(wxRegKey::HKCR
, GetVerbPath(verb
)); 
 789     // if the key already doesn't exist, it's a success 
 790     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 793 bool wxFileTypeImpl::RemoveMimeType() 
 795     wxCHECK_MSG( !m_ext
.empty(), false, _T("RemoveMimeType() needs extension") ); 
 797     wxRegKey 
rkey(wxRegKey::HKCR
, m_ext
); 
 798     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 801 bool wxFileTypeImpl::RemoveDefaultIcon() 
 803     wxCHECK_MSG( !m_ext
.empty(), false, 
 804                  _T("RemoveDefaultIcon() needs extension") ); 
 806     wxRegKey 
rkey (wxRegKey::HKCR
, m_strFileType  
+ _T("\\DefaultIcon")); 
 807     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 810 bool wxFileTypeImpl::RemoveDescription() 
 812     wxCHECK_MSG( !m_ext
.empty(), false, 
 813                  _T("RemoveDescription() needs extension") ); 
 815     wxRegKey 
rkey (wxRegKey::HKCR
, m_strFileType 
); 
 816     return !rkey
.Exists() || rkey
.DeleteSelf(); 
 819 #endif // wxUSE_MIMETYPE