怎样实现与SHSimpleIDListFromPath同样的功能?
需要将一些特殊路径转换为PIDL,例如“D:\NUL\CON”,或者转换一个暂时不存在的路径。目前SHSimpleIDListFromPath函数可以实现,但不敢保证在未来版本的windows中可用
MSDN上介绍的另一种实现方法:
An alternative to this function is as follows:
1.Call SHGetDesktopFolder to obtain IShellFolder for the desktop folder.
2.Get the IShellFolder's bind context (IBindCtx).
3.Call IShellFolder::ParseDisplayName with the IBindCtx and the path.
但是我不知道第二步该怎样操作。英文非常菜,靠Google翻译,所以很多东西读不通也就不知道是怎么回事
[解决办法]
我哭了,这个功能真复杂。网上搜不到,只有细细的翻MSDN,总算让我翻到线索了。
你不给我分真对不起我了。
class SimpleFileSysBindData : public IFileSystemBindData{ public: SimpleFileSysBindData() : _cRef(1) { ZeroMemory( &_fd, sizeof(_fd) ); } // *** IUnknown methods *** STDMETHODIMP QueryInterface( REFIID riid, void * * ppvObj ) { if ( riid == IID_IFileSystemBindData ) { *ppvObj = static_cast<IFileSystemBindData *>(this); AddRef(); return S_OK; } else if ( riid == IID_IUnknown ) { *ppvObj = static_cast<IUnknown *>(this); AddRef(); return S_OK; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) AddRef(void) { return InterlockedIncrement(&_cRef); } STDMETHODIMP_(ULONG) Release(void) { LONG cRef = InterlockedDecrement(&_cRef); if ( !cRef ) delete this; return cRef; } // *** IFileSystemBindData Methods *** STDMETHODIMP SetFindData( WIN32_FIND_DATAW const * pfd ) { _fd = *pfd; return S_OK; } STDMETHODIMP GetFindData( WIN32_FIND_DATAW * pfd ) { *pfd = _fd; return S_OK; }private: ~SimpleFileSysBindData() { } LONG _cRef; WIN32_FIND_DATAW _fd;};static inline IUnknown * CreateFSBD( void ){ IUnknown *pI = static_cast<IFileSystemBindData *>(new SimpleFileSysBindData); return pI;}HRESULT GetSimpleIDFromPath( LPWSTR pwszPath, WIN32_FIND_DATAW * pfd, LPITEMIDLIST * ppidl ){ HRESULT hr; IUnknown * pI; IFileSystemBindData * pfsbd; pI = CreateFSBD(); hr = pI->QueryInterface( IID_IFileSystemBindData, (void * *)&pfsbd ); pI->Release(); if ( SUCCEEDED(hr) ) { if ( pfd ) { pfsbd->SetFindData(pfd); } IBindCtx * pbc; hr = CreateBindCtx( 0, &pbc ); if ( SUCCEEDED(hr) ) { hr = (pbc)->RegisterObjectParam( STR_FILE_SYS_BIND_DATA, pfsbd ); pfsbd->Release(); } else { pfsbd->Release(); return hr; } // Get the desktop folder and parse the display name. IShellFolder * pFolder; hr = SHGetDesktopFolder(&pFolder); if ( SUCCEEDED(hr) ) { hr = pFolder->ParseDisplayName( NULL, pbc, (LPOLESTR)pwszPath, NULL, ppidl, NULL ); } pFolder->Release(); pbc->Release(); } return hr;}