Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.7 KiB

  1. // class that provides the base implementation of the send to object. from here
  2. // you can override the v_DropHandler and add your own functionality.
  3. #define HINST_THISDLL g_hinst
  4. // shorthand for error code saying user requested cancel
  5. #define E_CANCELLED HRESULT_FROM_WIN32(ERROR_CANCELLED)
  6. #define MRPARAM_DOC 0x00000001
  7. #define MRPARAM_USECODEPAGE 0x00000002
  8. #define MRFILE_DELETE 0x00000001
  9. #include <shimgdata.h>
  10. typedef struct
  11. {
  12. DWORD dwFlags; // MRFILE_*
  13. LPTSTR pszFileName; // points to beginning of chBuf
  14. LPTSTR pszTitle; // points to space in chBuf after space needed for filename
  15. IStream *pStream; // If non-null release stream when deleting the structure
  16. TCHAR chBuf[1];
  17. } MRFILEENTRY;
  18. typedef struct
  19. {
  20. DWORD dwFlags; // Attributes passed to the MAPI apis
  21. MRFILEENTRY *pFiles; // List of file information
  22. DWORD cchFileEntry; // number of bytes in a single MRFILELIST entry
  23. DWORD cchFile; // number of bytes in pszFileName field of MRFILELIST entry
  24. DWORD cchTitle; // number of bytes in pszTitle field of MRFILELIST entry
  25. int nFiles; // The number of files being sent.
  26. UINT uiCodePage; // Code page
  27. } MRPARAM;
  28. /*
  29. Helper class for walking file list. Example:
  30. CFileEnum MREnum(pmp, NULL);
  31. MRFILEENTRY *pFile;
  32. while (pFile = MREnum.Next())
  33. {
  34. ... do stuff with pFile ...
  35. }
  36. */
  37. class CFileEnum
  38. {
  39. private:
  40. int _nFilesLeft;
  41. MRPARAM * _pmp;
  42. MRFILEENTRY * _pFile;
  43. IActionProgress *_pap;
  44. public:
  45. CFileEnum(MRPARAM *pmp, IActionProgress *pap)
  46. { _pmp = pmp; _pFile = NULL; _nFilesLeft = -1; _pap = NULL; IUnknown_Set((IUnknown**)&_pap, pap); }
  47. ~CFileEnum()
  48. { ATOMICRELEASE(_pap); }
  49. MRFILEENTRY * Next()
  50. {
  51. if (_nFilesLeft < 0)
  52. {
  53. _nFilesLeft = _pmp->nFiles;
  54. _pFile = _pmp->pFiles;
  55. }
  56. MRFILEENTRY *pFile = NULL;
  57. if (_nFilesLeft > 0)
  58. {
  59. pFile = _pFile;
  60. _pFile = (MRFILEENTRY *)((LPBYTE)_pFile + _pmp->cchFileEntry);
  61. --_nFilesLeft;
  62. }
  63. if (_pap)
  64. _pap->UpdateProgress(_pmp->nFiles-_nFilesLeft, _pmp->nFiles);
  65. return pFile;
  66. }
  67. };
  68. class CSendTo : public IDropTarget, IShellExtInit, IPersistFile
  69. {
  70. private:
  71. CLSID _clsid;
  72. LONG _cRef;
  73. DWORD _grfKeyStateLast;
  74. DWORD _dwEffectLast;
  75. IStorage * _pStorageTemp;
  76. TCHAR _szTempPath[MAX_PATH];
  77. BOOL _fOptionsHidden;
  78. INT _iRecompSetting;
  79. IShellItem *_psi;
  80. int _PathCleanupSpec(/*IN OPTIONAL*/ LPCTSTR pszDir, /*IN OUT*/ LPTSTR pszSpec);
  81. HRESULT _CreateShortcutToPath(LPCTSTR pszPath, LPCTSTR pszTarget);
  82. FILEDESCRIPTOR* _GetFileDescriptor(FILEGROUPDESCRIPTOR *pfgd, BOOL fUnicode, int nIndex, LPTSTR pszName);
  83. HRESULT _StreamCopyTo(IStream *pstmFrom, IStream *pstmTo, LARGE_INTEGER cb, LARGE_INTEGER *pcbRead, LARGE_INTEGER *pcbWritten);
  84. BOOL _CreateTempFileShortcut(LPCTSTR pszTarget, LPTSTR pszShortcut);
  85. HRESULT _GetFileNameFromData(IDataObject *pdtobj, FORMATETC *pfmtetc, LPTSTR pszDescription);
  86. void _GetFileAndTypeDescFromPath(LPCTSTR pszPath, LPTSTR pszDesc);
  87. HRESULT _CreateNewURLShortcut(LPCTSTR pcszURL, LPCTSTR pcszURLFile);
  88. HRESULT _CreateURLFileToSend(IDataObject *pdtobj, MRPARAM *pmp);
  89. HRESULT _GetHDROPFromData(IDataObject *pdtobj, FORMATETC *pfmtetc, STGMEDIUM *pmedium, DWORD grfKeyState, MRPARAM *pmp);
  90. HRESULT _GetURLFromData(IDataObject *pdtobj, FORMATETC *pfmtetc, STGMEDIUM *pmedium, DWORD grfKeyState, MRPARAM *pmp);
  91. HRESULT _GetFileContentsFromData(IDataObject *pdtobj, FORMATETC *pfmtetc, STGMEDIUM *pmedium, DWORD grfKeyState, MRPARAM *pmp);
  92. HRESULT _GetTempStorage(IStorage **ppStorage);
  93. void _CollapseOptions(HWND hwnd, BOOL fHide);
  94. static BOOL_PTR s_ConfirmDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  95. BOOL_PTR _ConfirmDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  96. protected:
  97. BOOL AllocatePMP(MRPARAM *pmp, DWORD cchTitle, DWORD cchFiles);
  98. BOOL CleanupPMP(MRPARAM *pmp);
  99. HRESULT FilterPMP(MRPARAM *pmp);
  100. HRESULT CreateSendToFilesFromDataObj(IDataObject *pdtobj, DWORD grfKeyState, MRPARAM *pmp);
  101. // Virtual drop method implemented by derived object
  102. virtual HRESULT v_DropHandler(IDataObject *pdtobj, DWORD grfKeyState, DWORD dwEffect) PURE;
  103. public:
  104. CSendTo(CLSID clsid);
  105. virtual ~CSendTo();
  106. // IUnknown
  107. STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
  108. STDMETHOD_(ULONG, AddRef)();
  109. STDMETHOD_(ULONG, Release)();
  110. // IShellExtInit
  111. STDMETHODIMP Initialize(LPCITEMIDLIST pidlFolder, IDataObject *lpdobj, HKEY hkeyProgID)
  112. { return S_OK; };
  113. // IDropTarget
  114. STDMETHOD(DragEnter)(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  115. STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  116. STDMETHODIMP DragLeave()
  117. { return S_OK; }
  118. STDMETHOD(Drop)(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  119. // IPersist
  120. STDMETHODIMP GetClassID(CLSID *pClassID)
  121. { *pClassID = _clsid; return S_OK; };
  122. // IPersistFile
  123. STDMETHODIMP IsDirty(void)
  124. { return S_FALSE; };
  125. STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode)
  126. { return S_OK; };
  127. STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
  128. { return S_OK; };
  129. STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
  130. { return S_OK; };
  131. STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName)
  132. { *ppszFileName = NULL; return S_OK; };
  133. };