LPCWSTR CDataObject::GetFormatName(CLIPFORMAT cfFormat, bool bRaw) { static wchar_t szName[128]; szName[0] = bRaw ? 0 : L'\''; if (GetClipboardFormatName(cfFormat, szName+(bRaw?0:1), 80) >= 1) { if (!bRaw) { wcscat_c(szName, L"',"); } } else { szName[0] = 0; } if (!bRaw || (szName[0] == 0)) { int nLen = lstrlen(szName); _wsprintf(szName+nLen, SKIPLEN(countof(szName)-nLen) L"x%04X(%u)", cfFormat, cfFormat); } return szName; }
WStringAutoPtr ClipboardFormats ( void ) { wstring format_list = L""; if ( OpenClipboard ( NULL ) ) { UINT formats = CountClipboardFormats(); UINT next_format = 0; for ( UINT i = 0 ; i < formats ; i++ ) { next_format = EnumClipboardFormats ( next_format ); const int max_count = 4096; wchar_t format_name[max_count]; int name_length = GetClipboardFormatName ( next_format, format_name, max_count ); if ( name_length > 0 ) { format_list += format_name; format_list += L"\r"; } } CloseClipboard(); } return WStringAutoPtr ( new wstring ( format_list ) ); } // ClipboardFormats
BOOL CClipboardBackup::Backup() { if( ! ::OpenClipboard(NULL) ) return FALSE; ClearBackupDatas(); UINT format = 0; while( (format = ::EnumClipboardFormats(format)) != 0 ) { ClipboardData data; data.m_nFormat = format; if( format <= 14 ) data.m_szFormatName[0] = 0; else if( GetClipboardFormatName(format, data.m_szFormatName, 100) == 0 ) data.m_szFormatName[0] = 0; HANDLE hMem = ::GetClipboardData( format ); if( hMem == NULL ) continue; data.m_nLength = ::GlobalSize(hMem); LPVOID pMem = ::GlobalLock( hMem ); data.m_pData = new byte[data.m_nLength]; memcpy(data.m_pData, pMem, data.m_nLength); m_lstData.AddTail(data); } ::CloseClipboard(); return TRUE; }
static PyObject * py_get_clipboard_formatName(PyObject* self, PyObject* args) { // @pyparm int|format||Specifies the type of format to be retrieved. This // parameter must not specify any of the predefined clipboard formats. int format; if (!PyArg_ParseTuple(args, "i:GetClipboardFormatName", &format)) { return NULL; } TCHAR buf[256]; int rc; Py_BEGIN_ALLOW_THREADS; rc = GetClipboardFormatName((UINT)format, buf, 255); Py_END_ALLOW_THREADS; if (!rc) { return ReturnAPIError("GetClipboardFormatName"); } return PyWinObject_FromTCHAR(buf); // @pyseeapi GetClipboardFormatName // @rdesc If the function succeeds, the return value is the string containing // the format.<nl> // If the function fails, win32api.error is raised with the GetLastError // info. }
/* * clipboard_get_format - クリップボード形式名の取得 */ UINT clipboard_get_format(const UINT format, TCHAR *type_name) { int i; const FORMAT_NAME_INFO fi[] = { CF_TEXT, TEXT("TEXT"), CF_BITMAP, TEXT("BITMAP"), CF_METAFILEPICT, TEXT("METAFILE PICTURE"), CF_SYLK, TEXT("SYLK"), CF_DIF, TEXT("DIF"), CF_TIFF, TEXT("TIFF"), CF_OEMTEXT, TEXT("OEM TEXT"), CF_DIB, TEXT("DIB"), CF_PALETTE, TEXT("PALETTE"), CF_PENDATA, TEXT("PEN DATA"), CF_RIFF, TEXT("RIFF"), CF_WAVE, TEXT("WAVE DATA"), CF_UNICODETEXT, TEXT("UNICODE TEXT"), CF_ENHMETAFILE, TEXT("ENHANCED METAFILE"), CF_HDROP, TEXT("DROP FILE LIST"), CF_LOCALE, TEXT("LOCALE"), CF_MAX, TEXT("MAX"), CF_OWNERDISPLAY, TEXT("OWNER DISPLAY"), CF_DSPTEXT, TEXT("PRIVATE TEXT"), CF_DSPBITMAP, TEXT("PRIVATE BITMAP"), CF_DSPMETAFILEPICT, TEXT("PRIVATE METAFILE PICTURE"), CF_DSPENHMETAFILE, TEXT("PRIVATE ENHANCED METAFILE"), CF_PRIVATEFIRST, TEXT("PRIVATE FIRST"), CF_PRIVATELAST, TEXT("PRIVATE LAST"), CF_GDIOBJFIRST, TEXT("GDI OBJECT FIRST"), CF_GDIOBJLAST, TEXT("GDI OBJECT LAST"), 0, TEXT(""), }; if (format != 0) { // format から名前を取得 *type_name = TEXT('\0'); if (GetClipboardFormatName(format, type_name, BUF_SIZE - 1) != 0) { return 0; } for (i = 0; (fi + i)->format != 0; i++) { if (format == (fi + i)->format) { lstrcpy(type_name, (fi + i)->name); break; } } if ((fi + i)->format == 0) { lstrcpy(type_name, (fi + i)->name); } } else { // 名前から format を取得 for (i = 0; (fi + i)->format != 0; i++) { if (lstrcmpi(type_name, (fi + i)->name) == 0) { return ((int)(fi + i)->format); } } } return 0; }
//Do not change these these are stored in the database CString GetFormatName(CLIPFORMAT cbType) { switch(cbType) { case CF_TEXT: return _T("CF_TEXT"); case CF_BITMAP: return _T("CF_BITMAP"); case CF_METAFILEPICT: return _T("CF_METAFILEPICT"); case CF_SYLK: return _T("CF_SYLK"); case CF_DIF: return _T("CF_DIF"); case CF_TIFF: return _T("CF_TIFF"); case CF_OEMTEXT: return _T("CF_OEMTEXT"); case CF_DIB: return _T("CF_DIB"); case CF_PALETTE: return _T("CF_PALETTE"); case CF_PENDATA: return _T("CF_PENDATA"); case CF_RIFF: return _T("CF_RIFF"); case CF_WAVE: return _T("CF_WAVE"); case CF_UNICODETEXT: return _T("CF_UNICODETEXT"); case CF_ENHMETAFILE: return _T("CF_ENHMETAFILE"); case CF_HDROP: return _T("CF_HDROP"); case CF_LOCALE: return _T("CF_LOCALE"); case CF_OWNERDISPLAY: return _T("CF_OWNERDISPLAY"); case CF_DSPTEXT: return _T("CF_DSPTEXT"); case CF_DSPBITMAP: return _T("CF_DSPBITMAP"); case CF_DSPMETAFILEPICT: return _T("CF_DSPMETAFILEPICT"); case CF_DSPENHMETAFILE: return _T("CF_DSPENHMETAFILE"); default: //Not a default type get the name from the clipboard if (cbType != 0) { TCHAR szFormat[256]; GetClipboardFormatName(cbType, szFormat, 256); return szFormat; } break; } return "ERROR"; }
static void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx) { LogFlow(("vboxClipboardChanged\n")); if (pCtx->pClient == NULL) { return; } /* Query list of available formats and report to host. */ if (OpenClipboard (pCtx->hwnd)) { uint32_t u32Formats = 0; UINT format = 0; while ((format = EnumClipboardFormats (format)) != 0) { LogFlow(("vboxClipboardChanged format %#x\n", format)); switch (format) { case CF_UNICODETEXT: case CF_TEXT: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; break; case CF_DIB: case CF_BITMAP: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; break; default: if (format >= 0xC000) { TCHAR szFormatName[256]; int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); if (cActual) { if (strcmp (szFormatName, "HTML Format") == 0) { u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML; } } } break; } } CloseClipboard (); LogFlow(("vboxClipboardChanged u32Formats %02X\n", u32Formats)); vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, u32Formats); } }
static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx) { AssertPtr(pCtx); /* Query list of available formats and report to host. */ int rc = vboxOpenClipboard(pCtx->hwnd); if (RT_SUCCESS(rc)) { uint32_t u32Formats = 0; UINT format = 0; while ((format = EnumClipboardFormats(format)) != 0) { LogFlowFunc(("vboxClipboardChanged: format = 0x%08X\n", format)); switch (format) { case CF_UNICODETEXT: case CF_TEXT: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; break; case CF_DIB: case CF_BITMAP: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; break; default: { if (format >= 0xC000) { TCHAR szFormatName[256]; int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); if (cActual) { if (strcmp (szFormatName, "HTML Format") == 0) { u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML; } } } break; } } } CloseClipboard(); rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats); } else { LogFlow(("vboxClipboardChanged: error in open clipboard. hwnd: %x. err: %Rrc\n", pCtx->hwnd, rc)); } return rc; }
static int vboxClipboardChanged(VBOXCLIPBOARDCONTEXT *pCtx) { AssertPtr(pCtx); /* Query list of available formats and report to host. */ int rc = VINF_SUCCESS; if (FALSE == OpenClipboard(pCtx->hwnd)) { rc = RTErrConvertFromWin32(GetLastError()); } else { uint32_t u32Formats = 0; UINT format = 0; while ((format = EnumClipboardFormats (format)) != 0) { Log(("VBoxTray: vboxClipboardChanged: format = 0x%08X\n", format)); switch (format) { case CF_UNICODETEXT: case CF_TEXT: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; break; case CF_DIB: case CF_BITMAP: u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; break; default: if (format >= 0xC000) { TCHAR szFormatName[256]; int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); if (cActual) { if (strcmp (szFormatName, "HTML Format") == 0) { u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML; } } } break; } } CloseClipboard (); rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats); } return rc; }
/**************************************************************************** * * * FUNCTION : MyGetClipboardFormatName() * * * * PURPOSE : Properly retrieves the string associated with a clipboard * * format. If the format does not have a string associated * * with it, the string #dddd is returned. * * * * RETURNS : The number of characters copied into lpstr or 0 on error. * * * ****************************************************************************/ int MyGetClipboardFormatName( WORD fmt, LPSTR lpstr, int cbMax) { if (fmt < 0xc000) { // predefined or integer format - just get the atom string // wierdly enough, GetClipboardFormatName() doesn't support this. return(GlobalGetAtomName(fmt, lpstr, cbMax)); } else { return(GetClipboardFormatName(fmt, lpstr, cbMax)); } }
int main(int argc, char* argv[]) { bool resetClipboard = false; char *cp; for(argv++; *argv && *(cp = *argv) == '-'; argv++) { for(cp++; *cp; cp++) { switch(*cp) { case 'r': resetClipboard = true; continue; default: usage(); } break; } } if(OpenClipboard(NULL) == 0) { _ftprintf(stderr,_T("%s\n"), getLastErrorText().cstr()); return -1; } if(resetClipboard) { if(EmptyClipboard() == 0) { _ftprintf(stderr,_T("%s\n"), getLastErrorText().cstr()); return -1; } } else { for(int cf = EnumClipboardFormats(0); cf; cf = EnumClipboardFormats(cf)) { TCHAR name[256]; GetClipboardFormatName(cf,name,ARRAYSIZE(name)); TCHAR *cfName = findFormatName(cf); if(cfName != NULL) { _tprintf(_T("format:%-20s:"), cfName); } else { _tprintf(_T("format:%-20s:"), name); } HANDLE t = GetClipboardData(cf); if(t == NULL) { _tprintf(_T("GetClipboardData failed:%s\n"), getLastErrorText().cstr()); } else { TCHAR *str = (TCHAR*)t; if(cf == CF_TEXT) { _tprintf(_T("<%s>\n"), str); } try { hexdump(str,40,stdout); } catch(...) { } } } } CloseClipboard(); return 0; }
static HRESULT STDMETHODCALLTYPE CDevSettings_QueryGetData(IDataObject* iface, FORMATETC* pformatetc) { #if DEBUG TCHAR szFormatName[255]; #endif PCDevSettings This = impl_from_IDataObject(iface); if (pformatetc->dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT; if (pformatetc->lindex != -1) return DV_E_LINDEX; if (!(pformatetc->tymed & TYMED_HGLOBAL)) return DV_E_TYMED; /* Check if the requested data can be provided */ if (pformatetc->cfFormat == This->cfExtInterface || pformatetc->cfFormat == This->cfDisplayDevice || pformatetc->cfFormat == This->cfDisplayName || pformatetc->cfFormat == This->cfDisplayId || pformatetc->cfFormat == This->cfDisplayKey || pformatetc->cfFormat == This->cfDisplayStateFlags || pformatetc->cfFormat == This->cfMonitorDevice || pformatetc->cfFormat == This->cfMonitorName || pformatetc->cfFormat == This->cfPruningMode) { return S_OK; } #if DEBUG else { if (GetClipboardFormatName(pformatetc->cfFormat, szFormatName, sizeof(szFormatName) / sizeof(szFormatName[0]))) { DPRINT1("CDevSettings::QueryGetData(\"%ws\")\n", szFormatName); } else { DPRINT1("CDevSettings::QueryGetData(Format %u)\n", (unsigned int)pformatetc->cfFormat); } } #endif return DV_E_FORMATETC; }
/**************************************************************************** * * * FUNCTION : GetFormatName() * * * * PURPOSE : allocates and returns a pointer to a string representing * * a format. Use MyFree() to free this string. * * * * RETURNS : The number of characters copied into lpstr or 0 on error. * * * ****************************************************************************/ PSTR GetFormatName( WORD wFmt) { PSTR psz; WORD cb; if (wFmt == 1) { psz = MyAlloc(8); strcpy(psz, "CF_TEXT"); return psz; } psz = MyAlloc(255); *psz = '\0'; cb = GetClipboardFormatName(wFmt, psz, 255) + 1; return((PSTR)LocalReAlloc((HANDLE)psz, cb, LMEM_MOVEABLE)); }
gchar * _gdk_win32_cf_to_string (UINT format) { char buf[100]; switch (format) { #define CASE(x) case CF_##x: return "CF_" #x CASE (BITMAP); CASE (DIB); #ifdef CF_DIBV5 CASE (DIBV5); #endif CASE (DIF); CASE (DSPBITMAP); CASE (DSPENHMETAFILE); CASE (DSPMETAFILEPICT); CASE (DSPTEXT); CASE (ENHMETAFILE); CASE (HDROP); CASE (LOCALE); CASE (METAFILEPICT); CASE (OEMTEXT); CASE (OWNERDISPLAY); CASE (PALETTE); CASE (PENDATA); CASE (RIFF); CASE (SYLK); CASE (TEXT); CASE (WAVE); CASE (TIFF); CASE (UNICODETEXT); default: if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST) return static_printf ("CF_GDIOBJ%d", format - CF_GDIOBJFIRST); if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST) return static_printf ("CF_PRIVATE%d", format - CF_PRIVATEFIRST); if (GetClipboardFormatName (format, buf, sizeof (buf))) return static_printf ("'%s'", buf); else return static_printf ("unk-%#lx", format); } }
BOOL CXClipboardStack::Push() { if( ! ::OpenClipboard(NULL) ) { return FALSE; } std::list<LPXClipboardDataPiece> *plstThisTime = NULL; VERIFY(plstThisTime = new std::list<LPXClipboardDataPiece>); UINT uiFormat = 0; while(uiFormat = ::EnumClipboardFormats(uiFormat)) { LPXClipboardDataPiece lpXData = NULL; VERIFY(lpXData = new XClipboardDataPiece); lpXData->m_nFormat = uiFormat; if( uiFormat <= 14 ) { lpXData->m_szFormatName[0] = 0; } else if( !GetClipboardFormatName(uiFormat, lpXData->m_szFormatName, MAX_PATH)) { lpXData->m_szFormatName[0] = 0; } HANDLE hMem = ::GetClipboardData(uiFormat); if( hMem) { LONG nSize = (LONG)::GlobalSize(hMem); LPVOID pMem = ::GlobalLock(hMem); lpXData->m_hData = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, nSize ); LPVOID pNewMem = ::GlobalLock( lpXData->m_hData ); memcpy(pNewMem, pMem, nSize); ::GlobalUnlock(hMem); ::GlobalUnlock(lpXData->m_hData); } if (lpXData) { plstThisTime->push_back(lpXData); } } m_stkClipboard.push(plstThisTime); ::CloseClipboard(); return TRUE; }
static LPCTSTR GetFORMATLIST(UINT id) { const struct { UINT id; LPCTSTR name; } FORMATLIST [] = { { CF_NULL, _T("CF_NULL") }, { CF_TEXT, _T("CF_TEXT") }, { CF_BITMAP, _T("CF_BITMAP") }, { CF_METAFILEPICT, _T("CF_METAFILEPICT") }, { CF_SYLK, _T("CF_SYLK") }, { CF_DIF, _T("CF_DIF") }, { CF_TIFF, _T("CF_TIFF") }, { CF_OEMTEXT, _T("CF_OEMTEXT") }, { CF_DIB, _T("CF_DIB") }, { CF_PALETTE, _T("CF_PALETTE") }, { CF_PENDATA, _T("CF_PENDATA") }, { CF_RIFF, _T("CF_RIFF") }, { CF_WAVE, _T("CF_WAVE") }, { CF_UNICODETEXT, _T("CF_UNICODETEXT") }, { CF_ENHMETAFILE, _T("CF_ENHMETAFILE") }, { CF_HDROP, _T("CF_HDROP") }, { CF_LOCALE, _T("CF_LOCALE") }, { CF_DIBV5, _T("CF_DIBV5") }, { CF_OWNERDISPLAY, _T("CF_OWNERDISPLAY") }, { CF_DSPTEXT, _T("CF_DSPTEXT") }, { CF_DSPBITMAP, _T("CF_DSPBITMAP") }, { CF_DSPMETAFILEPICT, _T("CF_DSPMETAFILEPICT") }, { CF_DSPENHMETAFILE, _T("CF_DSPENHMETAFILE") }, { 0, NULL } }; static TCHAR buf [256] = { 0 }; for ( int i = 0 ; FORMATLIST[i].name ; i++ ) { if ( FORMATLIST[i].id == id ) return FORMATLIST[i].name; } if ( ! GetClipboardFormatName( id, buf, _countof( buf ) ) ) _stprintf_s( buf, _countof( buf ), _T("0x%x"), id ); return buf; }
CString GetClipFormatName(int uFormat,int htmlFormat) { if (uFormat <= 17) { return StrClipboardFormats[uFormat-1]; } else if (uFormat == htmlFormat) { return _T("CF_HTML"); } else { TCHAR szFormatName[256]; if (GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName))) { return szFormatName; } return _T("NONE"); } }
DROPEFFECT CArtOleDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { #ifdef _DEBUG pDataObject->BeginEnumFormats(); FORMATETC fmt; while (pDataObject->GetNextFormat(&fmt)) { if (fmt.cfFormat >= 0xc000) { char buffer[80]; GetClipboardFormatName(fmt.cfFormat, buffer, sizeof(buffer)); TRACE2("Format '%s' (%u)\n", buffer, fmt.cfFormat); } else { TRACE1("Format (%u)\n", fmt.cfFormat); } } #endif // _DEBUG return OnDragOver(pWnd, pDataObject, dwKeyState, point); }
/** * \brief Looks up the name for the specific clipboard format type. * * \param format The format to get the name for. * \param buf The buffer to copy the name into. * \param size The size of the buffer. * \return The length of the format name. */ static int _lookup_clipboard_format (UINT format, char *buf, int size) { int len; char *cpy; memset (buf, 0, size); switch (format) { case CF_TEXT: len = strlen (SCRAP_FORMAT_TEXT); cpy = SCRAP_FORMAT_TEXT; break; case CF_UNICODETEXT: len = 24; cpy = "text/plain;charset=utf-8"; break; case CF_TIFF: len = 10; cpy = "image/tiff"; break; case CF_DIB: len = strlen (SCRAP_FORMAT_BMP); cpy = SCRAP_FORMAT_BMP; break; case CF_WAVE: len = 9; cpy = "audio/wav"; break; default: len = GetClipboardFormatName (format, buf, size); return len; } if (len != 0) memcpy (buf, cpy, len); return len; }
// Implementation of GetData STDMETHODIMP CSimpleDataObjectImpl::GetData(FORMATETC* pformatetc, STGMEDIUM* pmedium) { // Check format etc if (pformatetc->dwAspect!=DVASPECT_CONTENT) return DV_E_DVASPECT; #ifdef _DEBUG TCHAR szFormat[MAX_PATH]; if (!GetClipboardFormatName(pformatetc->cfFormat, szFormat, MAX_PATH)) { wsprintf(szFormat, _T("%i"), pformatetc->cfFormat); } ATLTRACE(_T("CSimpleDataObjectImpl::GetData - %s %i\n"), szFormat, pformatetc->tymed); #endif // Get the format... CFormat* pFormat=FindFormat(pformatetc->cfFormat, (TYMED)pformatetc->tymed); if (!pFormat) return DATA_E_FORMATETC; // Init STGMEDIUM memset(pmedium, 0, sizeof(*pmedium)); if (pformatetc->tymed & TYMED_HGLOBAL) { // Delayed data? if (!pFormat->m_hData) { if (SUCCEEDED(OnGetData(pformatetc->cfFormat, pformatetc->lindex, &pmedium->hGlobal))) { pmedium->tymed=TYMED_HGLOBAL; return S_OK; } } else if (pformatetc->lindex==-1) { // Allocate memory DWORD_PTR dwSize=GlobalSize(pFormat->m_hData); pmedium->hGlobal=GlobalAlloc(GHND, dwSize); if (!pmedium->hGlobal) return E_OUTOFMEMORY; // Copy it memcpy(GlobalLock(pmedium->hGlobal), GlobalLock(pFormat->m_hData), dwSize); // Unlock GlobalUnlock(pmedium->hGlobal); GlobalUnlock(pFormat->m_hData); pmedium->tymed=TYMED_HGLOBAL; return S_OK; } } if (pformatetc->tymed & TYMED_ISTREAM) { // Delayed data? if (!pFormat->m_spStream) { if (SUCCEEDED(OnGetData(pformatetc->cfFormat, pformatetc->lindex, &pmedium->pstm))) { pmedium->tymed=TYMED_ISTREAM; return S_OK; } } else if (pformatetc->lindex==-1) { pFormat->m_spStream.CopyTo(&pmedium->pstm); pmedium->tymed=TYMED_ISTREAM; return S_OK; } } // Unknown format return DATA_E_FORMATETC; }
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { AssertPtr(pCtx); LRESULT rc = 0; switch (msg) { case WM_CLIPBOARDUPDATE: { Log(("WM_CLIPBOARDUPDATE\n")); if (GetClipboardOwner() != hwnd) { /* Clipboard was updated by another application. */ vboxClipboardChanged(pCtx); } } break; case WM_CHANGECBCHAIN: { if (vboxClipboardIsNewAPI(pCtx)) { rc = DefWindowProc(hwnd, msg, wParam, lParam); break; } HWND hwndRemoved = (HWND)wParam; HWND hwndNext = (HWND)lParam; LogFlowFunc(("WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd)); if (hwndRemoved == pCtx->hwndNextInChain) { /* The window that was next to our in the chain is being removed. * Relink to the new next window. */ pCtx->hwndNextInChain = hwndNext; } else { if (pCtx->hwndNextInChain) { /* Pass the message further. */ DWORD_PTR dwResult; rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult); if (!rc) rc = (LRESULT) dwResult; } } } break; case WM_DRAWCLIPBOARD: { LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd)); if (GetClipboardOwner() != hwnd) { /* Clipboard was updated by another application. */ /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ int vboxrc = vboxClipboardChanged(pCtx); if (RT_FAILURE(vboxrc)) LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc)); } if (pCtx->hwndNextInChain) { /* Pass the message to next windows in the clipboard chain. */ SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL); } } break; case WM_TIMER: { if (vboxClipboardIsNewAPI(pCtx)) break; HWND hViewer = GetClipboardViewer(); /* Re-register ourselves in the clipboard chain if our last ping * timed out or there seems to be no valid chain. */ if (!hViewer || pCtx->fCBChainPingInProcess) { vboxClipboardRemoveFromCBChain(pCtx); vboxClipboardAddToCBChain(pCtx); } /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be * processed by ourselves to the chain. */ pCtx->fCBChainPingInProcess = TRUE; hViewer = GetClipboardViewer(); if (hViewer) SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx); } break; case WM_CLOSE: { /* Do nothing. Ignore the message. */ } break; case WM_RENDERFORMAT: { /* Insert the requested clipboard format data into the clipboard. */ uint32_t u32Format = 0; UINT format = (UINT)wParam; LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format)); switch (format) { case CF_UNICODETEXT: u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; break; case CF_DIB: u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; break; default: if (format >= 0xC000) { TCHAR szFormatName[256]; int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); if (cActual) { if (strcmp (szFormatName, "HTML Format") == 0) { u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; } } } break; } if (u32Format == 0) { /* Unsupported clipboard format is requested. */ LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); EmptyClipboard(); } else { const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */ uint32_t cb = 0; /* Preallocate a buffer, most of small text transfers will fit into it. */ HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); if (hMem) { void *pMem = GlobalLock(hMem); LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); if (pMem) { /* Read the host data to the preallocated buffer. */ int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb); LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); if (RT_SUCCESS(vboxrc)) { if (cb == 0) { /* 0 bytes returned means the clipboard is empty. * Deallocate the memory and set hMem to NULL to get to * the clipboard empty code path. */ GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } else if (cb > cbPrealloc) { GlobalUnlock(hMem); /* The preallocated buffer is too small, adjust the size. */ hMem = GlobalReAlloc(hMem, cb, 0); LogFlowFunc(("Reallocated hMem = %p\n", hMem)); if (hMem) { pMem = GlobalLock(hMem); LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); if (pMem) { /* Read the host data to the preallocated buffer. */ uint32_t cbNew = 0; vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew); LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); if (RT_SUCCESS (vboxrc) && cbNew <= cb) { cb = cbNew; } else { GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } } else { GlobalFree(hMem); hMem = NULL; } } } if (hMem) { /* pMem is the address of the data. cb is the size of returned data. */ /* Verify the size of returned text, the memory block for clipboard * must have the exact string size. */ if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { size_t cbActual = 0; HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); if (FAILED (hrc)) { /* Discard invalid data. */ GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } else { /* cbActual is the number of bytes, excluding those used * for the terminating null character. */ cb = (uint32_t)(cbActual + 2); } } } if (hMem) { GlobalUnlock(hMem); hMem = GlobalReAlloc(hMem, cb, 0); LogFlowFunc(("Reallocated hMem = %p\n", hMem)); if (hMem) { /* 'hMem' contains the host clipboard data. * size is 'cb' and format is 'format'. */ HANDLE hClip = SetClipboardData(format, hMem); LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); if (hClip) { /* The hMem ownership has gone to the system. Finish the processing. */ break; } /* Cleanup follows. */ } } } if (hMem) GlobalUnlock(hMem); } if (hMem) GlobalFree(hMem); } /* Something went wrong. */ EmptyClipboard(); } } break; case WM_RENDERALLFORMATS: { /* Do nothing. The clipboard formats will be unavailable now, because the * windows is to be destroyed and therefore the guest side becomes inactive. */ int vboxrc = vboxOpenClipboard(hwnd); if (RT_SUCCESS(vboxrc)) { EmptyClipboard(); CloseClipboard(); } else { LogFlowFunc(("WM_RENDERALLFORMATS: Failed to open clipboard! rc: %Rrc\n", vboxrc)); } } break; case WM_USER: { /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ uint32_t u32Formats = (uint32_t)lParam; int vboxrc = vboxOpenClipboard(hwnd); if (RT_SUCCESS(vboxrc)) { EmptyClipboard(); HANDLE hClip = NULL; if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n")); hClip = SetClipboardData(CF_UNICODETEXT, NULL); } if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) { LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n")); hClip = SetClipboardData(CF_DIB, NULL); } if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) { UINT format = RegisterClipboardFormat ("HTML Format"); LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format)); if (format != 0) { hClip = SetClipboardData(format, NULL); } } CloseClipboard(); LogFlowFunc(("WM_USER: hClip = %p, err = %ld\n", hClip, GetLastError ())); } else { LogFlowFunc(("WM_USER: Failed to open clipboard! error = %Rrc\n", vboxrc)); } } break; case WM_USER + 1: { /* Send data in the specified format to the host. */ uint32_t u32Formats = (uint32_t)lParam; HANDLE hClip = NULL; int vboxrc = vboxOpenClipboard(hwnd); if (RT_SUCCESS(vboxrc)) { if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) { hClip = GetClipboardData(CF_DIB); if (hClip != NULL) { LPVOID lp = GlobalLock(hClip); if (lp != NULL) { LogFlowFunc(("WM_USER + 1: CF_DIB\n")); vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize(hClip)); GlobalUnlock(hClip); } else { hClip = NULL; } } } else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { hClip = GetClipboardData(CF_UNICODETEXT); if (hClip != NULL) { LPWSTR uniString = (LPWSTR)GlobalLock(hClip); if (uniString != NULL) { LogFlowFunc(("WM_USER + 1: CF_UNICODETEXT\n")); vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW(uniString) + 1) * 2); GlobalUnlock(hClip); } else { hClip = NULL; } } } else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) { UINT format = RegisterClipboardFormat ("HTML Format"); if (format != 0) { hClip = GetClipboardData(format); if (hClip != NULL) { LPVOID lp = GlobalLock(hClip); if (lp != NULL) { LogFlowFunc(("WM_USER + 1: CF_HTML\n")); vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip)); GlobalUnlock(hClip); } else { hClip = NULL; } } } } CloseClipboard(); } else { LogFlowFunc(("WM_USER: Failed to open clipboard! rc: %Rrc\n", vboxrc)); } if (hClip == NULL) { /* Requested clipboard format is not available, send empty data. */ VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); } } break; case WM_DESTROY: { vboxClipboardRemoveFromCBChain(pCtx); if (pCtx->timerRefresh) KillTimer(pCtx->hwnd, 0); /* * don't need to call PostQuitMessage cause * the VBoxTray already finished a message loop */ } break; default: { rc = DefWindowProc(hwnd, msg, wParam, lParam); } } #ifndef DEBUG_andy LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc)); #endif return rc; }
// ReadDataAndFillList(): Reads the data from the passed-in COleDataObject // and fills in the list control with the available formats. void CClipSpyListCtrl::ReadDataAndFillList ( IDataObject* pDO ) { FORMATETC etc; TCHAR szFormat[256]; HGLOBAL hgData; UINT uDataSize; CString sSize; int nItem = 0; // Empty the list control and the doc. DeleteAllItems(); // g_pMainWnd->ClearDataList(); // Get all the data and pass it to the main frame for storage. CComPtr<IEnumFORMATETC> pEnumFormats; pDO->EnumFormatEtc ( DATADIR_GET, &pEnumFormats ); while ( S_OK == pEnumFormats->Next ( 1, &etc, NULL ) ) { bool bReadData = false; STGMEDIUM stg = {0}; HRESULT hr; if ( FAILED( pDO->QueryGetData ( &etc ) )) continue; // See if this is a built-in clipboard format. If so, we already have // a description string for it - we just have to find it in the // clip format name map. If we don't find the format in the map, // then it's a custom format, and we need to get the name from Windows. CClipFormatNameMap::const_iterator it; it = m_mapFormatNames.find ( etc.cfFormat ); if ( it != m_mapFormatNames.end() ) lstrcpyn ( szFormat, it->second, countof(szFormat) ); else GetClipboardFormatName ( etc.cfFormat, szFormat, countof(szFormat) ); // Get an HGLOBAL or IStream on the next data format. etc.tymed |= TYMED_HGLOBAL | TYMED_ISTREAM; hr = pDO->GetData ( &etc, &stg ); if ( SUCCEEDED(hr) ) { // If the clipboard returned an HGLOBAL, read the data from the // global memory object. if ( stg.tymed & TYMED_HGLOBAL ) { hgData = stg.hGlobal; if ( NULL != hgData ) { uDataSize = GlobalSize ( hgData ); sSize.Format ( _T("%u (0x%X)"), uDataSize, uDataSize ); // g_pMainWnd->AddDataBlock ( hgData, uDataSize ); bReadData = true; } } // If the clipboard returned an IStream, read all the data from // the stream. if ( !bReadData && (stg.tymed & TYMED_ISTREAM) ) { LARGE_INTEGER li; ULARGE_INTEGER uli; li.QuadPart = 0; if ( SUCCEEDED( stg.pstm->Seek ( li, STREAM_SEEK_END, &uli ))) { HGLOBAL hg = GlobalAlloc ( GMEM_MOVEABLE | GMEM_SHARE, uli.LowPart ); void* pv = GlobalLock ( hg ); stg.pstm->Seek ( li, STREAM_SEEK_SET, NULL ); if ( SUCCEEDED( stg.pstm->Read ( pv, uli.LowPart, (PULONG) &uDataSize ))) { GlobalUnlock ( hg ); sSize.Format ( _T("%u (0x%X)"), uDataSize, uDataSize ); // g_pMainWnd->AddDataBlock ( hg, uDataSize ); // Free the memory we just allocated. GlobalFree ( hg ); bReadData = true; } else GlobalUnlock ( hg ); } } ReleaseStgMedium ( &stg ); } // end if (GetData() succeeded) InsertItem ( nItem, szFormat ); if ( bReadData ) { SetItemText ( nItem, 1, sSize ); } else { // If we couldn't get the data for this format, set the item data // to 1 so that the NM_CUSTOMDRAW handler will draw the text in grey. // g_pMainWnd->AddEmptyBlock(); SetItemData ( nItem, 1 ); if ( FAILED(hr) ) SetItemText ( nItem, 1, _T("<Data unavailable>") ); else SetItemText ( nItem, 1, _T("<Not displayable format>") ); } nItem++; } // end while SetColumnWidth ( 0, LVSCW_AUTOSIZE_USEHEADER ); SetColumnWidth ( 1, LVSCW_AUTOSIZE_USEHEADER ); }
//------------------------------------------------------------------------------ //http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx DWORD WINAPI Scan_clipboard(LPVOID lParam) { //check if local or not :) if (!LOCAL_SCAN) { h_thread_test[(unsigned int)lParam] = 0; check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan return 0; } //db sqlite3 *db = (sqlite3 *)db_scan; if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL); //lecture du contenu du presse papier et extraction if (OpenClipboard(0)) { char description[MAX_LINE_SIZE], format[DEFAULT_TMP_SIZE], data[MAX_LINE_SIZE],user[NB_USERNAME_SIZE+1]=""; unsigned int session_id = current_session_id; HGLOBAL hMem; //user DWORD s=NB_USERNAME_SIZE; GetUserName(user,&s); int nb_items = CountClipboardFormats(); if (nb_items > 0) { unsigned int uFormat = EnumClipboardFormats(0); #ifdef CMD_LINE_ONLY_NO_DB printf("\"Clipboard\";\"format\";\"code\";\"description\";\"user\";\"session_id\";\"data\";\r\n"); #endif // CMD_LINE_ONLY_NO_DB while (uFormat && start_scan && GetLastError() == ERROR_SUCCESS && --nb_items>0) { //check if ok if (IsClipboardFormatAvailable(uFormat) == FALSE) { uFormat = EnumClipboardFormats(uFormat); continue; } description[0] = 0; data[0]= 0; if (GetClipboardFormatName(uFormat, description, MAX_LINE_SIZE) != 0) { hMem = GetClipboardData(uFormat); if (hMem != NULL) { switch(uFormat) { case CF_TEXT: //format strncpy(format,"CF_TEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_BITMAP: //format strncpy(format,"CF_BITMAP",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Bitmap Picture",DEFAULT_TMP_SIZE); //do in bitmap to hexa SaveBitmapToHexaStr((HBITMAP)hMem , data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_METAFILEPICT: //format strncpy(format,"CF_METAFILEPICT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Meta-File Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); GlobalUnlock(hMem); break; case CF_SYLK: //format strncpy(format,"CF_SYLK",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Microsoft Symbolic Link (SYLK) data",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_OEMTEXT: //format strncpy(format,"CF_OEMTEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text (OEM)",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_DIB: //format strncpy(format,"CF_DIB",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"DIB Bitmap Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_DIF: //format strncpy(format,"CF_DIF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Software Arts' Data Interchange information",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_TIFF: //format strncpy(format,"CF_TIFF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Tagged Image File Format (TIFF) Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_PALETTE: //format strncpy(format,"CF_PALETTE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Colour Palette",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_PENDATA: //format strncpy(format,"CF_PENDATA",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Pen Data",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_UNICODETEXT: //format strncpy(format,"CF_UNICODETEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text Unicode",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE);h_thread_test[(unsigned int)lParam] = 0; GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_RIFF: //format strncpy(format,"CF_RIFF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"RIFF Audio data",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_WAVE: //format strncpy(format,"CF_WAVE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Wave File",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_ENHMETAFILE: //format strncpy(format,"CF_ENHMETAFILE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Enhanced Meta-File Picture",DEFAULT_TMP_SIZE); //datas DWORD dwSize = GetEnhMetaFileBits((HENHMETAFILE)hMem, 0, NULL); if (dwSize > 0) { LPBYTE buffer = (LPBYTE)malloc(dwSize); if (buffer != NULL) { if (GetEnhMetaFileBits((HENHMETAFILE)hMem, dwSize, buffer)!=0) { DatatoHexa(buffer, dwSize, data, MAX_LINE_SIZE); } free(buffer); } } addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_HDROP: { //format strncpy(format,"CF_HDROP",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"File List",DEFAULT_TMP_SIZE); HDROP H_DropInfo = (HDROP)hMem; char tmp[MAX_PATH]; DWORD i,nb_path = DragQueryFile(H_DropInfo, 0xFFFFFFFF, tmp, MAX_PATH); long int s2 =MAX_LINE_SIZE; for (i=0;i<nb_path;i++) { //traitement des données ^^ DragQueryFile(H_DropInfo, i, tmp, MAX_PATH); //add if (s2>0) { snprintf(data+strlen(data),s,"%s\r\n",tmp); //strncpy(data+strlen(data),tmp,s); s2-=strlen(data); } } convertStringToSQL(data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); } break; case CF_LOCALE: //format strncpy(format,"CF_LOCALE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text Locale Identifier",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"0x%X",(unsigned int)GlobalLock(hMem)); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 17: //CF_DIBV5 //format strncpy(format,"CF_DIBV5",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), sizeof(BITMAPV5HEADER), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49155: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"OwnerLink",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49156: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Native Bitmap Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49158: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"FileName",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49159: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"FileNameW",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49298: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Rich Text Format",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; default: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; } } } uFormat = EnumClipboardFormats(uFormat); } } CloseClipboard(); } if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL); check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan h_thread_test[(unsigned int)lParam] = 0; return 0; }
STDMETHODIMP CDDShellExt::Initialize(LPCITEMIDLIST pidlFolder,LPDATAOBJECT pDO,HKEY hProgID) { (void)hProgID; if(!connected) { bool b = m_ac.connectToServer(); if (b==true) { connected=true; } else return E_FAIL; } FORMATETC fmt={CF_HDROP,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL}; STGMEDIUM stg={TYMED_HGLOBAL}; HDROP hDrop; fDestDir[0]=0; if (!SHGetPathFromIDList(pidlFolder,fDestDir)) { #ifdef CATCHCOPY_EXPLORER_PLUGIN_DEBUG MessageBox(NULL,L"Initialize",L"E_FAIL 1",MB_OK); #endif // CATCHCOPY_EXPLORER_PLUGIN_DEBUG return E_FAIL; } // Detect if it's explorer that started the operation by enumerating available // clipboard formats and searching for one that only explorer uses IEnumFORMATETC *en; FORMATETC fmt2; WCHAR fmtName[256]=L"\0"; fFromExplorer=false; pDO->EnumFormatEtc(DATADIR_GET,&en); while(en->Next(1,&fmt2,NULL)==S_OK){ GetClipboardFormatName(fmt2.cfFormat,fmtName,256); if (!wcscmp(fmtName,CFSTR_SHELLIDLIST)) fFromExplorer=true; } en->Release(); // Look for CF_HDROP data in the data object. If there // is no such data, return an error back to Explorer. if (FAILED(pDO->GetData(&fmt,&stg))) { #ifdef CATCHCOPY_EXPLORER_PLUGIN_DEBUG MessageBox(NULL,L"Initialize",L"E_INVALIDARG 2",MB_OK); #endif // CATCHCOPY_EXPLORER_PLUGIN_DEBUG return E_INVALIDARG; } // Get a pointer to the actual data. hDrop=(HDROP)GlobalLock(stg.hGlobal); // Make sure it worked. if (hDrop==NULL) { #ifdef CATCHCOPY_EXPLORER_PLUGIN_DEBUG MessageBox(NULL,L"Initialize",L"E_INVALIDARG 1",MB_OK); #endif // CATCHCOPY_EXPLORER_PLUGIN_DEBUG return E_INVALIDARG; } UINT numFiles,i; WCHAR fn[MAX_PATH]=L""; numFiles=DragQueryFile(hDrop,0xFFFFFFFF,NULL,0); if (numFiles) { for(i=0;i<numFiles;++i) { if(DragQueryFile(hDrop,i,fn,MAX_PATH)) sources.push_back(fn); } } GlobalUnlock(stg.hGlobal); ReleaseStgMedium(&stg); return S_OK; }
HANDLE Clipboard::GetClipboardDataTimeout(UINT uFormat, BOOL *aNullIsOkay) // Update for v1.1.16: The comments below are obsolete; search for "v1.1.16" for related comments. // Same as GetClipboardData() except that it doesn't give up if the first call to GetClipboardData() fails. // Instead, it continues to retry the operation for the number of milliseconds in g_ClipboardTimeout. // This is necessary because GetClipboardData() has been observed to fail in repeatable situations (this // is strange because our thread already has the clipboard locked open -- presumably it happens because the // GetClipboardData() is unable to start a data stream from the application that actually serves up the data). // If cases where the first call to GetClipboardData() fails, a subsequent call will often succeed if you give // the owning application (such as Excel and Word) a little time to catch up. This is especially necessary in // the OnClipboardChange label, where sometimes a clipboard-change notification comes in before the owning // app has finished preparing its data for subsequent readers of the clipboard. { #ifdef DEBUG_BY_LOGGING_CLIPBOARD_FORMATS // Provides a convenient log of clipboard formats for analysis. static FILE *fp = fopen("c:\\debug_clipboard_formats.txt", "w"); #endif if (aNullIsOkay) *aNullIsOkay = FALSE; // Set default. TCHAR format_name[MAX_PATH + 1]; // MSDN's RegisterClipboardFormat() doesn't document any max length, but the ones we're interested in certainly don't exceed MAX_PATH. if (uFormat < 0xC000 || uFormat > 0xFFFF) // It's a registered format (you're supposed to verify in-range before calling GetClipboardFormatName()). Also helps performance. *format_name = '\0'; // Don't need the name if it's a standard/CF_* format. else { // v1.0.42.04: // Probably need to call GetClipboardFormatName() rather than comparing directly to uFormat because // MSDN implies that OwnerLink and other registered formats might not always have the same ID under // all OSes (past and future). GetClipboardFormatName(uFormat, format_name, MAX_PATH); // Since RegisterClipboardFormat() is case insensitive, the case might vary. So use stricmp() when // comparing format_name to anything. // "Link Source", "Link Source Descriptor" , and anything else starting with "Link Source" is likely // to be data that should not be attempted to be retrieved because: // 1) It causes unwanted bookmark effects in various versions of MS Word. // 2) Tests show that these formats are on the clipboard only if MS Word is open at the time // ClipboardAll is accessed. That implies they're transitory formats that aren't as essential // or well suited to ClipboardAll as the other formats (but if it weren't for #1 above, this // wouldn't be enough reason to omit it). // 3) Although there is hardly any documentation to be found at MSDN or elsewhere about these formats, // it seems they're related to OLE, with further implications that the data is transitory. // Here are the formats that Word 2002 removes from the clipboard when it the app closes: // 0xC002 ObjectLink >>> Causes WORD bookmarking problem. // 0xC003 OwnerLink // 0xC00D Link Source >>> Causes WORD bookmarking problem. // 0xC00F Link Source Descriptor >>> Doesn't directly cause bookmarking, but probably goes with above. // 0xC0DC Hyperlink if ( !_tcsnicmp(format_name, _T("Link Source"), 11) || !_tcsicmp(format_name, _T("ObjectLink")) || !_tcsicmp(format_name, _T("OwnerLink")) // v1.0.44.07: The following were added to solve interference with MS Outlook's MS Word editor. // If a hotkey like ^F1::ClipboardSave:=ClipboardAll is pressed after pressing Ctrl-C in that // editor (perhaps only when copying HTML), two of the following error dialogs would otherwise // be displayed (this occurs in Outlook 2002 and probably later versions): // "An outgoing call cannot be made since the application is dispatching an input-synchronous call." || !_tcsicmp(format_name, _T("Native")) || !_tcsicmp(format_name, _T("Embed Source")) ) return NULL; if (!_tcsicmp(format_name, _T("MSDEVColumnSelect")) || !_tcsicmp(format_name, _T("MSDEVLineSelect"))) { // v1.1.16: These formats are used by Visual Studio, Scintilla controls and perhaps others for // copying whole lines and rectangular blocks. Because their very presence/absence is used as // a boolean indicator, the data is irrelevant. Presumably for this reason, Scintilla controls // set NULL data, though doing so and then not handling WM_RENDERFORMAT is probably invalid. // Note newer versions of Visual Studio use "VisualStudioEditorOperationsLineCutCopyClipboardTag" // for line copy, but that doesn't need to be handled here because it has non-NULL data (and the // latest unreleased Scintilla [as at 2014-08-19] uses both, so we can discard the long one). // Since we just want to preserve this format's presence, indicate to caller that NULL is okay: if (aNullIsOkay) // i.e. caller passed a variable for us to set. *aNullIsOkay = TRUE; return NULL; } } #ifdef DEBUG_BY_LOGGING_CLIPBOARD_FORMATS _ftprintf(fp, _T("%04X\t%s\n"), uFormat, format_name); // Since fclose() is never called, the program has to exit to close/release the file. #endif #ifndef ENABLE_CLIPBOARDGETDATA_TIMEOUT // v1.1.16: The timeout and retry behaviour of this function is currently disabled, since it does more // harm than good. It previously did NO GOOD WHATSOEVER, because SLEEP_WITHOUT_INTERRUPTION indirectly // calls g_clip.Close() via CLOSE_CLIPBOARD_IF_OPEN, so any subsequent attempts to retrieve data by us // or our caller always fail. The main point of failure where retrying helps is OpenClipboard(), when // another program has the clipboard open -- and that's handled elsewhere. If the timeout is re-enabled // for this function, the following format will need to be excluded to prevent unnecessary delays: // - FileContents (CSTR_FILECONTENTS): MSDN says it is used "to transfer data as if it were a file, // regardless of how it is actually stored". For example, it could be a file inside a zip folder. // However, on Windows 8 it seems to also be present for normal files. It might be possible to // retrieve its data via OleGetClipboard(), though it could be very large. // Just return the data, even if NULL: return GetClipboardData(uFormat); #else HANDLE h; #ifdef _WIN64 DWORD aThreadID = __readgsdword(0x48); // Used to identify if code is called from different thread (AutoHotkey.dll) #else DWORD aThreadID = __readfsdword(0x24); #endif for (DWORD start_time = GetTickCount();;) { // Known failure conditions: // GetClipboardData() apparently fails when the text on the clipboard is greater than a certain size // (Even though GetLastError() reports "Operation completed successfully"). The data size at which // this occurs is somewhere between 20 to 96 MB (perhaps depending on system's memory and CPU speed). if (h = GetClipboardData(uFormat)) // Assign return h; // It failed, so act according to the type of format and the timeout that's in effect. // Certain standard (numerically constant) clipboard formats are known to validly yield NULL from a // call to GetClipboardData(). Never retry these because it would only cause unnecessary delays // (i.e. a failure until timeout). // v1.0.42.04: More importantly, retrying them appears to cause problems with saving a Word/Excel // clipboard via ClipboardAll. if (uFormat == CF_HDROP // This format can fail "normally" for the reasons described at "clipboard_contains_files". || !_tcsicmp(format_name, _T("OwnerLink"))) // Known to validly yield NULL from a call to GetClipboardData(), so don't retry it to avoid having to wait the full timeout period. return NULL; if (g_ClipboardTimeout != -1) // We were not told to wait indefinitely and... if (!g_ClipboardTimeout // ...we were told to make only one attempt, or ... || (int)(g_ClipboardTimeout - (GetTickCount() - start_time)) <= SLEEP_INTERVAL_HALF) //...it timed out. // Above must cast to int or any negative result will be lost due to DWORD type. return NULL; // Use SLEEP_WITHOUT_INTERRUPTION to prevent MainWindowProc() from accepting new hotkeys // during our operation, since a new hotkey subroutine might interfere with // what we're doing here (e.g. if it tries to use the clipboard, or perhaps overwrites // the deref buffer if this object's caller gave it any pointers into that memory area): SLEEP_WITHOUT_INTERRUPTION(INTERVAL_UNSPECIFIED) } #endif }
/* ************************************ * void WINAPI InitMenu(HWND hwnd, HMENU hmenu) * 功能 根据粘贴板中内容的格式,设置菜单项供用户选择显示方式 * 参数 hwnd,窗口句柄 * hmenu,需要设置的菜单句柄 **************************************/ void WINAPI InitMenu(HWND hwnd, HMENU hmenu) { UINT uFormat; char szFormatName[80]; LPCSTR lpFormatName; UINT fuFlags; UINT idMenuItem; // 判断菜单的第一项是不是auto // 所有的显示根据附加到这个POPUP中 if (GetMenuItemID(hmenu, 0) != ID_AUTO) return; // 将除了第一个以外的其他所有菜单项删除 while (GetMenuItemCount(hmenu) > 1) DeleteMenu(hmenu, 1, MF_BYPOSITION); // Auto项是否设置 fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED; CheckMenuItem(hmenu, ID_AUTO, fuFlags); // 检测粘贴板中格式的数量 if (CountClipboardFormats() == 0) return; // 打开粘贴板 if (!OpenClipboard(hwnd)) return; // 为每个格式附加一个菜单项 AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); uFormat = EnumClipboardFormats(0); while (uFormat) { // 程序为每一个格式定义了一个在菜单项中显示的名字 lpFormatName = GetPredefinedClipboardFormatName(uFormat); // 如果程序未定义,获取格式的名字 if (lpFormatName == NULL) { // 注意溢出 if (GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName))) lpFormatName = szFormatName; else lpFormatName = "(unknown)"; } // 是可显示的格式 if (IsDisplayableFormat(uFormat)) { fuFlags = MF_STRING; idMenuItem = uFormat; } else { fuFlags = MF_STRING | MF_GRAYED; idMenuItem = 0; } // 增加菜单项 AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName); // 下一个格式,循环 uFormat = EnumClipboardFormats(uFormat); } CloseClipboard(); }
/* static */ const char* VBoxDnDDataObject::ClipboardFormatToString(CLIPFORMAT fmt) { #ifdef VBOX_DND_DEBUG_FORMATS char szFormat[128]; if (GetClipboardFormatName(fmt, szFormat, sizeof(szFormat))) LogFlowFunc(("wFormat=%RI16, szName=%s\n", fmt, szFormat)); #endif switch (fmt) { case 1: return "CF_TEXT"; case 2: return "CF_BITMAP"; case 3: return "CF_METAFILEPICT"; case 4: return "CF_SYLK"; case 5: return "CF_DIF"; case 6: return "CF_TIFF"; case 7: return "CF_OEMTEXT"; case 8: return "CF_DIB"; case 9: return "CF_PALETTE"; case 10: return "CF_PENDATA"; case 11: return "CF_RIFF"; case 12: return "CF_WAVE"; case 13: return "CF_UNICODETEXT"; case 14: return "CF_ENHMETAFILE"; case 15: return "CF_HDROP"; case 16: return "CF_LOCALE"; case 17: return "CF_DIBV5"; case 18: return "CF_MAX"; case 49158: return "FileName"; case 49159: return "FileNameW"; case 49161: return "DATAOBJECT"; case 49171: return "Ole Private Data"; case 49314: return "Shell Object Offsets"; case 49316: return "File Contents"; case 49317: return "File Group Descriptor"; case 49323: return "Preferred Drop Effect"; case 49380: return "Shell Object Offsets"; case 49382: return "FileContents"; case 49383: return "FileGroupDescriptor"; case 49389: return "Preferred DropEffect"; case 49268: return "Shell IDList Array"; case 49619: return "RenPrivateFileAttachments"; default: break; } return "unknown"; }
PyObject* PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args) { int clip; HANDLE handle; int size; void* data; PyObject* result; int verbose = 0; /* debugging; will be removed in future versions */ if (!PyArg_ParseTuple(args, "|i", &verbose)) return NULL; clip = OpenClipboard(NULL); /* FIXME: check error status */ if (verbose) { UINT format = EnumClipboardFormats(0); char buffer[200]; char* result; while (format != 0) { if (GetClipboardFormatName(format, buffer, sizeof buffer) > 0) result = buffer; else switch (format) { case CF_BITMAP: result = "CF_BITMAP"; break; case CF_DIB: result = "CF_DIB"; break; case CF_DIF: result = "CF_DIF"; break; case CF_ENHMETAFILE: result = "CF_ENHMETAFILE"; break; case CF_HDROP: result = "CF_HDROP"; break; case CF_LOCALE: result = "CF_LOCALE"; break; case CF_METAFILEPICT: result = "CF_METAFILEPICT"; break; case CF_OEMTEXT: result = "CF_OEMTEXT"; break; case CF_OWNERDISPLAY: result = "CF_OWNERDISPLAY"; break; case CF_PALETTE: result = "CF_PALETTE"; break; case CF_PENDATA: result = "CF_PENDATA"; break; case CF_RIFF: result = "CF_RIFF"; break; case CF_SYLK: result = "CF_SYLK"; break; case CF_TEXT: result = "CF_TEXT"; break; case CF_WAVE: result = "CF_WAVE"; break; case CF_TIFF: result = "CF_TIFF"; break; case CF_UNICODETEXT: result = "CF_UNICODETEXT"; break; default: sprintf(buffer, "[%d]", format); result = buffer; break; } printf("%s (%d)\n", result, format); format = EnumClipboardFormats(format); } } handle = GetClipboardData(CF_DIB); if (!handle) { /* FIXME: add CF_HDROP support to allow cut-and-paste from the explorer */ CloseClipboard(); Py_INCREF(Py_None); return Py_None; } size = GlobalSize(handle); data = GlobalLock(handle); #if 0 /* calculate proper size for string formats */ if (format == CF_TEXT || format == CF_OEMTEXT) size = strlen(data); else if (format == CF_UNICODETEXT) size = wcslen(data) * 2; #endif result = PyBytes_FromStringAndSize(data, size); GlobalUnlock(handle); CloseClipboard(); return result; }
BOOL CClipboardBackup::Backup(bool clear) { if( m_bFilled ) return FALSE; if( !::OpenClipboard(NULL) ) return FALSE; BOOL b; UINT format = 0; while( (format = ::EnumClipboardFormats(format)) != 0 ) { ClipboardData data; data.m_nFormat = format; // skip some formats if( format == CF_BITMAP || format == CF_METAFILEPICT || format == CF_PALETTE || format == CF_OWNERDISPLAY || format == CF_DSPMETAFILEPICT || format == CF_DSPBITMAP || ( format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST ) ) { continue; } // get format name if( format <= 14 ) data.m_szFormatName[0] = 0; else if( GetClipboardFormatName(format, data.m_szFormatName, 100) == 0 ) data.m_szFormatName[0] = 0; // get handle HANDLE hMem = ::GetClipboardData( format ); if( hMem == NULL ) continue; // copy handle switch( format ) { case CF_ENHMETAFILE: case CF_DSPENHMETAFILE: data.m_hData = ::CopyMetaFile((HMETAFILE)hMem, NULL); break; default: { int size = ::GlobalSize(hMem); LPVOID pMem = ::GlobalLock( hMem ); data.m_hData = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, size ); LPVOID pNewMem = ::GlobalLock( data.m_hData ); memcpy(pNewMem, pMem, size); ::GlobalUnlock(hMem); ::GlobalUnlock(data.m_hData); } } m_lstData.AddTail(data); } if( clear ) { b = ::EmptyClipboard(); ATLASSERT(b); } b = ::CloseClipboard(); ATLASSERT(b); m_bFilled = TRUE; return TRUE; }
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { AssertPtr(pCtx); const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; LRESULT rc = 0; switch (msg) { case WM_CLIPBOARDUPDATE: { Log(("WM_CLIPBOARDUPDATE\n")); if (GetClipboardOwner() != hwnd) { /* Clipboard was updated by another application. */ uint32_t uFormats; int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); if (RT_SUCCESS(vboxrc)) vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); } } break; case WM_CHANGECBCHAIN: { if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) { rc = DefWindowProc(hwnd, msg, wParam, lParam); break; } HWND hWndRemoved = (HWND)wParam; HWND hWndNext = (HWND)lParam; LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd)); if (hWndRemoved == pWinCtx->hWndNextInChain) { /* The window that was next to our in the chain is being removed. * Relink to the new next window. */ pWinCtx->hWndNextInChain = hWndNext; } else { if (pWinCtx->hWndNextInChain) { /* Pass the message further. */ DWORD_PTR dwResult; rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); if (!rc) rc = (LRESULT)dwResult; } } } break; case WM_DRAWCLIPBOARD: { LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); if (GetClipboardOwner() != hwnd) { /* Clipboard was updated by another application. */ /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ uint32_t uFormats; int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); if (RT_SUCCESS(vboxrc)) vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); } if (pWinCtx->hWndNextInChain) { /* Pass the message to next windows in the clipboard chain. */ SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); } } break; case WM_TIMER: { if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) break; HWND hViewer = GetClipboardViewer(); /* Re-register ourselves in the clipboard chain if our last ping * timed out or there seems to be no valid chain. */ if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) { VBoxClipboardWinRemoveFromCBChain(pWinCtx); VBoxClipboardWinAddToCBChain(pWinCtx); } /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be * processed by ourselves to the chain. */ pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; hViewer = GetClipboardViewer(); if (hViewer) SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); } break; case WM_CLOSE: { /* Do nothing. Ignore the message. */ } break; case WM_RENDERFORMAT: { /* Insert the requested clipboard format data into the clipboard. */ uint32_t fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE; const UINT cfFormat = (UINT)wParam; switch (cfFormat) { case CF_UNICODETEXT: fFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; break; case CF_DIB: fFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP; break; #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST case CF_HDROP: fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; break; #endif default: if (cfFormat >= 0xC000) /** @todo r=andy Explain. */ { TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */ int cActual = GetClipboardFormatName(cfFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR)); if (cActual) { if (strcmp(szFormatName, "HTML Format") == 0) fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML; } } break; } LogFunc(("WM_RENDERFORMAT: format=%u -> fFormat=0x%x\n", cfFormat, fFormat)); if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE) { /* Unsupported clipboard format is requested. */ LogRel(("Clipboard: Unsupported clipboard format requested (0x%x)\n", fFormat)); VBoxClipboardWinClear(); } #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST else if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) { } #endif else { const uint32_t cbPrealloc = _4K; uint32_t cb = 0; /* Preallocate a buffer, most of small text transfers will fit into it. */ HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); if (hMem) { void *pMem = GlobalLock(hMem); LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); if (pMem) { /* Read the host data to the preallocated buffer. */ int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb); LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); if (RT_SUCCESS(vboxrc)) { if (cb == 0) { /* 0 bytes returned means the clipboard is empty. * Deallocate the memory and set hMem to NULL to get to * the clipboard empty code path. */ GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } else if (cb > cbPrealloc) { GlobalUnlock(hMem); /* The preallocated buffer is too small, adjust the size. */ hMem = GlobalReAlloc(hMem, cb, 0); LogFlowFunc(("Reallocated hMem = %p\n", hMem)); if (hMem) { pMem = GlobalLock(hMem); LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); if (pMem) { /* Read the host data to the preallocated buffer. */ uint32_t cbNew = 0; vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew); LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); if (RT_SUCCESS(vboxrc) && cbNew <= cb) { cb = cbNew; } else { GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } } else { GlobalFree(hMem); hMem = NULL; } } } if (hMem) { /* pMem is the address of the data. cb is the size of returned data. */ /* Verify the size of returned text, the memory block for clipboard * must have the exact string size. */ if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { size_t cbActual = 0; HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); if (FAILED(hrc)) { /* Discard invalid data. */ GlobalUnlock(hMem); GlobalFree(hMem); hMem = NULL; } else { /* cbActual is the number of bytes, excluding those used * for the terminating null character. */ cb = (uint32_t)(cbActual + 2); } } } if (hMem) { GlobalUnlock(hMem); hMem = GlobalReAlloc(hMem, cb, 0); LogFlowFunc(("Reallocated hMem = %p\n", hMem)); if (hMem) { /* 'hMem' contains the host clipboard data. * size is 'cb' and format is 'format'. */ HANDLE hClip = SetClipboardData(cfFormat, hMem); LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); if (hClip) { /* The hMem ownership has gone to the system. Finish the processing. */ break; } /* Cleanup follows. */ } } } if (hMem) GlobalUnlock(hMem); } if (hMem) GlobalFree(hMem); } /* Something went wrong. */ VBoxClipboardWinClear(); } } break; case WM_RENDERALLFORMATS: { /* Do nothing. The clipboard formats will be unavailable now, because the * windows is to be destroyed and therefore the guest side becomes inactive. */ int vboxrc = VBoxClipboardWinOpen(hwnd); if (RT_SUCCESS(vboxrc)) { VBoxClipboardWinClear(); VBoxClipboardWinClose(); } } break; case VBOX_CLIPBOARD_WM_SET_FORMATS: { /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam; LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats)); int vboxrc = VBoxClipboardWinOpen(hwnd); if (RT_SUCCESS(vboxrc)) { VBoxClipboardWinClear(); HANDLE hClip = NULL; if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) hClip = SetClipboardData(CF_UNICODETEXT, NULL); if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) hClip = SetClipboardData(CF_DIB, NULL); if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML) { UINT format = RegisterClipboardFormat("HTML Format"); if (format != 0) hClip = SetClipboardData(format, NULL); } #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) hClip = SetClipboardData(CF_HDROP, NULL); #endif /** @todo Implement more flexible clipboard precedence for supported formats. */ if (hClip == NULL) LogRel(("Clipboard: Unsupported format(s) from host (0x%x), ignoring\n", fFormats)); VBoxClipboardWinClose(); LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); } } break; case VBOX_CLIPBOARD_WM_READ_DATA: { /* Send data in the specified format to the host. */ uint32_t u32Formats = (uint32_t)lParam; HANDLE hClip = NULL; LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); int vboxrc = VBoxClipboardWinOpen(hwnd); if (RT_SUCCESS(vboxrc)) { if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) { hClip = GetClipboardData(CF_DIB); if (hClip != NULL) { LPVOID lp = GlobalLock(hClip); if (lp != NULL) { vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize(hClip)); GlobalUnlock(hClip); } else { hClip = NULL; } } } else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { hClip = GetClipboardData(CF_UNICODETEXT); if (hClip != NULL) { LPWSTR uniString = (LPWSTR)GlobalLock(hClip); if (uniString != NULL) { vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW(uniString) + 1) * 2); GlobalUnlock(hClip); } else { hClip = NULL; } } } else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) { UINT format = RegisterClipboardFormat("HTML Format"); if (format != 0) { hClip = GetClipboardData(format); if (hClip != NULL) { LPVOID lp = GlobalLock(hClip); if (lp != NULL) { vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip)); GlobalUnlock(hClip); } else { hClip = NULL; } } } } #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) { hClip = GetClipboardData(CF_HDROP); if (hClip) { HDROP hDrop = (HDROP)GlobalLock(hClip); if (hDrop) { /* vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, );*/ GlobalUnlock(hClip); } else { hClip = NULL; } } } #endif VBoxClipboardWinClose(); } if (hClip == NULL) { /* Requested clipboard format is not available, send empty data. */ VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); } } break; case WM_DESTROY: { VBoxClipboardWinRemoveFromCBChain(pWinCtx); if (pWinCtx->oldAPI.timerRefresh) KillTimer(pWinCtx->hWnd, 0); /* * don't need to call PostQuitMessage cause * the VBoxTray already finished a message loop */ } break; default: { rc = DefWindowProc(hwnd, msg, wParam, lParam); } break; } #ifndef DEBUG_andy LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc)); #endif return rc; }