From f4438b41e109b9eabe0d5eb9d9f58b74222d6eed Mon Sep 17 00:00:00 2001 From: "locka%iol.ie" Date: Thu, 21 Oct 1999 20:32:52 +0000 Subject: [PATCH] Added support for drag and drop of Internet Shortcut files git-svn-id: svn://10.0.0.236/trunk@51388 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/webshell/embed/ActiveX/DropTarget.cpp | 139 ++++++++++++++++-- mozilla/webshell/embed/ActiveX/DropTarget.h | 2 + .../webshell/embed/ActiveX/MozillaControl.idl | 11 -- .../embed/ActiveX/WebShellContainer.cpp | 1 + 4 files changed, 128 insertions(+), 25 deletions(-) diff --git a/mozilla/webshell/embed/ActiveX/DropTarget.cpp b/mozilla/webshell/embed/ActiveX/DropTarget.cpp index bb57319c8ff..137ef280080 100644 --- a/mozilla/webshell/embed/ActiveX/DropTarget.cpp +++ b/mozilla/webshell/embed/ActiveX/DropTarget.cpp @@ -17,13 +17,27 @@ */ #include "stdafx.h" + +#include +#include + #include "DropTarget.h" #ifndef CFSTR_SHELLURL #define CFSTR_SHELLURL _T("UniformResourceLocator") #endif +#ifndef CFSTR_FILENAME +#define CFSTR_FILENAME _T("FileName") +#endif + +#ifndef CFSTR_FILENAMEW +#define CFSTR_FILENAMEW _T("FileNameW") +#endif + static const UINT g_cfURL = RegisterClipboardFormat(CFSTR_SHELLURL); +static const UINT g_cfFileName = RegisterClipboardFormat(CFSTR_FILENAME); +static const UINT g_cfFileNameW = RegisterClipboardFormat(CFSTR_FILENAMEW); CDropTarget::CDropTarget() { @@ -41,6 +55,48 @@ void CDropTarget::SetOwner(CMozillaBrowser *pOwner) m_pOwner = pOwner; } + +HRESULT CDropTarget::GetURLFromFile(const TCHAR *pszFile, tstring &szURL) +{ + USES_CONVERSION; + CIPtr(IUniformResourceLocator) spUrl; + + // Let's see if the file is an Internet Shortcut... + HRESULT hr = CoCreateInstance (CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (void **) &spUrl); + if (spUrl == NULL) + { + return E_FAIL; + } + + // Get the IPersistFile interface + CIPtr(IPersistFile) spFile = spUrl; + if (spFile == NULL) + { + return E_FAIL; + } + + // Initialise the URL object from the filename + LPSTR lpTemp = NULL; + if (FAILED(spFile->Load(T2OLE(pszFile), STGM_READ)) || + FAILED(spUrl->GetURL(&lpTemp))) + { + return E_FAIL; + } + + // Free the memory + CIPtr(IMalloc) spMalloc; + if (FAILED(SHGetMalloc(&spMalloc))) + { + return E_FAIL; + } + + // Copy the URL & cleanup + szURL = A2T(lpTemp); + spMalloc->Free(lpTemp); + + return S_OK; +} + /////////////////////////////////////////////////////////////////////////////// // IDropTarget implementation @@ -59,30 +115,41 @@ HRESULT STDMETHODCALLTYPE CDropTarget::DragEnter(/* [unique][in] */ IDataObject } // TODO process Internet Shortcuts (*.URL) files - - // Test if the data object supports types we can handle - BOOL bSupported = FALSE; FORMATETC formatetc; memset(&formatetc, 0, sizeof(formatetc)); formatetc.dwAspect = DVASPECT_CONTENT; formatetc.lindex = -1; formatetc.tymed = TYMED_HGLOBAL; + + // Test if the data object contains a text URL format formatetc.cfFormat = g_cfURL; if (pDataObj->QueryGetData(&formatetc) == S_OK) { - bSupported = TRUE; + m_spDataObject = pDataObj; + *pdwEffect = DROPEFFECT_LINK; + return S_OK; } - if (bSupported) + // Test if the data object contains a file name + formatetc.cfFormat = g_cfFileName; + if (pDataObj->QueryGetData(&formatetc) == S_OK) { m_spDataObject = pDataObj; *pdwEffect = DROPEFFECT_LINK; + return S_OK; } - else + + // Test if the data object contains a wide character file name + formatetc.cfFormat = g_cfFileName; + if (pDataObj->QueryGetData(&formatetc) == S_OK) { - *pdwEffect = DROPEFFECT_NONE; + m_spDataObject = pDataObj; + *pdwEffect = DROPEFFECT_LINK; + return S_OK; } + // If we got here, then the format is not supported + *pdwEffect = DROPEFFECT_NONE; return S_OK; } @@ -124,9 +191,8 @@ HRESULT STDMETHODCALLTYPE CDropTarget::Drop(/* [unique][in] */ IDataObject __RPC *pdwEffect = DROPEFFECT_LINK; - // TODO process Internet Shortcuts (*.URL) files - // Get the URL from the data object + BSTR bstrURL = NULL; FORMATETC formatetc; STGMEDIUM stgmedium; memset(&formatetc, 0, sizeof(formatetc)); @@ -135,8 +201,9 @@ HRESULT STDMETHODCALLTYPE CDropTarget::Drop(/* [unique][in] */ IDataObject __RPC formatetc.dwAspect = DVASPECT_CONTENT; formatetc.lindex = -1; formatetc.tymed = TYMED_HGLOBAL; - formatetc.cfFormat = g_cfURL; + // Does the data object contain a URL? + formatetc.cfFormat = g_cfURL; if (m_spDataObject->GetData(&formatetc, &stgmedium) == S_OK) { NG_ASSERT(stgmedium.tymed == TYMED_HGLOBAL); @@ -147,14 +214,58 @@ HRESULT STDMETHODCALLTYPE CDropTarget::Drop(/* [unique][in] */ IDataObject __RPC if (m_pOwner) { USES_CONVERSION; - BSTR bstrURL = SysAllocString(A2OLE(pszURL)); - m_pOwner->Navigate(bstrURL, NULL, NULL, NULL, NULL); - SysFreeString(bstrURL); + bstrURL = SysAllocString(A2OLE(pszURL)); } GlobalUnlock(stgmedium.hGlobal); - ReleaseStgMedium(&stgmedium); + goto finish; } + // Does the data object point to a file? + formatetc.cfFormat = g_cfFileName; + if (m_spDataObject->GetData(&formatetc, &stgmedium) == S_OK) + { + USES_CONVERSION; + NG_ASSERT(stgmedium.tymed == TYMED_HGLOBAL); + NG_ASSERT(stgmedium.hGlobal); + tstring szURL; + char *pszURLFile = (char *) GlobalLock(stgmedium.hGlobal); + NG_TRACE("File \"%s\" dragged over control\n", pszURLFile); + if (SUCCEEDED(GetURLFromFile(A2T(pszURLFile), szURL))) + { + bstrURL = SysAllocString(T2OLE(szURL.c_str())); + } + GlobalUnlock(stgmedium.hGlobal); + goto finish; + } + + // Does the data object point to a wide character file? + formatetc.cfFormat = g_cfFileName; + if (m_spDataObject->GetData(&formatetc, &stgmedium) == S_OK) + { + USES_CONVERSION; + NG_ASSERT(stgmedium.tymed == TYMED_HGLOBAL); + NG_ASSERT(stgmedium.hGlobal); + tstring szURL; + WCHAR *pszURLFile = (WCHAR *) GlobalLock(stgmedium.hGlobal); + NG_TRACE("File \"%s\" dragged over control\n", W2A(pszURLFile)); + if (SUCCEEDED(GetURLFromFile(W2T(pszURLFile), szURL))) + { + USES_CONVERSION; + bstrURL = SysAllocString(T2OLE(szURL.c_str())); + } + GlobalUnlock(stgmedium.hGlobal); + goto finish; + } + +finish: + // If we got a URL, browse there! + if (bstrURL) + { + m_pOwner->Navigate(bstrURL, NULL, NULL, NULL, NULL); + SysFreeString(bstrURL); + } + + ReleaseStgMedium(&stgmedium); m_spDataObject.Release(); return S_OK; diff --git a/mozilla/webshell/embed/ActiveX/DropTarget.h b/mozilla/webshell/embed/ActiveX/DropTarget.h index ee5a92a120e..a7c64f89aae 100644 --- a/mozilla/webshell/embed/ActiveX/DropTarget.h +++ b/mozilla/webshell/embed/ActiveX/DropTarget.h @@ -41,6 +41,8 @@ END_COM_MAP() // Sets the owner of this object void SetOwner(CMozillaBrowser *pOwner); + // Helper method to extract a URL from an internet shortcut file + HRESULT CDropTarget::GetURLFromFile(const TCHAR *pszFile, tstring &szURL); // IDropTarget virtual HRESULT STDMETHODCALLTYPE DragEnter(/* [unique][in] */ IDataObject __RPC_FAR *pDataObj, /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt, /* [out][in] */ DWORD __RPC_FAR *pdwEffect); diff --git a/mozilla/webshell/embed/ActiveX/MozillaControl.idl b/mozilla/webshell/embed/ActiveX/MozillaControl.idl index 8900dddf18c..094141bb445 100644 --- a/mozilla/webshell/embed/ActiveX/MozillaControl.idl +++ b/mozilla/webshell/embed/ActiveX/MozillaControl.idl @@ -137,17 +137,6 @@ library MOZILLACONTROLLib HRESULT Busy([out,retval] VARIANT_BOOL *pBool); } - typedef - [ - uuid(34A226E0-DF30-11CF-89A9-00A0C9054129), - helpstring("Constants for WebBrowser CommandStateChange") - ] - enum CommandStateChangeConstants { - [helpstring("Command Change")] CSC_UPDATECOMMANDS = 0xFFFFFFFF, - [helpstring("Navigate Forward")] CSC_NAVIGATEFORWARD = 0x00000001, - [helpstring("Navigate Back")] CSC_NAVIGATEBACK = 0x00000002, - } CommandStateChangeConstants; - [ uuid(0002DF05-0000-0000-C000-000000000046), // IID_IWebBrowserApp helpstring("Web Browser Application Interface."), diff --git a/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp b/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp index a5b232952bf..91b0a327057 100644 --- a/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp +++ b/mozilla/webshell/embed/ActiveX/WebShellContainer.cpp @@ -19,6 +19,7 @@ #include "stdafx.h" #include +#include #include "WebShellContainer.h"