ReactOS  0.4.12-dev-14-gd0c8636
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 
11 LRESULT
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 
30 static 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
45  {CF_BITMAP , STRING_CF_BITMAP }, // 2
47  {CF_SYLK , STRING_CF_SYLK }, // 4
48  {CF_DIF , STRING_CF_DIF }, // 5
49  {CF_TIFF , 0/*STRING_CF_TIFF*/ }, // 6
50  {CF_OEMTEXT , STRING_CF_OEMTEXT }, // 7
51  {CF_DIB , STRING_CF_DIB }, // 8
52  {CF_PALETTE , STRING_CF_PALETTE }, // 9
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:
73  case CF_UNICODETEXT: case CF_ENHMETAFILE:
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 
94 void
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)
114  LoadStringW(hInstance, STRING_CF_UNKNOWN, (LPWSTR)lpszFormat, cch);
115  else
116  LoadStringA(hInstance, STRING_CF_UNKNOWN, (LPSTR)lpszFormat, cch);
117  }
118  return;
119  }
120 
121  /* Fallback to registered clipboard format */
122  if (Unicode)
123  {
124  if (!GetClipboardFormatNameW(uFormat, (LPWSTR)lpszFormat, cch))
125  LoadStringW(hInstance, STRING_CF_UNKNOWN, (LPWSTR)lpszFormat, cch);
126  }
127  else
128  {
129  if (!GetClipboardFormatNameA(uFormat, (LPSTR)lpszFormat, cch))
130  LoadStringA(hInstance, STRING_CF_UNKNOWN, (LPSTR)lpszFormat, cch);
131  }
132 }
133 
135 {
137  {
139  return;
140  }
141 
142  if (!EmptyClipboard())
143  {
145  }
146 
147  CloseClipboard();
148 }
149 
151 {
152  static UINT uFormatList[] =
153  {
156  CF_TEXT,
157  CF_OEMTEXT,
160  CF_DIBV5,
161  CF_DIB,
162  CF_BITMAP,
163  CF_DSPTEXT,
164  CF_DSPBITMAP,
167  CF_PALETTE
168  };
169 
170  return GetPriorityClipboardFormat(uFormatList, ARRAYSIZE(uFormatList));
171 }
172 
174 {
175  switch (uFormat)
176  {
177  case CF_OWNERDISPLAY:
178  case CF_UNICODETEXT:
179  case CF_TEXT:
180  case CF_OEMTEXT:
181  case CF_BITMAP:
182  case CF_ENHMETAFILE:
183  case CF_METAFILEPICT:
184  case CF_DIB:
185  case CF_DIBV5:
186  case CF_HDROP:
187  {
188  return TRUE;
189  }
190 
191  default:
192  {
193  return FALSE;
194  }
195  }
196 }
197 
198 SIZE_T
200  IN LPCWSTR lpText,
201  OUT LPCWSTR* lpNextLine)
202 {
203  LPCWSTR ptr;
204 
205  /* Find the next line of text (lpText is NULL-terminated) */
206  /* For newlines, focus only on '\n', not on '\r' */
207  ptr = wcschr(lpText, L'\n'); // Find the end of this line.
208  if (ptr)
209  {
210  /* We have the end of this line, go to the next line (ignore the endline in the count) */
211  *lpNextLine = ptr + 1;
212  }
213  else
214  {
215  /* This line was the last one, go pointing to the terminating NULL */
216  ptr = lpText + wcslen(lpText);
217  *lpNextLine = ptr;
218  }
219 
220  return (ptr - lpText);
221 }
222 
223 SIZE_T
225  IN LPCSTR lpText,
226  OUT LPCSTR* lpNextLine)
227 {
228  LPCSTR ptr;
229 
230  /* Find the next line of text (lpText is NULL-terminated) */
231  /* For newlines, focus only on '\n', not on '\r' */
232  ptr = strchr(lpText, '\n'); // Find the end of this line.
233  if (ptr)
234  {
235  /* We have the end of this line, go to the next line (ignore the endline in the count) */
236  *lpNextLine = ptr + 1;
237  }
238  else
239  {
240  /* This line was the last one, go pointing to the terminating NULL */
241  ptr = lpText + strlen(lpText);
242  *lpNextLine = ptr;
243  }
244 
245  return (ptr - lpText);
246 }
247 
249 {
250  SetRectEmpty(pRc);
251 
253  {
254  return FALSE;
255  }
256 
257  switch (uFormat)
258  {
259  case CF_DSPBITMAP:
260  case CF_BITMAP:
261  {
263  BITMAP bmp;
264 
265  hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
266  GetObjectW(hBitmap, sizeof(bmp), &bmp);
267  SetRect(pRc, 0, 0, bmp.bmWidth, bmp.bmHeight);
268  break;
269  }
270 
271  case CF_DIB:
272  case CF_DIBV5:
273  {
274  HGLOBAL hGlobal;
275  LPBITMAPINFOHEADER lpInfoHeader;
276 
277  hGlobal = GetClipboardData(uFormat);
278  if (!hGlobal)
279  break;
280 
281  lpInfoHeader = GlobalLock(hGlobal);
282  if (!lpInfoHeader)
283  break;
284 
285  if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
286  {
287  LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
288  SetRect(pRc, 0, 0,
289  lpCoreHeader->bcWidth,
290  lpCoreHeader->bcHeight);
291  }
292  else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
293  (lpInfoHeader->biSize == sizeof(BITMAPV4HEADER)) ||
294  (lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
295  {
296  SetRect(pRc, 0, 0,
297  lpInfoHeader->biWidth,
298  /* NOTE: biHeight < 0 for bottom-up DIBs, or > 0 for top-down DIBs */
299  (lpInfoHeader->biHeight > 0) ? lpInfoHeader->biHeight
300  : -lpInfoHeader->biHeight);
301  }
302  else
303  {
304  /* Invalid format */
305  }
306 
307  GlobalUnlock(hGlobal);
308  break;
309  }
310 
311  case CF_DSPTEXT:
312  case CF_TEXT:
313  case CF_OEMTEXT:
314  case CF_UNICODETEXT:
315  {
316  HDC hDC;
317  HGLOBAL hGlobal;
318  PVOID lpText, ptr;
319  DWORD dwSize;
320  SIZE txtSize = {0, 0};
321  SIZE_T lineSize;
322 
323  hGlobal = GetClipboardData(uFormat);
324  if (!hGlobal)
325  break;
326 
327  lpText = GlobalLock(hGlobal);
328  if (!lpText)
329  break;
330 
331  hDC = GetDC(Globals.hMainWnd);
332 
333  /* Find the size of the rectangle enclosing the text */
334  for (;;)
335  {
336  if (uFormat == CF_UNICODETEXT)
337  {
338  if (*(LPCWSTR)lpText == UNICODE_NULL)
339  break;
340  lineSize = GetLineExtentW(lpText, (LPCWSTR*)&ptr);
341  dwSize = GetTabbedTextExtentW(hDC, lpText, lineSize, 0, NULL);
342  }
343  else
344  {
345  if (*(LPCSTR)lpText == ANSI_NULL)
346  break;
347  lineSize = GetLineExtentA(lpText, (LPCSTR*)&ptr);
348  dwSize = GetTabbedTextExtentA(hDC, lpText, lineSize, 0, NULL);
349  }
350  txtSize.cx = max(txtSize.cx, LOWORD(dwSize));
351  txtSize.cy += HIWORD(dwSize);
352  lpText = ptr;
353  }
354 
355  ReleaseDC(Globals.hMainWnd, hDC);
356 
357  GlobalUnlock(hGlobal);
358 
359  SetRect(pRc, 0, 0, txtSize.cx, txtSize.cy);
360  break;
361  }
362 
363  default:
364  {
365  break;
366  }
367  }
368 
369  CloseClipboard();
370 
371  return TRUE;
372 }
#define STRING_CF_HDROP
Definition: resources.h:42
#define HDC
Definition: msvc.h:22
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
#define STRING_CF_ENHMETAFILE
Definition: resources.h:41
#define STRING_CF_PALETTE
Definition: resources.h:39
#define HBITMAP
Definition: msvc.h:28
#define CF_ENHMETAFILE
Definition: constants.h:409
UINT GetAutomaticClipboardFormat(void)
Definition: cliputils.c:150
HDC WINAPI GetDC(_In_opt_ HWND)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI GetTabbedTextExtentW(_In_ HDC hdc, _In_reads_(chCount) LPCWSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_ASKCBFORMATNAME
Definition: winuser.h:1834
#define CF_DSPMETAFILEPICT
Definition: constants.h:416
char CHAR
Definition: xmlstorage.h:175
int WINAPI LoadStringA(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPSTR lpBuffer, _In_ int cchBufferMax)
#define CF_PENDATA
Definition: constants.h:405
#define STRING_CF_BITMAP
Definition: resources.h:33
#define CF_SYLK
Definition: constants.h:399
BOOL GetClipboardDataDimensions(UINT uFormat, PRECT pRc)
Definition: cliputils.c:248
DWORD WINAPI GetTabbedTextExtentA(_In_ HDC hdc, _In_reads_(chCount) LPCSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
static int GetPredefinedClipboardFormatName(HINSTANCE hInstance, UINT uFormat, BOOL Unicode, PVOID lpszFormat, UINT cch)
Definition: cliputils.c:31
#define CF_TIFF
Definition: constants.h:401
#define CF_METAFILEPICT
Definition: constants.h:398
char * LPSTR
Definition: xmlstorage.h:182
SIZE_T GetLineExtentA(IN LPCSTR lpText, OUT LPCSTR *lpNextLine)
Definition: cliputils.c:224
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
WPARAM wParam
Definition: combotst.c:138
int WINAPI GetPriorityClipboardFormat(_In_reads_(cFormats) UINT *paFormatPriorityList, _In_ int cFormats)
UINT_PTR WPARAM
Definition: windef.h:207
int WINAPI GetClipboardFormatNameW(_In_ UINT format, _Out_writes_(cchMaxCount) LPWSTR lpszFormatName, _In_ int cchMaxCount)
void ShowLastWin32Error(HWND hwndParent)
Definition: winutils.c:11
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
HINSTANCE hInstance
Definition: charmap.c:20
#define STRING_CF_DIB
Definition: resources.h:38
#define STRING_CF_UNKNOWN
Definition: resources.h:31
#define UNICODE_NULL
#define ANSI_NULL
LONG_PTR LPARAM
Definition: windef.h:208
#define CF_OWNERDISPLAY
Definition: constants.h:413
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
static PVOID ptr
Definition: dispmode.c:27
#define CF_DSPENHMETAFILE
Definition: constants.h:417
void DeleteClipboardContent(void)
Definition: cliputils.c:134
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_BITMAP
Definition: constants.h:397
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
smooth NULL
Definition: ftsmooth.c:416
#define CF_HDROP
Definition: constants.h:410
LONG cx
Definition: windef.h:324
#define STRING_CF_OEMTEXT
Definition: resources.h:37
const char * LPCSTR
Definition: xmlstorage.h:183
#define CF_TEXT
Definition: constants.h:396
#define CF_DIF
Definition: constants.h:400
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
BOOL IsClipboardFormatSupported(UINT uFormat)
Definition: cliputils.c:173
#define STRING_CF_LOCALE
Definition: resources.h:43
unsigned int BOOL
Definition: ntddk_ex.h:94
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
void RetrieveClipboardFormatName(HINSTANCE hInstance, UINT uFormat, BOOL Unicode, PVOID lpszFormat, UINT cch)
Definition: cliputils.c:95
#define CF_DSPBITMAP
Definition: constants.h:415
struct tagBITMAPCOREHEADER * LPBITMAPCOREHEADER
unsigned int UINT
Definition: ndis.h:50
unsigned long DWORD
Definition: ntddk_ex.h:95
LRESULT SendClipboardOwnerMessage(IN BOOL bUnicode, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: cliputils.c:12
BITMAP bmp
Definition: alphablend.c:62
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
static const WCHAR L[]
Definition: oid.c:1087
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define CF_PALETTE
Definition: constants.h:404
#define CF_WAVE
Definition: constants.h:407
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define STRING_CF_TEXT
Definition: resources.h:32
#define CF_LOCALE
Definition: constants.h:411
static HDC hDC
Definition: 3dtext.c:33
ULONG_PTR SIZE_T
Definition: typedefs.h:78
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define CF_OEMTEXT
Definition: constants.h:402
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
Definition: bl.h:1331
SIZE_T GetLineExtentW(IN LPCWSTR lpText, OUT LPCWSTR *lpNextLine)
Definition: cliputils.c:199
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define CF_RIFF
Definition: constants.h:406
HANDLE WINAPI GetClipboardData(_In_ UINT)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define OUT
Definition: typedefs.h:39
#define STRING_CF_UNICODETEXT
Definition: resources.h:40
#define HIWORD(l)
Definition: typedefs.h:246
#define CF_DSPTEXT
Definition: constants.h:414
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
LONG cy
Definition: windef.h:325
#define STRING_CF_DIBV5
Definition: resources.h:44
static HBITMAP hBitmap
Definition: timezone.c:34
#define STRING_CF_SYLK
Definition: resources.h:35
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
int WINAPI GetClipboardFormatNameA(_In_ UINT format, _Out_writes_(cchMaxCount) LPSTR lpszFormatName, _In_ int cchMaxCount)
#define STRING_CF_METAFILEPICT
Definition: resources.h:34
#define CF_DIB
Definition: constants.h:403
#define STRING_CF_DIF
Definition: resources.h:36