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

📄 clipboardwin.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "ClipboardWin.h"#include "CString.h"#include "CachedImage.h"#include "ClipboardUtilitiesWin.h"#include "Document.h"#include "DragData.h"#include "Editor.h"#include "Element.h"#include "EventHandler.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameView.h"#include "HTMLNames.h"#include "Image.h"#include "MIMETypeRegistry.h"#include "Page.h"#include "Pasteboard.h"#include "PlatformMouseEvent.h"#include "PlatformString.h"#include "Range.h"#include "RenderImage.h"#include "ResourceResponse.h"#include "StringHash.h"#include "WCDataObject.h"#include "csshelper.h"#include "markup.h"#include <shlwapi.h>#include <wininet.h>#include <wtf/RefPtr.h>using namespace std;namespace WebCore {using namespace HTMLNames;// format string for static const char szShellDotUrlTemplate[] = "[InternetShortcut]\r\nURL=%s\r\n";// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText };static ClipboardDataType clipboardTypeFromMIMEType(const String& type){    String qType = type.stripWhiteSpace().lower();    // two special cases for IE compatibility    if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;"))        return ClipboardDataTypeText;    if (qType == "url" || qType == "text/uri-list")        return ClipboardDataTypeURL;    return ClipboardDataTypeNone;}static inline FORMATETC* fileDescriptorFormat(){    static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);    static FORMATETC fileDescriptorFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &fileDescriptorFormat;}static inline FORMATETC* fileContentFormatZero(){    static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS);    static FORMATETC fileContentFormat = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL};    return &fileContentFormat;}static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length){    size_t writeTo = 0;    size_t readFrom = 0;    while (readFrom < length) {        UINT type = PathGetCharType(psz[readFrom]);        if (psz[readFrom] == 0 || type & (GCT_LFNCHAR | GCT_SHORTCHAR)) {            psz[writeTo++] = psz[readFrom];        }        readFrom++;    }    psz[writeTo] = 0;}static String filesystemPathFromUrlOrTitle(const String& url, const String& title, TCHAR* extension, bool isLink){    bool usedURL = false;    WCHAR fsPathBuffer[MAX_PATH + 1];    fsPathBuffer[0] = 0;    int extensionLen = extension ? lstrlen(extension) : 0;    if (!title.isEmpty()) {        size_t len = min<size_t>(title.length(), MAX_PATH - extensionLen);        CopyMemory(fsPathBuffer, title.characters(), len * sizeof(UChar));        fsPathBuffer[len] = 0;        pathRemoveBadFSCharacters(fsPathBuffer, len);    }    if (!lstrlen(fsPathBuffer)) {        DWORD len = MAX_PATH;        String nullTermURL = url;        usedURL = true;        if (UrlIsFileUrl((LPCWSTR)nullTermURL.charactersWithNullTermination())             && SUCCEEDED(PathCreateFromUrl((LPCWSTR)nullTermURL.charactersWithNullTermination(), fsPathBuffer, &len, 0))) {            // When linking to a file URL we can trivially find the file name            PWSTR fn = PathFindFileName(fsPathBuffer);            if (fn && fn != fsPathBuffer)                lstrcpyn(fsPathBuffer, fn, lstrlen(fn) + 1);        } else {            // The filename for any content based drag should be the last element of             // the path.  If we can't find it, or we're coming up with the name for a link            // we just use the entire url.            KURL kurl(url);            String lastComponent;            if (!isLink && !(lastComponent = kurl.lastPathComponent()).isEmpty()) {                len = min<DWORD>(MAX_PATH, lastComponent.length());                CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar));            } else {                len = min<DWORD>(MAX_PATH, nullTermURL.length());                CopyMemory(fsPathBuffer, nullTermURL.characters(), len * sizeof(UChar));            }            fsPathBuffer[len] = 0;            pathRemoveBadFSCharacters(fsPathBuffer, len);        }    }    if (!extension)        return String((UChar*)fsPathBuffer);    if (!isLink && usedURL) {        PathRenameExtension(fsPathBuffer, extension);        return String((UChar*)fsPathBuffer);    }    String result((UChar*)fsPathBuffer);    result += String((UChar*)extension);    return result;}static HGLOBAL createGlobalURLContent(const String& url, int estimatedFileSize){    HRESULT hr = S_OK;    HGLOBAL memObj = 0;    char* fileContents;    char ansiUrl[INTERNET_MAX_URL_LENGTH + 1];    // Used to generate the buffer. This is null terminated whereas the fileContents won't be.    char contentGenerationBuffer[INTERNET_MAX_URL_LENGTH + ARRAYSIZE(szShellDotUrlTemplate) + 1];        if (estimatedFileSize > 0 && estimatedFileSize > ARRAYSIZE(contentGenerationBuffer))        return 0;    int ansiUrlSize = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)url.characters(), url.length(), ansiUrl, ARRAYSIZE(ansiUrl) - 1, 0, 0);    if (!ansiUrlSize)        return 0;    ansiUrl[ansiUrlSize] = 0;        int fileSize = (int) (ansiUrlSize+strlen(szShellDotUrlTemplate)-2); // -2 to remove the %s    ASSERT(estimatedFileSize < 0 || fileSize == estimatedFileSize);    memObj = GlobalAlloc(GPTR, fileSize);    if (!memObj)         return 0;    fileContents = (PSTR)GlobalLock(memObj);    sprintf_s(contentGenerationBuffer, ARRAYSIZE(contentGenerationBuffer), szShellDotUrlTemplate, ansiUrl);    CopyMemory(fileContents, contentGenerationBuffer, fileSize);        GlobalUnlock(memObj);        return memObj;}static HGLOBAL createGlobalImageFileContent(SharedBuffer* data){    HGLOBAL memObj = GlobalAlloc(GPTR, data->size());    if (!memObj)         return 0;    char* fileContents = (PSTR)GlobalLock(memObj);    CopyMemory(fileContents, data->data(), data->size());        GlobalUnlock(memObj);        return memObj;}static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, SharedBuffer* data){    if (fileName.isEmpty() || !data )        return 0;    WCHAR filePath[MAX_PATH];    if (url.isLocalFile()) {        String localPath = url.path();        // windows does not enjoy a leading slash on paths        if (localPath[0] == '/')            localPath = localPath.substring(1);        LPCTSTR localPathStr = localPath.charactersWithNullTermination();        if (wcslen(localPathStr) + 1 < MAX_PATH)            wcscpy_s(filePath, MAX_PATH, localPathStr);        else            return 0;    } else {        WCHAR tempPath[MAX_PATH];        WCHAR extension[MAX_PATH];        if (!::GetTempPath(ARRAYSIZE(tempPath), tempPath))            return 0;        if (!::PathAppend(tempPath, fileName.charactersWithNullTermination()))            return 0;        LPCWSTR foundExtension = ::PathFindExtension(tempPath);        if (foundExtension) {            if (wcscpy_s(extension, MAX_PATH, foundExtension))                return 0;        } else            *extension = 0;        ::PathRemoveExtension(tempPath);        for (int i = 1; i < 10000; i++) {            if (swprintf_s(filePath, MAX_PATH, TEXT("%s-%d%s"), tempPath, i, extension) == -1)                return 0;            if (!::PathFileExists(filePath))                break;        }        HANDLE tempFileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);        if (tempFileHandle == INVALID_HANDLE_VALUE)            return 0;        // Write the data to this temp file.        DWORD written;        BOOL tempWriteSucceeded = WriteFile(tempFileHandle, data->data(), data->size(), &written, 0);        CloseHandle(tempFileHandle);        if (!tempWriteSucceeded)            return 0;    }    SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2));    HGLOBAL memObj = GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize);    if (!memObj)         return 0;    DROPFILES* dropFiles = (DROPFILES*) GlobalLock(memObj);    dropFiles->pFiles = sizeof(DROPFILES);    dropFiles->fWide = TRUE;    wcscpy((LPWSTR)(dropFiles + 1), filePath);        GlobalUnlock(memObj);        return memObj;}static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& title, int& /*out*/ estimatedSize){    HRESULT hr = S_OK;    HGLOBAL memObj = 0;    String fsPath;    memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));    if (!memObj)        return 0;    FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);    memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));    fgd->cItems = 1;    fgd->fgd[0].dwFlags = FD_FILESIZE;    int fileSize = ::WideCharToMultiByte(CP_ACP, 0, url.characters(), url.length(), 0, 0, 0, 0);    fileSize += strlen(szShellDotUrlTemplate) - 2;  // -2 is for getting rid of %s in the template string    fgd->fgd[0].nFileSizeLow = fileSize;    estimatedSize = fileSize;    fsPath = filesystemPathFromUrlOrTitle(url, title, L".URL", true);    if (fsPath.length() <= 0) {        GlobalUnlock(memObj);        GlobalFree(memObj);        return 0;    }    int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName));    CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));    GlobalUnlock(memObj);        return memObj;}static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image){    ASSERT_ARG(image, image);    ASSERT(image->image()->data());    HRESULT hr = S_OK;    HGLOBAL memObj = 0;    String fsPath;    memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));    if (!memObj)        return 0;    FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);    memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));    fgd->cItems = 1;    fgd->fgd[0].dwFlags = FD_FILESIZE;    fgd->fgd[0].nFileSizeLow = image->image()->data()->size();        const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title;    String extension = image->image()->filenameExtension();    if (extension.isEmpty()) {        // Do not continue processing in the rare and unusual case where a decoded image is not able         // to provide a filename extension. Something tricky (like a bait-n-switch) is going on        return 0;    }    extension.insert(".", 0);    fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, (TCHAR*)extension.charactersWithNullTermination(), false);    if (fsPath.length() <= 0) {        GlobalUnlock(memObj);        GlobalFree(memObj);        return 0;    }    int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName));    CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));    GlobalUnlock(memObj);        return memObj;}// writeFileToDataObject takes ownership of fileDescriptor and fileContentstatic HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescriptor, HGLOBAL fileContent, HGLOBAL hDropContent){    HRESULT hr = S_OK;    FORMATETC* fe;    STGMEDIUM medium = {0};    medium.tymed = TYMED_HGLOBAL;    if (!fileDescriptor || !fileContent)        goto exit;    // Descriptor    fe = fileDescriptorFormat();    medium.hGlobal = fileDescriptor;    if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))        goto exit;    // Contents    fe = fileContentFormatZero();    medium.hGlobal = fileContent;    if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))        goto exit;    // HDROP    if (hDropContent) {        medium.hGlobal = hDropContent;

⌨️ 快捷键说明

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