⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 droptarget.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "emuledlg.h"
#include "DropTarget.h"
#include <intshcut.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define	FILETYPE_INETSHRTCUT	_T("Internet Shortcut File")
#define FILEEXT_INETSHRTCUTA	 "url"					 // ANSI string
#define FILEEXT_INETSHRTCUTW	L"url"					 // UNICODE string
#define FILEEXT_INETSHRTCUT		_T(FILEEXT_INETSHRTCUTA)
#define FILEEXTDOT_INETSHRTCUTA	   "."  FILEEXT_INETSHRTCUTA // ANSI string
#define FILEEXTDOT_INETSHRTCUTW	  L"."  FILEEXT_INETSHRTCUTW // UNICODE string
#define FILEEXTDOT_INETSHRTCUT	_T(".") FILEEXT_INETSHRTCUT
#define FILEFLT_INETSHRTCUT		FILETYPE_INETSHRTCUT _T("s (*") FILEEXTDOT_INETSHRTCUT _T(")|*") FILEEXTDOT_INETSHRTCUT _T("|")

BOOL IsUrlSchemeSupportedA(LPCSTR pszUrl)
{
	static const struct SCHEME
	{
		LPCSTR pszPrefix;
		int iLen;
	} _aSchemes[] = 
	{
#define SCHEME_ENTRY(prefix)	{ prefix, ARRSIZE(prefix)-1 }
		SCHEME_ENTRY("ed2k://")
#undef SCHEME_ENTRY
	};

	for (int i = 0; i < ARRSIZE(_aSchemes); i++)
	{
		if (strncmp(pszUrl, _aSchemes[i].pszPrefix, _aSchemes[i].iLen) == 0)
			return TRUE;
	}
	return FALSE;
}

BOOL IsUrlSchemeSupportedW(LPCWSTR pszUrl)
{
	static const struct SCHEME
	{
		LPCWSTR pszPrefix;
		int iLen;
	} _aSchemes[] = 
	{
#define SCHEME_ENTRY(prefix)	{ prefix, ARRSIZE(prefix)-1 }
		SCHEME_ENTRY(L"ed2k://")
#undef SCHEME_ENTRY
	};

	for (int i = 0; i < ARRSIZE(_aSchemes); i++)
	{
		if (wcsncmp(pszUrl, _aSchemes[i].pszPrefix, _aSchemes[i].iLen) == 0)
			return TRUE;
	}
	return FALSE;
}

// GetFileExtA -- ANSI version
// 
// This function is thought to be used only for filenames which have been
// validated by 'GetFullPathName' or similar functions.
LPCSTR GetFileExtA(LPCSTR pszPathA, int iLen /*= -1*/)
{
	// Just search the last '.'-character which comes after an optionally 
	// available last '\'-char.
	int iPos = iLen >= 0 ? iLen : strlen(pszPathA);
	while (iPos-- > 0)
	{
		if (pszPathA[iPos] == '.')
			return &pszPathA[iPos];
		if (pszPathA[iPos] == '\\')
			break;
	}

	return NULL;
}

// GetFileExtW -- UNICODE version
//
// This function is thought to be used only for filenames which have been
// validated by 'GetFullPathName' or similar functions.
LPCWSTR GetFileExtW(LPCWSTR pszPathW, int iLen /*= -1*/)
{
	// Just search the last '.'-character which comes after an optionally 
	// available last '\'-char.
	int iPos = iLen >= 0 ? iLen : wcslen(pszPathW);
	while (iPos-- > 0)
	{
		if (pszPathW[iPos] == L'.')
			return &pszPathW[iPos];
		if (pszPathW[iPos] == L'\\')
			break;
	}

	return NULL;
}


//////////////////////////////////////////////////////////////////////////////
// PASTEURLDATA

struct PASTEURLDATA
{
	PASTEURLDATA()
	{
		m_eType = (DataType)-1;
		m_dwFlags = 0;
	}
	PASTEURLDATA(BSTR bstrText, DWORD dwFlags = 0)
	{
		m_eType = HTMLText;
		m_bstrURLs = bstrText;
		m_dwFlags = dwFlags;
	}
	PASTEURLDATA(IDispatch *pIDispatch, DWORD dwFlags = 0)
	{
		m_eType = Document;
		m_pIDispDoc = pIDispatch;
		m_dwFlags = dwFlags;
	}

	enum DataType
	{
		Text,
		HTMLText,
		Document
	} m_eType;
	DWORD m_dwFlags;
	union
	{
		BSTR m_bstrURLs;
		IDispatch *m_pIDispDoc;
	};
};


//////////////////////////////////////////////////////////////////////////////
// CMainFrameDropTarget

CMainFrameDropTarget::CMainFrameDropTarget()
{
	m_bDropDataValid = FALSE;

	m_cfHTML = (CLIPFORMAT)RegisterClipboardFormat(_T("HTML Format"));
	ASSERT(m_cfHTML != 0);

	m_cfShellURL = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLURL);
	ASSERT(m_cfShellURL != 0);
}

HRESULT CMainFrameDropTarget::PasteHTMLDocument(IHTMLDocument2* doc, PASTEURLDATA* pPaste)
{
	HRESULT hrPasteResult = S_FALSE; // default: nothing was pasted
	int iURLElements = 0;

	// get_links		HREF	all <LINK> and <AREA> elements -> that's *wrong* it also contains all <A> elements!
	// get_anchors		HREF	all <A> elements which have a NAME or ID value!

	//
	// Links
	//
	CComPtr<IHTMLElementCollection> links;
	if (doc->get_links(&links) == S_OK)
	{
		long lLinks;
		if (links->get_length(&lLinks) == S_OK && lLinks > 0)
		{
			iURLElements += lLinks;
			CComVariant vaIndex((long)0);
			CComVariant vaNull((long)0);
			for (long i = 0; i < lLinks; i++)
			{
				vaIndex.lVal = i;
				CComPtr<IDispatch> item;
				if (links->item(vaIndex, vaNull, &item) == S_OK)
				{
					CComPtr<IHTMLAnchorElement> anchor;
					if (SUCCEEDED(item->QueryInterface(&anchor)))
					{
						CComBSTR bstrHref;
						if (anchor->get_href(&bstrHref) == S_OK && bstrHref.Length() > 0 && IsUrlSchemeSupportedW(bstrHref))
						{
							theApp.emuledlg->ProcessED2KLink(CString(bstrHref));
							hrPasteResult = S_OK;
						}
						anchor.Release(); // conserve memory
					}
				}
			}
		}
		links.Release(); // conserve memory
	}

	//
	// Text
	//
	// The explicit handling of text is needed, if we're looking at contents which were copied
	// to the clipboard in HTML format -- although it is simple raw text!! This situation applies,
	// if the user opens the "View Partial Source" HTML window for some selected HTML contents,
	// and copies some text (e.g. an URL) to the clipboard. In that case we'll get the raw text
	// as HTML contents!!!
	//
	// PROBLEM: We can *not* always process the HTML elements (anchors, ...) *and* the inner text.
	// The following example (a rather *usual* one) would lead to the adding of the same URL twice
	// because the URL is noted as a HREF *and* as the inner text.
	//
	// <P><A href="http://www.domain.com/image.gif">http://www.domain.com/image.gif</A></P>
	//
	// So, in practice, the examination of the 'innerText' is only done, if there were no other
	// HTML elements in the document.
	//
	if (iURLElements == 0)
	{
		CComPtr<IHTMLElement> el;
		if (doc->get_body(&el) == S_OK)
		{
			CComBSTR bstr;
			if (el->get_innerText(&bstr) == S_OK && bstr.Length() > 0)
			{
				LPCWSTR pwsz = bstr;
				while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
					pwsz++;

				// PROBLEM: The 'innerText' does not contain any HTML tags, but it *MAY* contain
				// HTML comments like "<!--StartFragment-->...<!--EndFragment-->". Those
				// tags have to be explicitly parsed to get the real raw text contents.
				// Those Start- and End-tags are available if the text is copied into the clipboard
				// from a HTML window which was open with "View Partial Source"!
				static const WCHAR _wszStartFrag[] = L"<!--StartFragment-->";
				if (wcsncmp(pwsz, _wszStartFrag, ARRSIZE(_wszStartFrag)-1) == 0)
				{
					pwsz += ARRSIZE(_wszStartFrag)-1;

					// If there's a Start-tag, search for an End-tag.
					static const WCHAR _wszEndFrag[] = L"<!--EndFragment-->";
					LPWSTR pwszEnd = (LPWSTR)bstr + bstr.Length();
					pwszEnd -= ARRSIZE(_wszEndFrag)-1;
					if (pwszEnd >= pwsz)
					{
						if (wcsncmp(pwszEnd, _wszEndFrag, ARRSIZE(_wszEndFrag)-1) == 0)
							*pwszEnd = L'\0'; // Ugly but efficient, terminate the BSTR!
					}
				}

				// Search all white-space terminated strings and check for a valid URL-scheme
				while (*pwsz != L'\0')
				{
					while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
						pwsz++;

					if (IsUrlSchemeSupportedW(pwsz))
					{
						LPCWSTR pwszEnd = pwsz;
						while (*pwszEnd != L'\0' && !iswspace(*pwszEnd)) // Search next white space (end of current string)
							pwszEnd++;
						int iLen = pwszEnd - pwsz;
						if (iLen > 0)
						{
							CString strURL(pwsz, iLen);
							theApp.emuledlg->ProcessED2KLink(strURL);
							hrPasteResult = S_OK;
							pwsz += iLen;
						}
					}
					else
					{
						while (*pwsz != L'\0' && !iswspace(*pwsz)) // Search next white space (end of current string)
							pwsz++;
					}

					while (*pwsz != L'\0' && iswspace(*pwsz)) // Skip white spaces
						pwsz++;
				}
			}
		}
	}

	return hrPasteResult;
}

HRESULT CMainFrameDropTarget::PasteHTML(PASTEURLDATA* pPaste)
{
	HRESULT hrPasteResult = S_FALSE; // default: nothing was pasted
	if (pPaste->m_bstrURLs[0] != L'\0')
	{
		HRESULT hr;
		CComPtr<IHTMLDocument2> doc;
		if (SUCCEEDED(hr = doc.CoCreateInstance(CLSID_HTMLDocument, NULL)))
		{
			SAFEARRAY* psfHtmlLines = SafeArrayCreateVector(VT_VARIANT, 0, 1);
			if (psfHtmlLines != NULL)
			{
				VARIANT* pva;
				if (SafeArrayAccessData(psfHtmlLines, (void**)&pva) == S_OK)
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -