From 60c090d24a4b347481ba35bdcb6c224bcbc026d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 13 Feb 2016 20:57:39 +0000 Subject: [PATCH] [CLIPBRD]: Finish the implementation of clipboard write file support. There may be room for improvements. CORE-10852 #resolve svn path=/trunk/; revision=70735 --- reactos/base/applications/clipbrd/clipbrd.c | 2 +- reactos/base/applications/clipbrd/cliputils.c | 131 +++++++++--------- reactos/base/applications/clipbrd/cliputils.h | 9 +- reactos/base/applications/clipbrd/fileutils.c | 76 +++++++--- 4 files changed, 129 insertions(+), 89 deletions(-) diff --git a/reactos/base/applications/clipbrd/clipbrd.c b/reactos/base/applications/clipbrd/clipbrd.c index 97e22de35b4..42e5be3adfe 100644 --- a/reactos/base/applications/clipbrd/clipbrd.c +++ b/reactos/base/applications/clipbrd/clipbrd.c @@ -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)) { diff --git a/reactos/base/applications/clipbrd/cliputils.c b/reactos/base/applications/clipbrd/cliputils.c index ca11e072ddb..e13348a9ebe 100644 --- a/reactos/base/applications/clipbrd/cliputils.c +++ b/reactos/base/applications/clipbrd/cliputils.c @@ -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); } } } diff --git a/reactos/base/applications/clipbrd/cliputils.h b/reactos/base/applications/clipbrd/cliputils.h index 904be569dae..28d64b8b3e7 100644 --- a/reactos/base/applications/clipbrd/cliputils.h +++ b/reactos/base/applications/clipbrd/cliputils.h @@ -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); diff --git a/reactos/base/applications/clipbrd/fileutils.c b/reactos/base/applications/clipbrd/fileutils.c index 3c41333880d..17ffa3e4724 100644 --- a/reactos/base/applications/clipbrd/fileutils.c +++ b/reactos/base/applications/clipbrd/fileutils.c @@ -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); }