ExplorerFindFile.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "main.h"
  2. #include "ExplorerFindFile.h"
  3. ExplorerFindFile::ExplorerFindFile()
  4. {
  5. }
  6. ExplorerFindFile::~ExplorerFindFile()
  7. {
  8. }
  9. void ExplorerFindFile::Reset()
  10. {
  11. pidlList.clear();
  12. }
  13. // still need to make this handle zip:// entries natively to get them working as needed
  14. BOOL ExplorerFindFile::AddFile( wchar_t *file )
  15. {
  16. LPSHELLFOLDER pDesktopFolder = 0;
  17. if ( SUCCEEDED( SHGetDesktopFolder( &pDesktopFolder ) ) )
  18. {
  19. LPITEMIDLIST filepidl = 0, folderpidl = 0;
  20. wchar_t folder[ MAX_PATH ] = { 0 },
  21. param[ 512 ] = { 0 },
  22. *filews = 0;
  23. int zip = 0;
  24. // doing this to handle zip:// entries where there is a valid file
  25. // path included in the entry so extract it (from FFOD plugin code)
  26. lstrcpynW( param, file, 7 );
  27. if ( !lstrcmpiW( param, L"zip://" ) )
  28. {
  29. file += 6;
  30. zip = 1;
  31. }
  32. filews = file + lstrlenW( file ) - 1;
  33. if ( wcsstr( filews, L"." ) != 0 )
  34. {
  35. while ( filews && *filews && ( *filews != L'.' ) && ( filews != file ) )
  36. {
  37. filews = CharPrevW( file, filews );
  38. if ( zip && *filews == L',' )
  39. {
  40. zip = 0;
  41. }
  42. if ( zip && *filews == L'.' )
  43. {
  44. zip = 0;
  45. filews = CharPrevW( file, filews );
  46. }
  47. }
  48. }
  49. while ( filews && *filews && ( *filews != L',' && *filews != L':' && *filews != L'|' ) )
  50. filews = CharNextW( filews );
  51. if ( filews )
  52. *filews = 0;
  53. // doing this to handle foo.rsn\bar.spc so it'll just
  54. // find foo.rsn (which should then be a valid entry)
  55. filews = wcsstr( file, L".rsn\\" );
  56. if ( filews )
  57. {
  58. *( filews + 4 ) = 0;
  59. }
  60. // and now get the folder path of the file
  61. lstrcpynW( folder, file, MAX_PATH );
  62. if ( PathIsRelativeW( folder ) )
  63. {
  64. // sort out relative files based against winamp.exe
  65. wchar_t szTemp[ MAX_PATH ] = { 0 }, szTemp2[ MAX_PATH ] = { 0 };
  66. GetModuleFileNameW( hMainInstance, szTemp, sizeof( szTemp ) );
  67. PathRemoveFileSpecW( szTemp );
  68. PathCombineW( szTemp2, szTemp, folder );
  69. PathCanonicalizeW( folder, szTemp2 );
  70. // and once calculated then we copy the file back
  71. lstrcpynW( file, folder, MAX_PATH );
  72. }
  73. PathRemoveFileSpecW( folder );
  74. HRESULT hr = pDesktopFolder->ParseDisplayName( NULL, 0, folder, 0, &folderpidl, 0 );
  75. if ( FAILED( hr ) )
  76. {
  77. pDesktopFolder->Release();
  78. return FALSE;
  79. }
  80. hr = pDesktopFolder->ParseDisplayName( NULL, 0, file, 0, &filepidl, 0 );
  81. if ( FAILED( hr ) )
  82. {
  83. pDesktopFolder->Release();
  84. return FALSE;
  85. }
  86. PIDLListMap::iterator itr = pidlList.begin();
  87. for ( ; itr != pidlList.end(); itr++ )
  88. {
  89. wchar_t tmp[ MAX_PATH ] = { 0 };
  90. SHGetPathFromIDListW( itr->first, tmp );
  91. // the LPITEMIDLIST isn't consistant for all calls it seems and
  92. // so it requires doing a physical check against the folder path
  93. // rather than comparing LPITEMIDLIST values which would be nice
  94. if ( !_wcsnicmp( folder, tmp, wcslen( folder ) ) )
  95. {
  96. itr->second.push_back( filepidl );
  97. break;
  98. }
  99. }
  100. // if we got here then there was no match with the currently parsed
  101. // folder and so we need to add it to the pidllist for use later on
  102. if ( itr == pidlList.end() )
  103. {
  104. std::vector<LPCITEMIDLIST> list;
  105. list.push_back( filepidl );
  106. //PIDLListMap::MapPair p(folderpidl, list);
  107. pidlList.insert( { folderpidl, list } );
  108. }
  109. pDesktopFolder->Release();
  110. return TRUE;
  111. }
  112. return FALSE;
  113. }
  114. BOOL ExplorerFindFile::ShowFiles()
  115. {
  116. if(pidlList.size())
  117. {
  118. BOOL ret = TRUE;
  119. for (PIDLListMap::iterator itr=pidlList.begin();itr!=pidlList.end();itr++)
  120. {
  121. if(FAILED(SHOpenFolderAndSelectItems(itr->first,(UINT)itr->second.size(),itr->second.data(),NULL))){
  122. ret = FALSE;
  123. }
  124. }
  125. Reset();
  126. return ret;
  127. }
  128. return FALSE;
  129. }
  130. #ifdef CBCLASS
  131. #undef CBCLASS
  132. #endif
  133. #define CBCLASS ExplorerFindFile
  134. START_DISPATCH;
  135. CB(API_EXPLORERFINDFILE_ADDFILE, AddFile)
  136. CB(API_EXPLORERFINDFILE_SHOWFILES, ShowFiles)
  137. VCB(API_EXPLORERFINDFILE_RESET, Reset)
  138. END_DISPATCH