ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

shellclasses.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004, 2005 Martin Fuchs
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 
00019 
00020  //
00021  // Explorer clone
00022  //
00023  // shellclasses.h
00024  //
00025  // C++ wrapper classes for COM interfaces and shell objects
00026  //
00027  // Martin Fuchs, 20.07.2003
00028  //
00029 
00030 
00031  // windows shell headers
00032 #include <shellapi.h>
00033 #include <shlobj.h>
00034 
00035 /*@@
00036 #if _MSC_VER>=1300  // VS.Net
00037 #include <comdefsp.h>
00038 using namespace _com_util;
00039 #endif
00040 */
00041 
00042 #ifndef _INC_COMUTIL    // is comutil.h of MS headers not available?
00043 #ifndef _NO_COMUTIL
00044 #define _NO_COMUTIL
00045 #endif
00046 #endif
00047 
00048  // work around GCC's wide string constant bug when compiling inline functions
00049 #ifdef __GNUC__
00050 extern const LPCTSTR sCFSTR_SHELLIDLIST;
00051 #undef CFSTR_SHELLIDLIST
00052 #define CFSTR_SHELLIDLIST sCFSTR_SHELLIDLIST
00053 #endif
00054 
00055 #ifdef _MSC_VER
00056 #define NOVTABLE __declspec(novtable)
00057 #else
00058 #define NOVTABLE
00059 #endif
00060 #define ANSUNC
00061 
00062 
00063  // Exception Handling
00064 
00065 #ifndef _NO_COMUTIL
00066 
00067 #define COMExceptionBase _com_error
00068 
00069 #else
00070 
00072 struct COMExceptionBase
00073 {
00074     COMExceptionBase(HRESULT hr)
00075      :  _hr(hr)
00076     {
00077     }
00078 
00079     HRESULT Error() const
00080     {
00081         return _hr;
00082     }
00083 
00084     LPCTSTR ErrorMessage() const
00085     {
00086         if (_msg.empty()) {
00087             LPTSTR pBuf;
00088 
00089             if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
00090                 0, _hr, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR)&pBuf, 0, NULL)) {
00091                 _msg = pBuf;
00092                 LocalFree(pBuf);
00093              } else {
00094                 TCHAR buffer[128];
00095                 _sntprintf(buffer, COUNTOF(buffer), TEXT("unknown Exception: 0x%08lX"), _hr);
00096                 _msg = buffer;
00097              }
00098         }
00099 
00100         return _msg;
00101     }
00102 
00103 protected:
00104     HRESULT _hr;
00105     mutable String _msg;
00106 };
00107 
00108 #endif
00109 
00110 
00112 
00113 struct COMException : public COMExceptionBase
00114 {
00115     typedef COMExceptionBase super;
00116 
00117     COMException(HRESULT hr)
00118      :  super(hr),
00119         _context(CURRENT_CONTEXT),
00120         _file(NULL), _line(0)
00121     {
00122         LOG(toString());
00123         LOG(CURRENT_CONTEXT.getStackTrace());
00124     }
00125 
00126     COMException(HRESULT hr, const char* file, int line)
00127      :  super(hr),
00128         _context(CURRENT_CONTEXT),
00129         _file(file), _line(line)
00130     {
00131         LOG(toString());
00132         LOG(CURRENT_CONTEXT.getStackTrace());
00133     }
00134 
00135     COMException(HRESULT hr, const String& obj)
00136      :  super(hr),
00137         _context(CURRENT_CONTEXT),
00138         _file(NULL), _line(0)
00139     {
00140         LOG(toString());
00141         LOG(CURRENT_CONTEXT.getStackTrace());
00142     }
00143 
00144     COMException(HRESULT hr, const String& obj, const char* file, int line)
00145      :  super(hr),
00146         _context(CURRENT_CONTEXT),
00147         _file(file), _line(line)
00148     {
00149         LOG(toString());
00150         LOG(CURRENT_CONTEXT.getStackTrace());
00151     }
00152 
00153     String toString() const;
00154 
00155     Context _context;
00156 
00157     const char* _file;
00158     int _line;
00159 };
00160 
00161 #define THROW_EXCEPTION(hr) throw COMException(hr, __FILE__, __LINE__)
00162 #define CHECKERROR(hr) ((void)(FAILED(hr)? THROW_EXCEPTION(hr): 0))
00163 
00164 
00165 #ifdef _NO_COMUTIL
00166 
00167 inline void CheckError(HRESULT hr)
00168 {
00169     if (FAILED(hr))
00170         throw COMException(hr);
00171 }
00172 
00173 #endif
00174 
00175 
00177 
00178 struct ComInit
00179 {
00180     ComInit()
00181     {
00182         CHECKERROR(CoInitialize(0));
00183     }
00184 
00185 #if (_WIN32_WINNT>=0x0400) || defined(_WIN32_DCOM)
00186     ComInit(DWORD flag)
00187     {
00188         CHECKERROR(CoInitializeEx(0, flag));
00189     }
00190 #endif
00191 
00192     ~ComInit()
00193     {
00194         CoUninitialize();
00195     }
00196 };
00197 
00198 
00200 
00201 struct OleInit
00202 {
00203     OleInit()
00204     {
00205         CHECKERROR(OleInitialize(0));
00206     }
00207 
00208     ~OleInit()
00209     {
00210         OleUninitialize();
00211     }
00212 };
00213 
00214 
00216 
00217 extern void HandleException(COMException& e, HWND hwnd);
00218 
00219 
00221 
00222 struct CommonShellMalloc
00223 {
00224     CommonShellMalloc()
00225     {
00226         _p = NULL;
00227     }
00228 
00229     void init()
00230     {
00231         if (!_p)
00232             CHECKERROR(SHGetMalloc(&_p));
00233     }
00234 
00235     ~CommonShellMalloc()
00236     {
00237         if (_p)
00238             _p->Release();
00239     }
00240 
00241     operator IMalloc*()
00242     {
00243         return _p;
00244     }
00245 
00246     IMalloc* _p;
00247 };
00248 
00249 
00251 
00252 struct ShellMalloc
00253 {
00254     ShellMalloc()
00255     {
00256          // initialize s_cmn_shell_malloc
00257         s_cmn_shell_malloc.init();
00258     }
00259 
00260     IMalloc* operator->()
00261     {
00262         return s_cmn_shell_malloc;
00263     }
00264 
00265     static CommonShellMalloc s_cmn_shell_malloc;
00266 };
00267 
00268 
00270 
00271 template<typename T> struct SShellPtr
00272 {
00273     ~SShellPtr()
00274     {
00275         _malloc->Free(_p);
00276     }
00277 
00278     T* operator->()
00279     {
00280         return _p;
00281     }
00282 
00283     T const* operator->() const
00284     {
00285         return _p;
00286     }
00287 
00288     operator T const *() const
00289     {
00290         return _p;
00291     }
00292 
00293     const T& operator*() const
00294     {
00295         return *_p;
00296     }
00297 
00298     T& operator*()
00299     {
00300         return *_p;
00301     }
00302 
00303 protected:
00304     SShellPtr()
00305      :  _p(0)
00306     {
00307     }
00308 
00309     SShellPtr(T* p)
00310      :  _p(p)
00311     {
00312     }
00313 
00314     void Free()
00315     {
00316         _malloc->Free(_p);
00317         _p = NULL;
00318     }
00319 
00320     T* _p;
00321     mutable ShellMalloc _malloc;    // IMalloc memory management object
00322 
00323 private:
00324      // disallow copying of SShellPtr objects
00325     SShellPtr(const SShellPtr&) {}
00326     void operator=(SShellPtr const&) {}
00327 };
00328 
00329 
00331 
00332 template<typename T> struct SIfacePtr
00333 {
00334     SIfacePtr()
00335      :  _p(0)
00336     {
00337     }
00338 
00339     SIfacePtr(T* p)
00340      :  _p(p)
00341     {
00342         if (p)
00343             p->AddRef();
00344     }
00345 
00346     SIfacePtr(IUnknown* unknown, REFIID riid)
00347     {
00348         CHECKERROR(unknown->QueryInterface(riid, (LPVOID*)&_p));
00349     }
00350 
00351     ~SIfacePtr()
00352     {
00353         Free();
00354     }
00355 
00356     T* operator->()
00357     {
00358         return _p;
00359     }
00360 
00361     const T* operator->() const
00362     {
00363         return _p;
00364     }
00365 
00366 /* not GCC compatible
00367     operator const T*() const
00368     {
00369         return _p;
00370     } */
00371 
00372     operator T*()
00373     {
00374         return _p;
00375     }
00376 
00377     T** operator&()
00378     {
00379         return &_p;
00380     }
00381 
00382     bool empty() const  //NOTE: GCC seems not to work correctly when defining operator bool() AND operator T*() at one time
00383     {
00384         return !_p;
00385     }
00386 
00387     SIfacePtr& operator=(T* p)
00388     {
00389         Free();
00390 
00391         if (p) {
00392             p->AddRef();
00393             _p = p;
00394         }
00395 
00396         return *this;
00397     }
00398 
00399     void operator=(SIfacePtr const& o)
00400     {
00401         T* h = _p;
00402 
00403         if (o._p)
00404             o._p->AddRef();
00405 
00406         _p = o._p;
00407 
00408         if (h)
00409             h->Release();
00410     }
00411 
00412     HRESULT CreateInstance(REFIID clsid, REFIID riid)
00413     {
00414         return CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&_p);
00415     }
00416 
00417     template<typename I> HRESULT QueryInterface(REFIID riid, I* p)
00418     {
00419         return _p->QueryInterface(riid, (LPVOID*)p);
00420     }
00421 
00422     T* get()
00423     {
00424         return _p;
00425     }
00426 
00427     void Free()
00428     {
00429         T* h = _p;
00430         _p = NULL;
00431 
00432         if (h)
00433             h->Release();
00434     }
00435 
00436 protected:
00437     SIfacePtr(const SIfacePtr& o)
00438      :  _p(o._p)
00439     {
00440         if (_p)
00441             _p->AddRef();
00442     }
00443 
00444     T* _p;
00445 };
00446 
00447 
00448 struct NOVTABLE ComSrvObject    // NOVTABLE erlaubt, da protected Destruktor
00449 {
00450 protected:
00451     ComSrvObject() : _ref(1) {}
00452     virtual ~ComSrvObject() {}
00453 
00454     ULONG   _ref;
00455 };
00456 
00457 struct SimpleComObject : public ComSrvObject
00458 {
00459     ULONG IncRef() {return ++_ref;}
00460     ULONG DecRef() {ULONG ref=--_ref; if (!ref) {_ref++; delete this;} return ref;}
00461 };
00462 
00463 
00464  // server object interfaces
00465 
00466 template<typename BASE> struct IComSrvQI : public BASE
00467 {
00468     IComSrvQI(REFIID uuid_base)
00469      :  _uuid_base(uuid_base)
00470     {
00471     }
00472 
00473     STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv)
00474     {
00475         *ppv = NULL;
00476 
00477         if (IsEqualIID(riid, _uuid_base) || IsEqualIID(riid, IID_IUnknown))
00478             {*ppv=static_cast<BASE*>(this); this->AddRef(); return S_OK;}
00479 
00480         return E_NOINTERFACE;
00481     }
00482 
00483 protected:
00484     IComSrvQI() {}
00485     virtual ~IComSrvQI() {}
00486 
00487     REFIID  _uuid_base;
00488 };
00489 
00490 template<> struct IComSrvQI<IUnknown> : public IUnknown
00491 {
00492     STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv)
00493     {
00494         *ppv = NULL;
00495 
00496         if (IsEqualIID(riid, IID_IUnknown))
00497             {*ppv=this; AddRef(); return S_OK;}
00498 
00499         return E_NOINTERFACE;
00500     }
00501 
00502 protected:
00503     IComSrvQI<IUnknown>() {}
00504     virtual ~IComSrvQI<IUnknown>() {}
00505 };
00506 
00507 
00508 template<typename BASE, typename OBJ>
00509     class IComSrvBase : public IComSrvQI<BASE>
00510 {
00511     typedef IComSrvQI<BASE> super;
00512 
00513 protected:
00514     IComSrvBase(REFIID uuid_base)
00515      :  super(uuid_base)
00516     {
00517     }
00518 
00519 public:
00520     STDMETHODIMP_(ULONG) AddRef() {return static_cast<OBJ*>(this)->IncRef();}
00521     STDMETHODIMP_(ULONG) Release() {return static_cast<OBJ*>(this)->DecRef();}
00522 };
00523 
00524 
00525 
00526 struct ShellFolder;
00527 
00528 
00530 
00531 struct CommonDesktop
00532 {
00533     CommonDesktop()
00534     {
00535         _desktop = 0;
00536     }
00537 
00538     ~CommonDesktop();
00539 
00540     void init();
00541 
00542     operator ShellFolder&()
00543     {
00544         return *_desktop;
00545     }
00546 
00547 protected:
00548     ShellFolder* _desktop;
00549 };
00550 
00551 
00552 #ifndef _NO_COMUTIL // _com_ptr available?
00553 
00555 struct ShellFolder : public IShellFolderPtr // IShellFolderPtr uses intrinsic extensions of the VC++ compiler.
00556 {
00557     typedef IShellFolderPtr super;
00558 
00559     ShellFolder();  // desktop folder
00560     ShellFolder(IShellFolder* p);
00561     ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl);
00562     ShellFolder(LPCITEMIDLIST pidl);
00563 
00564     void    attach(IShellFolder* parent, LPCITEMIDLIST pidl);
00565     String  get_name(LPCITEMIDLIST pidl=NULL, SHGDNF flags=SHGDN_NORMAL) const;
00566 
00567     bool    empty() const {return !operator bool();}    //NOTE: see SIfacePtr::empty()
00568 };
00569 
00570 #ifdef UNICODE
00571 #define IShellLinkPtr IShellLinkWPtr
00572 #else
00573 #define IShellLinkPtr IShellLinkAPtr
00574 #endif
00575 
00577 struct ShellLinkPtr : public IShellLinkPtr
00578 {
00579     typedef IShellLinkPtr super;
00580 
00581     ShellLinkPtr(IShellLink* p)
00582      :  super(p)
00583     {
00584         p->AddRef();
00585     }
00586 
00587     bool    empty() const {return !operator bool();}    //NOTE: see SIfacePtr::empty()
00588 };
00589 
00590 #else // _com_ptr not available -> use SIfacePtr
00591 
00593 struct ShellFolder : public SIfacePtr<IShellFolder>
00594 {
00595     typedef SIfacePtr<IShellFolder> super;
00596 
00597     ShellFolder();
00598     ShellFolder(IShellFolder* p);
00599     ShellFolder(IShellFolder* parent, LPCITEMIDLIST pidl);
00600     ShellFolder(LPCITEMIDLIST pidl);
00601 
00602     void    attach(IShellFolder* parent, LPCITEMIDLIST pidl);
00603     String  get_name(LPCITEMIDLIST pidl, SHGDNF flags=SHGDN_NORMAL) const;
00604 };
00605 
00607 struct ShellLinkPtr : public SIfacePtr<IShellLink>
00608 {
00609     typedef SIfacePtr<IShellLink> super;
00610 
00611     ShellLinkPtr(IShellLink* p)
00612      :  super(p)
00613     {
00614         _p->AddRef();
00615     }
00616 
00617 };
00618 
00619 #endif
00620 
00621 
00622 extern ShellFolder& GetDesktopFolder();
00623 
00624 
00625 #ifdef UNICODE
00626 #define path_from_pidl path_from_pidlW
00627 #else
00628 #define path_from_pidl path_from_pidlA
00629 #endif
00630 
00631 extern HRESULT path_from_pidlA(IShellFolder* folder, LPCITEMIDLIST pidl, LPSTR buffer, int len);
00632 extern HRESULT path_from_pidlW(IShellFolder* folder, LPCITEMIDLIST pidl, LPWSTR buffer, int len);
00633 extern HRESULT name_from_pidl(IShellFolder* folder, LPCITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags);
00634 
00635 
00636  // ILGetSize() was missing in previous versions of MinGW and is not exported from shell32.dll on Windows 2000.
00637 extern "C" UINT ILGetSize_local(LPCITEMIDLIST pidl);
00638 #define ILGetSize ILGetSize_local
00639 
00640 #if 0
00641 #ifdef UNICODE      // CFSTR_FILENAME was defined wrong in previous versions of MinGW.
00642 #define CFSTR_FILENAMEW TEXT("FileNameW")
00643 #undef CFSTR_FILENAME
00644 #define CFSTR_FILENAME CFSTR_FILENAMEW
00645 #endif
00646 #endif
00647 
00648 
00650 
00651 struct ShellPath : public SShellPtr<ITEMIDLIST>
00652 {
00653     typedef SShellPtr<ITEMIDLIST> super;
00654 
00655     ShellPath()
00656     {
00657     }
00658 
00659     ShellPath(IShellFolder* folder, LPCWSTR path)
00660     {
00661         CONTEXT("ShellPath::ShellPath(IShellFolder*, LPCWSTR)");
00662 
00663         if (path)
00664             CHECKERROR(folder->ParseDisplayName(0, NULL, (LPOLESTR)path, NULL, &_p, NULL));
00665         else
00666             _p = NULL;
00667     }
00668 
00669     ShellPath(LPCWSTR path)
00670     {
00671         OBJ_CONTEXT("ShellPath::ShellPath(LPCWSTR)", path);
00672 
00673         if (path)
00674             CHECKERROR(GetDesktopFolder()->ParseDisplayName(0, NULL, (LPOLESTR)path, NULL, &_p, NULL));
00675         else
00676             _p = NULL;
00677     }
00678 
00679     ShellPath(IShellFolder* folder, LPCSTR path)
00680     {
00681         CONTEXT("ShellPath::ShellPath(IShellFolder*, LPCSTR)");
00682 
00683         WCHAR b[MAX_PATH];
00684 
00685         if (path) {
00686             MultiByteToWideChar(CP_ACP, 0, path, -1, b, COUNTOF(b));
00687             CHECKERROR(folder->ParseDisplayName(0, NULL, b, NULL, &_p, NULL));
00688         } else
00689             _p = NULL;
00690     }
00691 
00692     ShellPath(LPCSTR path)
00693     {
00694         CONTEXT("ShellPath::ShellPath(LPCSTR)");
00695 
00696         WCHAR b[MAX_PATH];
00697 
00698         if (path) {
00699             MultiByteToWideChar(CP_ACP, 0, path, -1, b, COUNTOF(b));
00700             CHECKERROR(GetDesktopFolder()->ParseDisplayName(0, NULL, b, NULL, &_p, NULL));
00701         } else
00702             _p = NULL;
00703     }
00704 
00705     ShellPath(const ShellPath& o)
00706      :  super(NULL)
00707     {
00708         //CONTEXT("ShellPath::ShellPath(const ShellPath&)");
00709 
00710         if (o._p) {
00711             int l = ILGetSize(o._p);
00712             _p = (ITEMIDLIST*) _malloc->Alloc(l);
00713             if (_p) memcpy(_p, o._p, l);
00714         }
00715     }
00716 
00717     explicit ShellPath(LPITEMIDLIST p)
00718      :  super(p)
00719     {
00720     }
00721 
00722     ShellPath(LPCITEMIDLIST p)
00723     {
00724         //CONTEXT("ShellPath::ShellPath(LPCITEMIDLIST)");
00725 
00726         if (p) {
00727             int l = ILGetSize(p);
00728             _p = (ITEMIDLIST*) _malloc->Alloc(l);
00729             if (_p) memcpy(_p, p, l);
00730         }
00731     }
00732 
00733     void operator=(const ShellPath& o)
00734     {
00735         //CONTEXT("ShellPath::operator=(const ShellPath&)");
00736 
00737         ITEMIDLIST* h = _p;
00738 
00739         if (o._p) {
00740             int l = ILGetSize(o._p);
00741 
00742             _p = (ITEMIDLIST*) _malloc->Alloc(l);
00743             if (_p) memcpy(_p, o._p, l);
00744         }
00745         else
00746             _p = NULL;
00747 
00748         _malloc->Free(h);
00749     }
00750 
00751     void operator=(ITEMIDLIST* p)
00752     {
00753         //CONTEXT("ShellPath::operator=(ITEMIDLIST*)");
00754 
00755         ITEMIDLIST* h = _p;
00756 
00757         if (p) {
00758             int l = ILGetSize(p);
00759             _p = (ITEMIDLIST*) _malloc->Alloc(l);
00760             if (_p) memcpy(_p, p, l);
00761         }
00762         else
00763             _p = NULL;
00764 
00765         _malloc->Free(h);
00766     }
00767 
00768     void operator=(const SHITEMID& o)
00769     {
00770         ITEMIDLIST* h = _p;
00771 
00772         LPBYTE p = (LPBYTE)_malloc->Alloc(o.cb+2);
00773         if (p) *(PWORD)((LPBYTE)memcpy(p, &o, o.cb)+o.cb) = 0;
00774         _p = (ITEMIDLIST*)p;
00775 
00776         _malloc->Free(h);
00777     }
00778 
00779     void operator+=(const SHITEMID& o)
00780     {
00781         int l0 = ILGetSize(_p);
00782         LPBYTE p = (LPBYTE)_malloc->Alloc(l0+o.cb);
00783         int l = l0 - 2;
00784 
00785         if (p) {
00786             memcpy(p, _p, l);
00787             *(PWORD)((LPBYTE)memcpy(p+l, &o, o.cb)+o.cb) = 0;
00788         }
00789 
00790         _malloc->Free(_p);
00791         _p = (ITEMIDLIST*)p;
00792     }
00793 
00794     friend bool operator<(const ShellPath& a, const ShellPath& b)
00795     {
00796         int la = ILGetSize(a._p);
00797         int lb = ILGetSize(b._p);
00798 
00799         int r = memcmp(a._p, b._p, min(la, lb));
00800         if (r)
00801             return r < 0;
00802         else
00803             return la < lb;
00804     }
00805 
00806     void assign(LPCITEMIDLIST pidl, size_t size)
00807     {
00808         //CONTEXT("ShellPath::assign(LPCITEMIDLIST, size_t)");
00809 
00810         ITEMIDLIST* h = _p;
00811 
00812         _p = (ITEMIDLIST*) _malloc->Alloc(size+sizeof(USHORT/*SHITEMID::cb*/));
00813 
00814         if (_p) {
00815             memcpy(_p, pidl, size);
00816             ((ITEMIDLIST*)((LPBYTE)_p+size))->mkid.cb = 0; // terminator
00817         }
00818 
00819         _malloc->Free(h);
00820     }
00821 
00822     void assign(LPCITEMIDLIST pidl)
00823     {
00824         //CONTEXT("ShellPath::assign(LPCITEMIDLIST)");
00825 
00826         ITEMIDLIST* h = _p;
00827 
00828         if (pidl) {
00829             int l = ILGetSize(pidl);
00830             _p = (ITEMIDLIST*) _malloc->Alloc(l);
00831             if (_p) memcpy(_p, pidl, l);
00832         } else
00833             _p = NULL;
00834 
00835         _malloc->Free(h);
00836     }
00837 
00838     void split(ShellPath& parent, ShellPath& obj) const;
00839 
00840     void GetUIObjectOf(REFIID riid, LPVOID* ppvOut, HWND hWnd=0, ShellFolder& sf=GetDesktopFolder());
00841 
00842     ShellFolder get_folder()
00843     {
00844         return ShellFolder(_p);
00845     }
00846 
00847     ShellFolder get_folder(IShellFolder* parent)
00848     {
00849         CONTEXT("ShellPath::get_folder()");
00850         return ShellFolder(parent, _p);
00851     }
00852 
00853      // convert an item id list from relative to absolute (=relative to the desktop) format
00854     ShellPath create_absolute_pidl(LPCITEMIDLIST parent_pidl) const;
00855 };
00856 
00857 
00858 #if defined(__WINE__) && defined(NONAMELESSUNION)   // Wine doesn't know of unnamed union members and uses some macros instead.
00859 #define UNION_MEMBER(x) DUMMYUNIONNAME.##x
00860 #else
00861 #define UNION_MEMBER(x) x
00862 #endif
00863 
00864 
00865  // encapsulation of STRRET structure for easy string retrieval with conversion
00866 
00867 #ifdef UNICODE
00868 #define StrRet StrRetW
00869 //#define   tcscpyn wcscpyn
00870 #else
00871 #define StrRet StrRetA
00872 //#define   tcscpyn strcpyn
00873 #endif
00874 
00875 //extern LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count);
00876 //extern LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count);
00877 
00879 struct StrRetA : public STRRET
00880 {
00881     ~StrRetA()
00882     {
00883         if (uType == STRRET_WSTR)
00884             ShellMalloc()->Free(pOleStr);
00885     }
00886 
00887     void GetString(const SHITEMID& shiid, LPSTR b, int l)
00888     {
00889         switch(uType) {
00890           case STRRET_WSTR:
00891             WideCharToMultiByte(CP_ACP, 0, UNION_MEMBER(pOleStr), -1, b, l, NULL, NULL);
00892             break;
00893 
00894           case STRRET_OFFSET:
00895             lstrcpynA(b, (LPCSTR)&shiid+UNION_MEMBER(uOffset), l);
00896             break;
00897 
00898           case STRRET_CSTR:
00899             lstrcpynA(b, UNION_MEMBER(cStr), l);
00900         }
00901     }
00902 };
00903 
00905 struct StrRetW : public STRRET
00906 {
00907     ~StrRetW()
00908     {
00909         if (uType == STRRET_WSTR)
00910             ShellMalloc()->Free(pOleStr);
00911     }
00912 
00913     void GetString(const SHITEMID& shiid, LPWSTR b, int l)
00914     {
00915         switch(uType) {
00916           case STRRET_WSTR:
00917             lstrcpynW(b, UNION_MEMBER(pOleStr), l);
00918             break;
00919 
00920           case STRRET_OFFSET:
00921             MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&shiid+UNION_MEMBER(uOffset), -1, b, l);
00922             break;
00923 
00924           case STRRET_CSTR:
00925             MultiByteToWideChar(CP_ACP, 0, UNION_MEMBER(cStr), -1, b, l);
00926         }
00927     }
00928 };
00929 
00930 
00932 class FileSysShellPath : public ShellPath
00933 {
00934     TCHAR   _fullpath[MAX_PATH];
00935 
00936 protected:
00937     FileSysShellPath() {_fullpath[0] = '\0';}
00938 
00939 public:
00940     FileSysShellPath(const ShellPath& o) : ShellPath(o) {_fullpath[0] = '\0';}
00941 
00942     operator LPCTSTR() {if (!SHGetPathFromIDList(_p, _fullpath)) return NULL; return _fullpath;}
00943 };
00944 
00945 
00947 struct FolderBrowser : public FileSysShellPath
00948 {
00949     FolderBrowser(HWND owner, UINT flags, LPCTSTR title, LPCITEMIDLIST root=0)
00950     {
00951         _displayname[0] = '\0';
00952         _browseinfo.hwndOwner = owner;
00953         _browseinfo.pidlRoot = root;
00954         _browseinfo.pszDisplayName = _displayname;
00955         _browseinfo.lpszTitle = title;
00956         _browseinfo.ulFlags = flags;
00957         _browseinfo.lpfn = 0;
00958         _browseinfo.lParam = 0;
00959         _browseinfo.iImage = 0;
00960 
00961         _p = SHBrowseForFolder(&_browseinfo);
00962     }
00963 
00964     LPCTSTR GetDisplayName()
00965     {
00966         return _displayname;
00967     }
00968 
00969     bool IsOK()
00970     {
00971         return _p != 0;
00972     }
00973 
00974 private:
00975     BROWSEINFO _browseinfo;
00976     TCHAR   _displayname[MAX_PATH];
00977 };
00978 
00979 
00981 struct SpecialFolderPath : public ShellPath
00982 {
00983     SpecialFolderPath(int folder, HWND hwnd)
00984     {
00985         HRESULT hr = SHGetSpecialFolderLocation(hwnd, folder, &_p);
00986         CHECKERROR(hr);
00987     }
00988 };
00989 
00991 struct DesktopFolderPath : public SpecialFolderPath
00992 {
00993     DesktopFolderPath()
00994      :  SpecialFolderPath(CSIDL_DESKTOP, 0)
00995     {
00996     }
00997 };
00998 
01000 struct SpecialFolder : public ShellFolder
01001 {
01002     SpecialFolder(int folder, HWND hwnd)
01003      :  ShellFolder(GetDesktopFolder(), SpecialFolderPath(folder, hwnd))
01004     {
01005     }
01006 };
01007 
01009 struct DesktopFolder : public ShellFolder
01010 {
01011 };
01012 
01013 
01015 struct SpecialFolderFSPath
01016 {
01017     SpecialFolderFSPath(int folder/*e.g. CSIDL_DESKTOP*/, HWND hwnd);
01018 
01019     operator LPCTSTR()
01020     {
01021         return _fullpath;
01022     }
01023 
01024 protected:
01025     TCHAR   _fullpath[MAX_PATH];
01026 };
01027 
01028 /*
01030 struct SpecialFolderFSPath : public FileSysShellPath
01031 {
01032     SpecialFolderFSPath(int folder, HWND hwnd)
01033     {
01034         CONTEXT("SpecialFolderFSPath::SpecialFolderFSPath()");
01035 
01036         HRESULT hr = SHGetSpecialFolderLocation(hwnd, folder, &_p);
01037         CHECKERROR(hr);
01038     }
01039 };
01040 */
01041 
01042 
01044 
01045 struct ShellItemEnumerator : public SIfacePtr<IEnumIDList>
01046 {
01047     ShellItemEnumerator(IShellFolder* folder, DWORD flags=SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN)
01048     {
01049         CONTEXT("ShellItemEnumerator::ShellItemEnumerator()");
01050 
01051         CHECKERROR(folder->EnumObjects(0, flags, &_p));
01052     }
01053 };
01054 
01055 
01057 struct PIDList
01058 {
01059     PIDList()
01060     {
01061         memset(&_stgm, 0, sizeof(STGMEDIUM));
01062     }
01063 
01064     ~PIDList()
01065     {
01066         if (_stgm.hGlobal) {
01067             GlobalUnlock(_stgm.hGlobal);
01068             ReleaseStgMedium(&_stgm);
01069         }
01070     }
01071 
01072     HRESULT GetData(IDataObject* selection)
01073     {
01074         static UINT CF_IDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
01075 
01076         FORMATETC fetc;
01077         fetc.cfFormat = CF_IDLIST;
01078         fetc.ptd = NULL;
01079         fetc.dwAspect = DVASPECT_CONTENT;
01080         fetc.lindex = -1;
01081         fetc.tymed = TYMED_HGLOBAL;
01082 
01083         HRESULT hr = selection->QueryGetData(&fetc);
01084         if (FAILED(hr))
01085             return hr;
01086 
01087         hr = selection->GetData(&fetc, &_stgm);
01088         if (FAILED(hr))
01089             return hr;
01090 
01091         _pIDList = (LPIDA)GlobalLock(_stgm.hGlobal);
01092 
01093         return hr;
01094     }
01095 
01096     operator LPIDA() {return _pIDList;}
01097 
01098 protected:
01099     STGMEDIUM _stgm;
01100     LPIDA _pIDList;
01101 };
01102 
01103 
01104 struct CtxMenuInterfaces
01105 {
01106     CtxMenuInterfaces()
01107     {
01108         reset();
01109     }
01110 
01111     void    reset();
01112     bool    HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam);
01113     IContextMenu* query_interfaces(IContextMenu* pcm1);
01114 
01115     IContextMenu2*  _pctxmenu2;
01116 
01117 #ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
01118     IContextMenu3*  _pctxmenu3;
01119 #endif
01120 };
01121 
01122 template<typename BASE> struct ExtContextMenuHandlerT
01123  : public BASE
01124 {
01125     typedef BASE super;
01126 
01127     ExtContextMenuHandlerT(HWND hwnd)
01128      :  super(hwnd)
01129     {
01130     }
01131 
01132     template<typename PARA> ExtContextMenuHandlerT(HWND hwnd, const PARA& info)
01133      :  super(hwnd, info)
01134     {
01135     }
01136 
01137     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
01138     {
01139         switch(nmsg) {
01140           case WM_DRAWITEM:
01141           case WM_MEASUREITEM:
01142             if (!wparam)    // Is the message menu-related?
01143                 if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam))
01144                     return TRUE;
01145 
01146             break;
01147 
01148           case WM_INITMENUPOPUP:
01149             if (_cm_ifs.HandleMenuMsg(nmsg, wparam, lparam))
01150                 return 0;
01151 
01152             break;
01153 
01154 #ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
01155           case WM_MENUCHAR: // only supported by IContextMenu3
01156            if (_cm_ifs._pctxmenu3) {
01157                LRESULT lResult = 0;
01158 
01159                _cm_ifs._pctxmenu3->HandleMenuMsg2(nmsg, wparam, lparam, &lResult);
01160 
01161                return lResult;
01162            }
01163 
01164            return 0;
01165 #endif
01166         }
01167 
01168         return super::WndProc(nmsg, wparam, lparam);
01169     }
01170 
01171 protected:
01172     CtxMenuInterfaces _cm_ifs;
01173 };
01174 
01175 
01176 extern HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl,
01177                                         LPCITEMIDLIST* ppidl, int x, int y, CtxMenuInterfaces& cm_ifs);

Generated on Sun May 27 2012 04:18:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.