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