/* * clipboard helper functions * * Copyright 2000 Juergen Schmied <juergen.schmied@debitel.de> * * For copy & paste functions within contextmenus does the shell use * the OLE clipboard functions in combination with dataobjects. * The OLE32.DLL gets loaded with LoadLibrary * * - a right mousebutton-copy sets the following formats: * classic: * Shell IDList Array * Prefered Drop Effect * Shell Object Offsets * HDROP * FileName * ole: * OlePrivateData (ClipboardDataObjectInterface) * */ #include <string.h> #include "debugtools.h" #include "pidl.h" #include "wine/undocshell.h" #include "shell32_main.h" DEFAULT_DEBUG_CHANNEL(shell) static int refClipCount = 0; static HINSTANCE hShellOle32 = 0; /************************************************************************** * InitShellOle * * */ void InitShellOle(void) { } /************************************************************************** * FreeShellOle * * unload OLE32.DLL */ void FreeShellOle(void) { if (!--refClipCount) { pOleUninitialize(); FreeLibrary(hShellOle32); } } /************************************************************************** * LoadShellOle * * make sure OLE32.DLL is loaded */ BOOL GetShellOle(void) { if(!refClipCount) { hShellOle32 = LoadLibraryA("ole32.dll"); if(hShellOle32) { pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize"); pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize"); pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop"); pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop"); pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop"); pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium"); pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard"); pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard"); pOleInitialize(NULL); refClipCount++; } } return TRUE; } /************************************************************************** * RenderHDROP * * creates a CF_HDROP structure */ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { int i; int rootsize = 0,size = 0; char szRootPath[MAX_PATH]; char szFileName[MAX_PATH]; HGLOBAL hGlobal; DROPFILES *pDropFiles; int offset; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); /* get the size needed */ size = sizeof(DROPFILES); SHGetPathFromIDListA(pidlRoot, szRootPath); PathAddBackslashA(szRootPath); rootsize = strlen(szRootPath); for (i=0; i<cidl;i++) { _ILSimpleGetText(apidl[i], szFileName, MAX_PATH); size += rootsize + strlen(szFileName) + 1; } size++; /* Fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; pDropFiles = (DROPFILES *)GlobalLock(hGlobal); pDropFiles->pFiles = sizeof(DROPFILES); pDropFiles->fWide = FALSE; offset = pDropFiles->pFiles; strcpy(szFileName, szRootPath); for (i=0; i<cidl;i++) { _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize); size = strlen(szFileName) + 1; strcpy(((char*)pDropFiles)+offset, szFileName); offset += size; } ((char*)pDropFiles)[offset] = 0; GlobalUnlock(hGlobal); return hGlobal; } HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { int i,offset = 0, sizePidl, size; HGLOBAL hGlobal; LPCIDA pcida; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); /* get the size needed */ size = sizeof(CIDA) + sizeof (UINT)*(cidl); /* header */ size += ILGetSize (pidlRoot); /* root pidl */ for(i=0; i<cidl; i++) { size += ILGetSize(apidl[i]); /* child pidls */ } /* fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; pcida = GlobalLock (hGlobal); pcida->cidl = cidl; /* root pidl */ offset = sizeof(CIDA) + sizeof (UINT)*(cidl); pcida->aoffset[0] = offset; /* first element */ sizePidl = ILGetSize (pidlRoot); memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl); offset += sizePidl; for(i=0; i<cidl; i++) /* child pidls */ { pcida->aoffset[i+1] = offset; sizePidl = ILGetSize(apidl[i]); memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl); offset += sizePidl; } GlobalUnlock(hGlobal); return hGlobal; } HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { FIXME("\n"); return 0; } HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { FIXME("\n"); return 0; } HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { FIXME("\n"); return 0; } HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) { int len, size = 0; char szTemp[MAX_PATH], *szFileName; HGLOBAL hGlobal; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); /* build name of first file */ SHGetPathFromIDListA(pidlRoot, szTemp); PathAddBackslashA(szTemp); len = strlen(szTemp); _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len); size = strlen(szTemp) + 1; /* fill the structure */ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); if(!hGlobal) return hGlobal; szFileName = (char *)GlobalLock(hGlobal); GlobalUnlock(hGlobal); return hGlobal; } HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags) { DWORD * pdwFlag; HGLOBAL hGlobal; TRACE("(0x%08lx)\n", dwFlags); hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD)); if(!hGlobal) return hGlobal; pdwFlag = (DWORD*)GlobalLock(hGlobal); *pdwFlag = dwFlags; GlobalUnlock(hGlobal); return hGlobal; } /************************************************************************** * IsDataInClipboard * * checks if there is something in the clipboard we can use */ BOOL IsDataInClipboard (HWND hwnd) { BOOL ret = FALSE; if (OpenClipboard(hwnd)) { if (GetOpenClipboardWindow()) { ret = IsClipboardFormatAvailable(CF_TEXT); } CloseClipboard(); } return ret; }