[CLIPBRD]: Finish the implementation of clipboard write file support. There may be room for improvements.

CORE-10852 #resolve

svn path=/trunk/; revision=70735
This commit is contained in:
Hermès Bélusca-Maïto 2016-02-13 20:57:39 +00:00
parent df2659d0ac
commit 60c090d24a
4 changed files with 129 additions and 89 deletions

View file

@ -193,7 +193,7 @@ void UpdateDisplayMenu(void)
uFormat = EnumClipboardFormats(0);
while (uFormat)
{
RetrieveClipboardFormatName(Globals.hInstance, uFormat, szFormatName, ARRAYSIZE(szFormatName));
RetrieveClipboardFormatName(Globals.hInstance, uFormat, TRUE, szFormatName, ARRAYSIZE(szFormatName));
if (!IsClipboardFormatSupported(uFormat))
{

View file

@ -8,73 +8,61 @@
#include "precomp.h"
int GetPredefinedClipboardFormatName(HINSTANCE hInstance, UINT uFormat, LPWSTR lpszFormat, UINT cch)
static int
GetPredefinedClipboardFormatName(HINSTANCE hInstance,
UINT uFormat,
BOOL Unicode,
PVOID lpszFormat,
UINT cch)
{
static
struct FORMAT_NAME
{
UINT uFormat;
UINT uResID;
} uFormatList[] = {
/* Table sorted in increasing order of CF_xxx values, please keep it this way! */
{CF_TEXT , STRING_CF_TEXT }, // 1
{CF_BITMAP , STRING_CF_BITMAP }, // 2
{CF_METAFILEPICT, STRING_CF_METAFILEPICT}, // 3
{CF_SYLK , STRING_CF_SYLK }, // 4
{CF_DIF , STRING_CF_DIF }, // 5
{CF_TIFF , 0/*STRING_CF_TIFF*/ }, // 6
{CF_OEMTEXT , STRING_CF_OEMTEXT }, // 7
{CF_DIB , STRING_CF_DIB }, // 8
{CF_PALETTE , STRING_CF_PALETTE }, // 9
{CF_PENDATA , 0/*STRING_CF_PENDATA*/ }, // 10
{CF_RIFF , 0/*STRING_CF_RIFF*/ }, // 11
{CF_WAVE , 0/*STRING_CF_WAVE*/ }, // 12
{CF_UNICODETEXT , STRING_CF_UNICODETEXT }, // 13
{CF_ENHMETAFILE , STRING_CF_ENHMETAFILE }, // 14
#if(WINVER >= 0x0400)
{CF_HDROP , STRING_CF_HDROP }, // 15
{CF_LOCALE , STRING_CF_LOCALE }, // 16
#endif
#if(WINVER >= 0x0500)
{CF_DIBV5 , STRING_CF_DIBV5 }, // 17
#endif
};
switch (uFormat)
{
case CF_TEXT:
{
return LoadStringW(hInstance, STRING_CF_TEXT, lpszFormat, cch);
}
case CF_BITMAP:
{
return LoadStringW(hInstance, STRING_CF_BITMAP, lpszFormat, cch);
}
case CF_OEMTEXT:
{
return LoadStringW(hInstance, STRING_CF_OEMTEXT, lpszFormat, cch);
}
case CF_UNICODETEXT:
{
return LoadStringW(hInstance, STRING_CF_UNICODETEXT, lpszFormat, cch);
}
case CF_DIB:
{
return LoadStringW(hInstance, STRING_CF_DIB, lpszFormat, cch);
}
case CF_LOCALE:
{
return LoadStringW(hInstance, STRING_CF_LOCALE, lpszFormat, cch);
}
case CF_ENHMETAFILE:
{
return LoadStringW(hInstance, STRING_CF_ENHMETAFILE, lpszFormat, cch);
}
case CF_METAFILEPICT:
{
return LoadStringW(hInstance, STRING_CF_METAFILEPICT, lpszFormat, cch);
}
case CF_PALETTE:
{
return LoadStringW(hInstance, STRING_CF_PALETTE, lpszFormat, cch);
}
case CF_TEXT: case CF_BITMAP: case CF_METAFILEPICT:
case CF_SYLK: case CF_DIF: // case CF_TIFF:
case CF_OEMTEXT: case CF_DIB: case CF_PALETTE:
// case CF_PENDATA: // case CF_RIFF: // case CF_WAVE:
case CF_UNICODETEXT: case CF_ENHMETAFILE:
#if(WINVER >= 0x0400)
case CF_HDROP: case CF_LOCALE:
#endif
#if(WINVER >= 0x0500)
case CF_DIBV5:
#endif
{
return LoadStringW(hInstance, STRING_CF_DIBV5, lpszFormat, cch);
}
case CF_SYLK:
{
return LoadStringW(hInstance, STRING_CF_SYLK, lpszFormat, cch);
}
case CF_DIF:
{
return LoadStringW(hInstance, STRING_CF_DIF, lpszFormat, cch);
}
case CF_HDROP:
{
return LoadStringW(hInstance, STRING_CF_HDROP, lpszFormat, cch);
if (Unicode)
return LoadStringW(hInstance, uFormatList[uFormat-1].uResID, (LPWSTR)lpszFormat, cch);
else
return LoadStringA(hInstance, uFormatList[uFormat-1].uResID, (LPSTR)lpszFormat, cch);
}
default:
@ -84,13 +72,24 @@ int GetPredefinedClipboardFormatName(HINSTANCE hInstance, UINT uFormat, LPWSTR l
}
}
void RetrieveClipboardFormatName(HINSTANCE hInstance, UINT uFormat, LPWSTR lpszFormat, UINT cch)
void
RetrieveClipboardFormatName(HINSTANCE hInstance,
UINT uFormat,
BOOL Unicode,
PVOID lpszFormat,
UINT cch)
{
if (!GetPredefinedClipboardFormatName(hInstance, uFormat, lpszFormat, cch))
if (!GetPredefinedClipboardFormatName(hInstance, uFormat, Unicode, lpszFormat, cch))
{
if (!GetClipboardFormatNameW(uFormat, lpszFormat, cch))
if (Unicode)
{
LoadStringW(hInstance, STRING_CF_UNKNOWN, lpszFormat, cch);
if (!GetClipboardFormatNameW(uFormat, (LPWSTR)lpszFormat, cch))
LoadStringW(hInstance, STRING_CF_UNKNOWN, (LPWSTR)lpszFormat, cch);
}
else
{
if (!GetClipboardFormatNameA(uFormat, (LPSTR)lpszFormat, cch))
LoadStringA(hInstance, STRING_CF_UNKNOWN, (LPSTR)lpszFormat, cch);
}
}
}

View file

@ -6,8 +6,13 @@
* PROGRAMMERS: Ricardo Hanke
*/
int GetPredefinedClipboardFormatName(HINSTANCE hInstance, UINT uFormat, LPWSTR lpszFormat, UINT cch);
void RetrieveClipboardFormatName(HINSTANCE hInstance, UINT uFormat, LPWSTR lpszFormat, UINT cch);
void
RetrieveClipboardFormatName(HINSTANCE hInstance,
UINT uFormat,
BOOL Unicode,
PVOID lpszFormat,
UINT cch);
void DeleteClipboardContent(void);
UINT GetAutomaticClipboardFormat(void);
BOOL IsClipboardFormatSupported(UINT uFormat);

View file

@ -81,6 +81,39 @@ static BOOL ClipboardReadMemory(HANDLE hFile, DWORD dwFormat, DWORD dwOffset, DW
return TRUE;
}
static BOOL ClipboardWriteMemory(HANDLE hFile, DWORD dwFormat, DWORD dwOffset, PDWORD pdwLength)
{
HGLOBAL hData;
LPVOID lpData;
DWORD dwBytesWritten;
hData = GetClipboardData(dwFormat);
if (!hData)
return FALSE;
lpData = GlobalLock(hData);
if (!lpData)
return FALSE;
*pdwLength = GlobalSize(hData);
if (SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
{
GlobalUnlock(hData);
return FALSE;
}
if (!WriteFile(hFile, lpData, *pdwLength, &dwBytesWritten, NULL))
{
GlobalUnlock(hData);
return FALSE;
}
GlobalUnlock(hData);
return TRUE;
}
static BOOL ClipboardReadPalette(HANDLE hFile, DWORD dwOffset, DWORD dwLength)
{
LPLOGPALETTE lpPalette;
@ -286,7 +319,6 @@ void ReadClipboardFile(LPCWSTR lpFileName)
SizeOfFormatHeader = sizeof(CLIPFORMATHEADER);
pClipFileHeader = &ClipFileHeader;
pClipFormatArray = &ClipFormatArray;
// MessageBox(Globals.hMainWnd, L"We have a Win3.11 clipboard file!", L"File format", 0);
break;
case CLIP_FMT_NT:
@ -295,7 +327,6 @@ void ReadClipboardFile(LPCWSTR lpFileName)
SizeOfFormatHeader = sizeof(NTCLIPFORMATHEADER);
pClipFileHeader = &NtClipFileHeader;
pClipFormatArray = &NtClipFormatArray;
// MessageBox(Globals.hMainWnd, L"We have a WinNT clipboard file!", L"File format", 0);
break;
default:
@ -436,8 +467,6 @@ void WriteClipboardFile(LPCWSTR lpFileName, WORD wFileIdentifier)
DWORD dwBytesWritten;
int i;
WCHAR szFormatName[MAX_FMT_NAME_LEN];
/* Create the file for write access */
hFile = CreateFileW(lpFileName, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
@ -457,7 +486,6 @@ void WriteClipboardFile(LPCWSTR lpFileName, WORD wFileIdentifier)
SizeOfFormatHeader = sizeof(CLIPFORMATHEADER);
pClipFileHeader = &ClipFileHeader;
pClipFormatArray = &ClipFormatArray;
// MessageBox(Globals.hMainWnd, L"We write a Win3.11 clipboard file!", L"File format", 0);
ClipFileHeader.wFileIdentifier = CLIP_FMT_31; // wFileIdentifier
ClipFileHeader.wFormatCount = wFormatCount;
@ -469,7 +497,6 @@ void WriteClipboardFile(LPCWSTR lpFileName, WORD wFileIdentifier)
SizeOfFormatHeader = sizeof(NTCLIPFORMATHEADER);
pClipFileHeader = &NtClipFileHeader;
pClipFormatArray = &NtClipFormatArray;
// MessageBox(Globals.hMainWnd, L"We write a WinNT clipboard file!", L"File format", 0);
NtClipFileHeader.wFileIdentifier = CLIP_FMT_NT; // wFileIdentifier
NtClipFileHeader.wFormatCount = wFormatCount;
@ -497,35 +524,43 @@ void WriteClipboardFile(LPCWSTR lpFileName, WORD wFileIdentifier)
dwFormatID = EnumClipboardFormats(0);
while (dwFormatID)
{
if (i >= wFormatCount) assert(FALSE); // break;
if (i >= wFormatCount)
{
/* Must never happen! */
assert(FALSE);
break;
}
RetrieveClipboardFormatName(Globals.hInstance, dwFormatID, szFormatName, ARRAYSIZE(szFormatName));
/* Write the clipboard data at the specified offset, and retrieve its length */
if (!ClipboardWriteMemory(hFile, dwFormatID, dwOffData, &dwLenData))
goto Cont;
// TODO: Copy the format name string into the format header,
// possibly converting into ANSI for Win3.1 format, and render
// in the file the different type of data. From the renderers
// we retrieve the real size of the data into 'dwLenData'.
/* TODO: Write the data stream at 'dwOffData' */
dwLenData = 0;
/* Write format data */
/* Write the format data header */
switch (wFileIdentifier)
{
case CLIP_FMT_31:
ZeroMemory(pClipFormatArray, sizeof(CLIPFORMATHEADER));
((CLIPFORMATHEADER*)pClipFormatArray)->dwFormatID = dwFormatID;
((CLIPFORMATHEADER*)pClipFormatArray)->dwLenData = dwLenData;
((CLIPFORMATHEADER*)pClipFormatArray)->dwOffData = dwOffData;
// szName = ((CLIPFORMATHEADER*)pClipFormatArray)->szName;
ZeroMemory( ((CLIPFORMATHEADER*)pClipFormatArray)->szName , sizeof(((CLIPFORMATHEADER*)pClipFormatArray)->szName) );
RetrieveClipboardFormatName(Globals.hInstance,
dwFormatID,
FALSE,
((CLIPFORMATHEADER*)pClipFormatArray)->szName,
ARRAYSIZE(((CLIPFORMATHEADER*)pClipFormatArray)->szName));
break;
case CLIP_FMT_NT:
case CLIP_FMT_BK:
ZeroMemory(pClipFormatArray, sizeof(NTCLIPFORMATHEADER));
((NTCLIPFORMATHEADER*)pClipFormatArray)->dwFormatID = dwFormatID;
((NTCLIPFORMATHEADER*)pClipFormatArray)->dwLenData = dwLenData;
((NTCLIPFORMATHEADER*)pClipFormatArray)->dwOffData = dwOffData;
// szName = ((NTCLIPFORMATHEADER*)pClipFormatArray)->szName;
ZeroMemory( ((NTCLIPFORMATHEADER*)pClipFormatArray)->szName , sizeof(((NTCLIPFORMATHEADER*)pClipFormatArray)->szName) );
RetrieveClipboardFormatName(Globals.hInstance,
dwFormatID,
TRUE,
((NTCLIPFORMATHEADER*)pClipFormatArray)->szName,
ARRAYSIZE(((NTCLIPFORMATHEADER*)pClipFormatArray)->szName));
break;
}
@ -544,6 +579,7 @@ void WriteClipboardFile(LPCWSTR lpFileName, WORD wFileIdentifier)
/* Adjust the offset for the next data stream */
dwOffData += dwLenData;
Cont:
i++;
dwFormatID = EnumClipboardFormats(dwFormatID);
}