|
|
@@ -30,27 +30,27 @@ extern long g_cDllRef;
|
|
|
|
|
|
|
|
|
OCContextMenu::OCContextMenu(void)
|
|
|
- : m_cRef(1)
|
|
|
- , m_pszMenuText(L"&Share")
|
|
|
- , m_pszVerb("ocshare")
|
|
|
- , m_pwszVerb(L"ocshare")
|
|
|
- , m_pszVerbCanonicalName("OCShareViaOC")
|
|
|
- , m_pwszVerbCanonicalName(L"OCShareViaOC")
|
|
|
- , m_pszVerbHelpText("Share via ownCloud")
|
|
|
- , m_pwszVerbHelpText(L"Share via ownCloud")
|
|
|
+ : m_cRef(1)
|
|
|
+ , m_pszMenuText(L"&Share")
|
|
|
+ , m_pszVerb("ocshare")
|
|
|
+ , m_pwszVerb(L"ocshare")
|
|
|
+ , m_pszVerbCanonicalName("OCShareViaOC")
|
|
|
+ , m_pwszVerbCanonicalName(L"OCShareViaOC")
|
|
|
+ , m_pszVerbHelpText("Share via ownCloud")
|
|
|
+ , m_pwszVerbHelpText(L"Share via ownCloud")
|
|
|
{
|
|
|
- InterlockedIncrement(&g_cDllRef);
|
|
|
+ InterlockedIncrement(&g_cDllRef);
|
|
|
}
|
|
|
|
|
|
OCContextMenu::~OCContextMenu(void)
|
|
|
{
|
|
|
- InterlockedDecrement(&g_cDllRef);
|
|
|
+ InterlockedDecrement(&g_cDllRef);
|
|
|
}
|
|
|
|
|
|
|
|
|
void OCContextMenu::OnVerbDisplayFileName(HWND hWnd)
|
|
|
{
|
|
|
- OCClientInterface::ShareObject(std::wstring(m_szSelectedFile));
|
|
|
+ OCClientInterface::ShareObject(std::wstring(m_szSelectedFile));
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -59,30 +59,30 @@ void OCContextMenu::OnVerbDisplayFileName(HWND hWnd)
|
|
|
// Query to the interface the component supported.
|
|
|
IFACEMETHODIMP OCContextMenu::QueryInterface(REFIID riid, void **ppv)
|
|
|
{
|
|
|
- static const QITAB qit[] =
|
|
|
- {
|
|
|
- QITABENT(OCContextMenu, IContextMenu),
|
|
|
- QITABENT(OCContextMenu, IShellExtInit),
|
|
|
- { 0 },
|
|
|
- };
|
|
|
- return QISearch(this, qit, riid, ppv);
|
|
|
+ static const QITAB qit[] =
|
|
|
+ {
|
|
|
+ QITABENT(OCContextMenu, IContextMenu),
|
|
|
+ QITABENT(OCContextMenu, IShellExtInit),
|
|
|
+ { 0 },
|
|
|
+ };
|
|
|
+ return QISearch(this, qit, riid, ppv);
|
|
|
}
|
|
|
|
|
|
// Increase the reference count for an interface on an object.
|
|
|
IFACEMETHODIMP_(ULONG) OCContextMenu::AddRef()
|
|
|
{
|
|
|
- return InterlockedIncrement(&m_cRef);
|
|
|
+ return InterlockedIncrement(&m_cRef);
|
|
|
}
|
|
|
|
|
|
// Decrease the reference count for an interface on an object.
|
|
|
IFACEMETHODIMP_(ULONG) OCContextMenu::Release()
|
|
|
{
|
|
|
- ULONG cRef = InterlockedDecrement(&m_cRef);
|
|
|
- if (0 == cRef) {
|
|
|
- delete this;
|
|
|
- }
|
|
|
+ ULONG cRef = InterlockedDecrement(&m_cRef);
|
|
|
+ if (0 == cRef) {
|
|
|
+ delete this;
|
|
|
+ }
|
|
|
|
|
|
- return cRef;
|
|
|
+ return cRef;
|
|
|
}
|
|
|
|
|
|
#pragma endregion
|
|
|
@@ -92,40 +92,40 @@ IFACEMETHODIMP_(ULONG) OCContextMenu::Release()
|
|
|
|
|
|
// Initialize the context menu handler.
|
|
|
IFACEMETHODIMP OCContextMenu::Initialize(
|
|
|
- LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKeyProgID)
|
|
|
+ LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKeyProgID)
|
|
|
{
|
|
|
- if (!pDataObj) {
|
|
|
- return E_INVALIDARG;
|
|
|
- }
|
|
|
-
|
|
|
- HRESULT hr = E_FAIL;
|
|
|
-
|
|
|
- FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
|
|
- STGMEDIUM stm;
|
|
|
-
|
|
|
- if (SUCCEEDED(pDataObj->GetData(&fe, &stm))) {
|
|
|
- // Get an HDROP handle.
|
|
|
- HDROP hDrop = static_cast<HDROP>(GlobalLock(stm.hGlobal));
|
|
|
- if (hDrop) {
|
|
|
- // Ignore multi-selections
|
|
|
- UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
|
|
|
- if (nFiles == 1) {
|
|
|
- // Get the path of the file.
|
|
|
- if (0 != DragQueryFile(hDrop, 0, m_szSelectedFile, ARRAYSIZE(m_szSelectedFile)))
|
|
|
- {
|
|
|
- hr = S_OK;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- GlobalUnlock(stm.hGlobal);
|
|
|
- }
|
|
|
-
|
|
|
- ReleaseStgMedium(&stm);
|
|
|
- }
|
|
|
-
|
|
|
- // If any value other than S_OK is returned from the method, the context
|
|
|
- // menu item is not displayed.
|
|
|
- return hr;
|
|
|
+ if (!pDataObj) {
|
|
|
+ return E_INVALIDARG;
|
|
|
+ }
|
|
|
+
|
|
|
+ HRESULT hr = E_FAIL;
|
|
|
+
|
|
|
+ FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
|
|
+ STGMEDIUM stm;
|
|
|
+
|
|
|
+ if (SUCCEEDED(pDataObj->GetData(&fe, &stm))) {
|
|
|
+ // Get an HDROP handle.
|
|
|
+ HDROP hDrop = static_cast<HDROP>(GlobalLock(stm.hGlobal));
|
|
|
+ if (hDrop) {
|
|
|
+ // Ignore multi-selections
|
|
|
+ UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
|
|
|
+ if (nFiles == 1) {
|
|
|
+ // Get the path of the file.
|
|
|
+ if (0 != DragQueryFile(hDrop, 0, m_szSelectedFile, ARRAYSIZE(m_szSelectedFile)))
|
|
|
+ {
|
|
|
+ hr = S_OK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ GlobalUnlock(stm.hGlobal);
|
|
|
+ }
|
|
|
+
|
|
|
+ ReleaseStgMedium(&stm);
|
|
|
+ }
|
|
|
+
|
|
|
+ // If any value other than S_OK is returned from the method, the context
|
|
|
+ // menu item is not displayed.
|
|
|
+ return hr;
|
|
|
}
|
|
|
|
|
|
#pragma endregion
|
|
|
@@ -135,135 +135,135 @@ IFACEMETHODIMP OCContextMenu::Initialize(
|
|
|
|
|
|
void InsertSeperator(HMENU hMenu, UINT indexMenu)
|
|
|
{
|
|
|
- // Add a separator.
|
|
|
- MENUITEMINFO sep = { sizeof(sep) };
|
|
|
- sep.fMask = MIIM_TYPE;
|
|
|
- sep.fType = MFT_SEPARATOR;
|
|
|
- InsertMenuItem(hMenu, indexMenu, TRUE, &sep);
|
|
|
+ // Add a separator.
|
|
|
+ MENUITEMINFO sep = { sizeof(sep) };
|
|
|
+ sep.fMask = MIIM_TYPE;
|
|
|
+ sep.fType = MFT_SEPARATOR;
|
|
|
+ InsertMenuItem(hMenu, indexMenu, TRUE, &sep);
|
|
|
}
|
|
|
|
|
|
IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
|
|
|
{
|
|
|
- // If uFlags include CMF_DEFAULTONLY then we should not do anything.
|
|
|
- if (CMF_DEFAULTONLY & uFlags)
|
|
|
- {
|
|
|
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
|
|
|
- }
|
|
|
-
|
|
|
- OCClientInterface::ContextMenuInfo info = OCClientInterface::FetchInfo();
|
|
|
- bool skip = true;
|
|
|
- for (const std::wstring path : info.watchedDirectories) {
|
|
|
- if (StringUtil::begins_with(std::wstring(m_szSelectedFile), path)) {
|
|
|
- skip = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (skip) {
|
|
|
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
|
|
|
- }
|
|
|
-
|
|
|
- InsertSeperator(hMenu, indexMenu);
|
|
|
- indexMenu++;
|
|
|
-
|
|
|
- assert(!info.shareMenuTitle.empty());
|
|
|
- MENUITEMINFO mii = { sizeof(mii) };
|
|
|
- mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
|
|
- mii.wID = idCmdFirst + IDM_SHARE;
|
|
|
- mii.fType = MFT_STRING;
|
|
|
- mii.dwTypeData = &info.shareMenuTitle[0];
|
|
|
- mii.fState = MFS_ENABLED;
|
|
|
- if (!InsertMenuItem(hMenu, indexMenu, TRUE, &mii))
|
|
|
- {
|
|
|
- return HRESULT_FROM_WIN32(GetLastError());
|
|
|
- }
|
|
|
-
|
|
|
- indexMenu++;
|
|
|
- InsertSeperator(hMenu, indexMenu);
|
|
|
-
|
|
|
-
|
|
|
- // Return an HRESULT value with the severity set to SEVERITY_SUCCESS.
|
|
|
- // Set the code value to the offset of the largest command identifier
|
|
|
- // that was assigned, plus one (1).
|
|
|
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_SHARE + 1));
|
|
|
+ // If uFlags include CMF_DEFAULTONLY then we should not do anything.
|
|
|
+ if (CMF_DEFAULTONLY & uFlags)
|
|
|
+ {
|
|
|
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ OCClientInterface::ContextMenuInfo info = OCClientInterface::FetchInfo();
|
|
|
+ bool skip = true;
|
|
|
+ for (const std::wstring path : info.watchedDirectories) {
|
|
|
+ if (StringUtil::begins_with(std::wstring(m_szSelectedFile), path)) {
|
|
|
+ skip = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (skip) {
|
|
|
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ InsertSeperator(hMenu, indexMenu);
|
|
|
+ indexMenu++;
|
|
|
+
|
|
|
+ assert(!info.shareMenuTitle.empty());
|
|
|
+ MENUITEMINFO mii = { sizeof(mii) };
|
|
|
+ mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
|
|
+ mii.wID = idCmdFirst + IDM_SHARE;
|
|
|
+ mii.fType = MFT_STRING;
|
|
|
+ mii.dwTypeData = &info.shareMenuTitle[0];
|
|
|
+ mii.fState = MFS_ENABLED;
|
|
|
+ if (!InsertMenuItem(hMenu, indexMenu, TRUE, &mii))
|
|
|
+ {
|
|
|
+ return HRESULT_FROM_WIN32(GetLastError());
|
|
|
+ }
|
|
|
+
|
|
|
+ indexMenu++;
|
|
|
+ InsertSeperator(hMenu, indexMenu);
|
|
|
+
|
|
|
+
|
|
|
+ // Return an HRESULT value with the severity set to SEVERITY_SUCCESS.
|
|
|
+ // Set the code value to the offset of the largest command identifier
|
|
|
+ // that was assigned, plus one (1).
|
|
|
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_SHARE + 1));
|
|
|
}
|
|
|
|
|
|
IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
|
|
|
{
|
|
|
|
|
|
- // For the Unicode case, if the high-order word is not zero, the
|
|
|
- // command's verb string is in lpcmi->lpVerbW.
|
|
|
- if (HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW))
|
|
|
- {
|
|
|
- // Is the verb supported by this context menu extension?
|
|
|
- if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, m_pwszVerb) == 0)
|
|
|
- {
|
|
|
- OnVerbDisplayFileName(pici->hwnd);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // If the verb is not recognized by the context menu handler, it
|
|
|
- // must return E_FAIL to allow it to be passed on to the other
|
|
|
- // context menu handlers that might implement that verb.
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // If the command cannot be identified through the verb string, then
|
|
|
- // check the identifier offset.
|
|
|
- else
|
|
|
- {
|
|
|
- // Is the command identifier offset supported by this context menu
|
|
|
- // extension?
|
|
|
- if (LOWORD(pici->lpVerb) == IDM_SHARE)
|
|
|
- {
|
|
|
- OnVerbDisplayFileName(pici->hwnd);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // If the verb is not recognized by the context menu handler, it
|
|
|
- // must return E_FAIL to allow it to be passed on to the other
|
|
|
- // context menu handlers that might implement that verb.
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return S_OK;
|
|
|
+ // For the Unicode case, if the high-order word is not zero, the
|
|
|
+ // command's verb string is in lpcmi->lpVerbW.
|
|
|
+ if (HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW))
|
|
|
+ {
|
|
|
+ // Is the verb supported by this context menu extension?
|
|
|
+ if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, m_pwszVerb) == 0)
|
|
|
+ {
|
|
|
+ OnVerbDisplayFileName(pici->hwnd);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If the verb is not recognized by the context menu handler, it
|
|
|
+ // must return E_FAIL to allow it to be passed on to the other
|
|
|
+ // context menu handlers that might implement that verb.
|
|
|
+ return E_FAIL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If the command cannot be identified through the verb string, then
|
|
|
+ // check the identifier offset.
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Is the command identifier offset supported by this context menu
|
|
|
+ // extension?
|
|
|
+ if (LOWORD(pici->lpVerb) == IDM_SHARE)
|
|
|
+ {
|
|
|
+ OnVerbDisplayFileName(pici->hwnd);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If the verb is not recognized by the context menu handler, it
|
|
|
+ // must return E_FAIL to allow it to be passed on to the other
|
|
|
+ // context menu handlers that might implement that verb.
|
|
|
+ return E_FAIL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return S_OK;
|
|
|
}
|
|
|
|
|
|
IFACEMETHODIMP OCContextMenu::GetCommandString(UINT_PTR idCommand,
|
|
|
- UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
|
|
|
+ UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax)
|
|
|
{
|
|
|
- HRESULT hr = E_INVALIDARG;
|
|
|
-
|
|
|
- if (idCommand == IDM_SHARE)
|
|
|
- {
|
|
|
- switch (uFlags)
|
|
|
- {
|
|
|
- case GCS_HELPTEXTW:
|
|
|
- // Only useful for pre-Vista versions of Windows that have a
|
|
|
- // Status bar.
|
|
|
- hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
|
|
|
- m_pwszVerbHelpText);
|
|
|
- break;
|
|
|
-
|
|
|
- case GCS_VERBW:
|
|
|
- // GCS_VERBW is an optional feature that enables a caller to
|
|
|
- // discover the canonical name for the verb passed in through
|
|
|
- // idCommand.
|
|
|
- hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
|
|
|
- m_pwszVerbCanonicalName);
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- hr = S_OK;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // If the command (idCommand) is not supported by this context menu
|
|
|
- // extension handler, return E_INVALIDARG.
|
|
|
-
|
|
|
- return hr;
|
|
|
+ HRESULT hr = E_INVALIDARG;
|
|
|
+
|
|
|
+ if (idCommand == IDM_SHARE)
|
|
|
+ {
|
|
|
+ switch (uFlags)
|
|
|
+ {
|
|
|
+ case GCS_HELPTEXTW:
|
|
|
+ // Only useful for pre-Vista versions of Windows that have a
|
|
|
+ // Status bar.
|
|
|
+ hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
|
|
|
+ m_pwszVerbHelpText);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case GCS_VERBW:
|
|
|
+ // GCS_VERBW is an optional feature that enables a caller to
|
|
|
+ // discover the canonical name for the verb passed in through
|
|
|
+ // idCommand.
|
|
|
+ hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
|
|
|
+ m_pwszVerbCanonicalName);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ hr = S_OK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If the command (idCommand) is not supported by this context menu
|
|
|
+ // extension handler, return E_INVALIDARG.
|
|
|
+
|
|
|
+ return hr;
|
|
|
}
|
|
|
|
|
|
#pragma endregion
|