ReactOS 0.4.15-dev-7098-ge0c17c3
cliputils.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Clipboard Viewer
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Clipboard helper functions.
5 * COPYRIGHT: Copyright 2015-2018 Ricardo Hanke
6 * Copyright 2015-2018 Hermes Belusca-Maito
7 */
8
9#include "precomp.h"
10
13 IN BOOL bUnicode,
14 IN UINT uMsg,
17{
18 HWND hwndOwner;
19
20 hwndOwner = GetClipboardOwner();
21 if (!hwndOwner)
22 return GetLastError();
23
24 if (bUnicode)
25 return SendMessageW(hwndOwner, uMsg, wParam, lParam);
26 else
27 return SendMessageA(hwndOwner, uMsg, wParam, lParam);
28}
29
30static int
32 UINT uFormat,
33 BOOL Unicode,
34 PVOID lpszFormat,
35 UINT cch)
36{
37 static
38 struct FORMAT_NAME
39 {
40 UINT uFormat;
41 UINT uResID;
42 } uFormatList[] = {
43 /* Table sorted in increasing order of CF_xxx values, please keep it this way! */
44 {CF_TEXT , STRING_CF_TEXT }, // 1
47 {CF_SYLK , STRING_CF_SYLK }, // 4
48 {CF_DIF , STRING_CF_DIF }, // 5
49 {CF_TIFF , 0/*STRING_CF_TIFF*/ }, // 6
51 {CF_DIB , STRING_CF_DIB }, // 8
53 {CF_PENDATA , 0/*STRING_CF_PENDATA*/ }, // 10
54 {CF_RIFF , 0/*STRING_CF_RIFF*/ }, // 11
55 {CF_WAVE , 0/*STRING_CF_WAVE*/ }, // 12
58#if(WINVER >= 0x0400)
59 {CF_HDROP , STRING_CF_HDROP }, // 15
60 {CF_LOCALE , STRING_CF_LOCALE }, // 16
61#endif
62#if(WINVER >= 0x0500)
63 {CF_DIBV5 , STRING_CF_DIBV5 }, // 17
64#endif
65 };
66
67 switch (uFormat)
68 {
69 case CF_TEXT: case CF_BITMAP: case CF_METAFILEPICT:
70 case CF_SYLK: case CF_DIF: // case CF_TIFF:
71 case CF_OEMTEXT: case CF_DIB: case CF_PALETTE:
72 // case CF_PENDATA: // case CF_RIFF: // case CF_WAVE:
74#if(WINVER >= 0x0400)
75 case CF_HDROP: case CF_LOCALE:
76#endif
77#if(WINVER >= 0x0500)
78 case CF_DIBV5:
79#endif
80 {
81 if (Unicode)
82 return LoadStringW(hInstance, uFormatList[uFormat-1].uResID, (LPWSTR)lpszFormat, cch);
83 else
84 return LoadStringA(hInstance, uFormatList[uFormat-1].uResID, (LPSTR)lpszFormat, cch);
85 }
86
87 default:
88 {
89 return 0;
90 }
91 }
92}
93
94void
96 UINT uFormat,
97 BOOL Unicode,
98 PVOID lpszFormat,
99 UINT cch)
100{
101 ZeroMemory(lpszFormat, cch * (Unicode ? sizeof(WCHAR) : sizeof(CHAR)));
102
103 /* Check for predefined clipboard format */
104 if (GetPredefinedClipboardFormatName(hInstance, uFormat, Unicode, lpszFormat, cch) != 0)
105 return;
106
107 /* Check for owner-display format */
108 if (uFormat == CF_OWNERDISPLAY)
109 {
111 (WPARAM)cch, (LPARAM)lpszFormat) != 0)
112 {
113 if (Unicode)
115 else
117 }
118 return;
119 }
120
121 /* Fallback to registered clipboard format */
122 if (Unicode)
123 {
124 if (!GetClipboardFormatNameW(uFormat, (LPWSTR)lpszFormat, cch))
126 }
127 else
128 {
129 if (!GetClipboardFormatNameA(uFormat, (LPSTR)lpszFormat, cch))
131 }
132}
133
135{
137 {
139 return;
140 }
141
142 if (!EmptyClipboard())
143 {
145 }
146
148}
149
151{
152 static UINT uFormatList[] =
153 {
156 CF_TEXT,
160 CF_DIBV5,
161 CF_DIB,
162 CF_BITMAP,
169 };
170
171 return GetPriorityClipboardFormat(uFormatList, ARRAYSIZE(uFormatList));
172}
173
175{
176 switch (uFormat)
177 {
178 case CF_OWNERDISPLAY:
179 case CF_UNICODETEXT:
180 case CF_TEXT:
181 case CF_OEMTEXT:
182 case CF_BITMAP:
183 case CF_ENHMETAFILE:
184 case CF_METAFILEPICT:
185 case CF_DIB:
186 case CF_DIBV5:
187 case CF_HDROP:
188 {
189 return TRUE;
190 }
191
192 default:
193 {
194 return FALSE;
195 }
196 }
197}
198
199SIZE_T
201 IN LPCWSTR lpText,
202 OUT LPCWSTR* lpNextLine)
203{
204 LPCWSTR ptr;
205
206 /* Find the next line of text (lpText is NULL-terminated) */
207 /* For newlines, focus only on '\n', not on '\r' */
208 ptr = wcschr(lpText, L'\n'); // Find the end of this line.
209 if (ptr)
210 {
211 /* We have the end of this line, go to the next line (ignore the endline in the count) */
212 *lpNextLine = ptr + 1;
213 }
214 else
215 {
216 /* This line was the last one, go pointing to the terminating NULL */
217 ptr = lpText + wcslen(lpText);
218 *lpNextLine = ptr;
219 }
220
221 return (ptr - lpText);
222}
223
224SIZE_T
226 IN LPCSTR lpText,
227 OUT LPCSTR* lpNextLine)
228{
229 LPCSTR ptr;
230
231 /* Find the next line of text (lpText is NULL-terminated) */
232 /* For newlines, focus only on '\n', not on '\r' */
233 ptr = strchr(lpText, '\n'); // Find the end of this line.
234 if (ptr)
235 {
236 /* We have the end of this line, go to the next line (ignore the endline in the count) */
237 *lpNextLine = ptr + 1;
238 }
239 else
240 {
241 /* This line was the last one, go pointing to the terminating NULL */
242 ptr = lpText + strlen(lpText);
243 *lpNextLine = ptr;
244 }
245
246 return (ptr - lpText);
247}
248
250{
251 SetRectEmpty(pRc);
252
254 {
255 return FALSE;
256 }
257
258 switch (uFormat)
259 {
260 case CF_DSPBITMAP:
261 case CF_BITMAP:
262 {
264 BITMAP bmp;
265
267 GetObjectW(hBitmap, sizeof(bmp), &bmp);
268 SetRect(pRc, 0, 0, bmp.bmWidth, bmp.bmHeight);
269 break;
270 }
271
272 case CF_DIB:
273 case CF_DIBV5:
274 {
275 HGLOBAL hGlobal;
276 LPBITMAPINFOHEADER lpInfoHeader;
277
278 hGlobal = GetClipboardData(uFormat);
279 if (!hGlobal)
280 break;
281
282 lpInfoHeader = GlobalLock(hGlobal);
283 if (!lpInfoHeader)
284 break;
285
286 if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
287 {
288 LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
289 SetRect(pRc, 0, 0,
290 lpCoreHeader->bcWidth,
291 lpCoreHeader->bcHeight);
292 }
293 else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
294 (lpInfoHeader->biSize == sizeof(BITMAPV4HEADER)) ||
295 (lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
296 {
297 SetRect(pRc, 0, 0,
298 lpInfoHeader->biWidth,
299 /* NOTE: biHeight < 0 for bottom-up DIBs, or > 0 for top-down DIBs */
300 (lpInfoHeader->biHeight > 0) ? lpInfoHeader->biHeight
301 : -lpInfoHeader->biHeight);
302 }
303 else
304 {
305 /* Invalid format */
306 }
307
308 GlobalUnlock(hGlobal);
309 break;
310 }
311
312 case CF_DSPTEXT:
313 case CF_TEXT:
314 case CF_OEMTEXT:
315 case CF_UNICODETEXT:
316 {
317 HDC hDC;
318 HGLOBAL hGlobal;
319 PVOID lpText, ptr;
321 SIZE txtSize = {0, 0};
322 SIZE_T lineSize;
323
324 hGlobal = GetClipboardData(uFormat);
325 if (!hGlobal)
326 break;
327
328 lpText = GlobalLock(hGlobal);
329 if (!lpText)
330 break;
331
333
334 /* Find the size of the rectangle enclosing the text */
335 for (;;)
336 {
337 if (uFormat == CF_UNICODETEXT)
338 {
339 if (*(LPCWSTR)lpText == UNICODE_NULL)
340 break;
341 lineSize = GetLineExtentW(lpText, (LPCWSTR*)&ptr);
342 dwSize = GetTabbedTextExtentW(hDC, lpText, lineSize, 0, NULL);
343 }
344 else
345 {
346 if (*(LPCSTR)lpText == ANSI_NULL)
347 break;
348 lineSize = GetLineExtentA(lpText, (LPCSTR*)&ptr);
349 dwSize = GetTabbedTextExtentA(hDC, lpText, lineSize, 0, NULL);
350 }
351 txtSize.cx = max(txtSize.cx, LOWORD(dwSize));
352 txtSize.cy += HIWORD(dwSize);
353 lpText = ptr;
354 }
355
357
358 GlobalUnlock(hGlobal);
359
360 SetRect(pRc, 0, 0, txtSize.cx, txtSize.cy);
361 break;
362 }
363
364 default:
365 {
366 break;
367 }
368 }
369
371
372 return TRUE;
373}
static HDC hDC
Definition: 3dtext.c:33
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define STRING_CF_ENHMETAFILE
Definition: resources.h:41
#define STRING_CF_PALETTE
Definition: resources.h:39
#define STRING_CF_DIB
Definition: resources.h:38
#define STRING_CF_UNICODETEXT
Definition: resources.h:40
#define STRING_CF_HDROP
Definition: resources.h:42
#define STRING_CF_BITMAP
Definition: resources.h:33
#define STRING_CF_LOCALE
Definition: resources.h:43
#define STRING_CF_SYLK
Definition: resources.h:35
#define STRING_CF_DIBV5
Definition: resources.h:44
#define STRING_CF_UNKNOWN
Definition: resources.h:31
#define STRING_CF_DIF
Definition: resources.h:36
#define STRING_CF_TEXT
Definition: resources.h:32
#define STRING_CF_OEMTEXT
Definition: resources.h:37
#define STRING_CF_METAFILEPICT
Definition: resources.h:34
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_METAFILEPICT
Definition: constants.h:398
#define CF_BITMAP
Definition: constants.h:397
#define CF_PALETTE
Definition: constants.h:404
#define CF_DSPENHMETAFILE
Definition: constants.h:417
#define CF_OWNERDISPLAY
Definition: constants.h:413
#define CF_PENDATA
Definition: constants.h:405
#define CF_WAVE
Definition: constants.h:407
#define CF_DSPMETAFILEPICT
Definition: constants.h:416
#define CF_HDROP
Definition: constants.h:410
#define CF_LOCALE
Definition: constants.h:411
#define CF_DIF
Definition: constants.h:400
#define CF_DSPBITMAP
Definition: constants.h:415
#define CF_ENHMETAFILE
Definition: constants.h:409
#define CF_SYLK
Definition: constants.h:399
#define CF_TEXT
Definition: constants.h:396
#define CF_TIFF
Definition: constants.h:401
#define CF_DSPTEXT
Definition: constants.h:414
#define CF_DIB
Definition: constants.h:403
#define CF_RIFF
Definition: constants.h:406
#define CF_OEMTEXT
Definition: constants.h:402
HINSTANCE hInstance
Definition: charmap.c:19
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
UINT GetAutomaticClipboardFormat(void)
Definition: cliputils.c:150
void RetrieveClipboardFormatName(HINSTANCE hInstance, UINT uFormat, BOOL Unicode, PVOID lpszFormat, UINT cch)
Definition: cliputils.c:95
static int GetPredefinedClipboardFormatName(HINSTANCE hInstance, UINT uFormat, BOOL Unicode, PVOID lpszFormat, UINT cch)
Definition: cliputils.c:31
SIZE_T GetLineExtentA(IN LPCSTR lpText, OUT LPCSTR *lpNextLine)
Definition: cliputils.c:225
void DeleteClipboardContent(void)
Definition: cliputils.c:134
BOOL IsClipboardFormatSupported(UINT uFormat)
Definition: cliputils.c:174
BOOL GetClipboardDataDimensions(UINT uFormat, PRECT pRc)
Definition: cliputils.c:249
LRESULT SendClipboardOwnerMessage(IN BOOL bUnicode, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: cliputils.c:12
SIZE_T GetLineExtentW(IN LPCWSTR lpText, OUT LPCWSTR *lpNextLine)
Definition: cliputils.c:200
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define wcschr
Definition: compat.h:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
BITMAP bmp
Definition: alphablend.c:62
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
unsigned int UINT
Definition: ndis.h:50
#define UNICODE_NULL
#define ANSI_NULL
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
Definition: bl.h:1331
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
#define max(a, b)
Definition: svc.c:63
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IN
Definition: typedefs.h:39
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
struct tagBITMAPCOREHEADER * LPBITMAPCOREHEADER
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetTabbedTextExtentA(_In_ HDC hdc, _In_reads_(chCount) LPCSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
int WINAPI GetClipboardFormatNameA(_In_ UINT format, _Out_writes_(cchMaxCount) LPSTR lpszFormatName, _In_ int cchMaxCount)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
DWORD WINAPI GetTabbedTextExtentW(_In_ HDC hdc, _In_reads_(chCount) LPCWSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPSTR lpBuffer, _In_ int cchBufferMax)
HANDLE WINAPI GetClipboardData(_In_ UINT)
#define WM_ASKCBFORMATNAME
Definition: winuser.h:1872
int WINAPI GetPriorityClipboardFormat(_In_reads_(cFormats) UINT *paFormatPriorityList, _In_ int cFormats)
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
int WINAPI GetClipboardFormatNameW(_In_ UINT format, _Out_writes_(cchMaxCount) LPWSTR lpszFormatName, _In_ int cchMaxCount)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
void ShowLastWin32Error(HWND hwndParent)
Definition: winutils.c:11
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175