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
12 SendClipboardOwnerMessage(
20 hwndOwner
= GetClipboardOwner();
22 return GetLastError();
25 return SendMessageW(hwndOwner
, uMsg
, wParam
, lParam
);
27 return SendMessageA(hwndOwner
, uMsg
, wParam
, lParam
);
31 GetPredefinedClipboardFormatName(HINSTANCE hInstance
,
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
46 {CF_METAFILEPICT
, STRING_CF_METAFILEPICT
}, // 3
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
56 {CF_UNICODETEXT
, STRING_CF_UNICODETEXT
}, // 13
57 {CF_ENHMETAFILE
, STRING_CF_ENHMETAFILE
}, // 14
59 {CF_HDROP
, STRING_CF_HDROP
}, // 15
60 {CF_LOCALE
, STRING_CF_LOCALE
}, // 16
63 {CF_DIBV5
, STRING_CF_DIBV5
}, // 17
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
:
75 case CF_HDROP
: case CF_LOCALE
:
82 return LoadStringW(hInstance
, uFormatList
[uFormat
-1].uResID
, (LPWSTR
)lpszFormat
, cch
);
84 return LoadStringA(hInstance
, uFormatList
[uFormat
-1].uResID
, (LPSTR
)lpszFormat
, cch
);
95 RetrieveClipboardFormatName(HINSTANCE hInstance
,
101 ZeroMemory(lpszFormat
, cch
* (Unicode
? sizeof(WCHAR
) : sizeof(CHAR
)));
103 /* Check for predefined clipboard format */
104 if (GetPredefinedClipboardFormatName(hInstance
, uFormat
, Unicode
, lpszFormat
, cch
) != 0)
107 /* Check for owner-display format */
108 if (uFormat
== CF_OWNERDISPLAY
)
110 if (SendClipboardOwnerMessage(Unicode
, WM_ASKCBFORMATNAME
,
111 (WPARAM
)cch
, (LPARAM
)lpszFormat
) != 0)
114 LoadStringW(hInstance
, STRING_CF_UNKNOWN
, (LPWSTR
)lpszFormat
, cch
);
116 LoadStringA(hInstance
, STRING_CF_UNKNOWN
, (LPSTR
)lpszFormat
, cch
);
121 /* Fallback to registered clipboard format */
124 if (!GetClipboardFormatNameW(uFormat
, (LPWSTR
)lpszFormat
, cch
))
125 LoadStringW(hInstance
, STRING_CF_UNKNOWN
, (LPWSTR
)lpszFormat
, cch
);
129 if (!GetClipboardFormatNameA(uFormat
, (LPSTR
)lpszFormat
, cch
))
130 LoadStringA(hInstance
, STRING_CF_UNKNOWN
, (LPSTR
)lpszFormat
, cch
);
134 void DeleteClipboardContent(void)
136 if (!OpenClipboard(Globals
.hMainWnd
))
138 ShowLastWin32Error(Globals
.hMainWnd
);
142 if (!EmptyClipboard())
144 ShowLastWin32Error(Globals
.hMainWnd
);
150 UINT
GetAutomaticClipboardFormat(void)
152 static UINT uFormatList
[] =
170 return GetPriorityClipboardFormat(uFormatList
, ARRAYSIZE(uFormatList
));
173 BOOL
IsClipboardFormatSupported(UINT uFormat
)
177 case CF_OWNERDISPLAY
:
183 case CF_METAFILEPICT
:
201 OUT LPCWSTR
* lpNextLine
)
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.
210 /* We have the end of this line, go to the next line (ignore the endline in the count) */
211 *lpNextLine
= ptr
+ 1;
215 /* This line was the last one, go pointing to the terminating NULL */
216 ptr
= lpText
+ wcslen(lpText
);
220 return (ptr
- lpText
);
226 OUT LPCSTR
* lpNextLine
)
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.
235 /* We have the end of this line, go to the next line (ignore the endline in the count) */
236 *lpNextLine
= ptr
+ 1;
240 /* This line was the last one, go pointing to the terminating NULL */
241 ptr
= lpText
+ strlen(lpText
);
245 return (ptr
- lpText
);
248 BOOL
GetClipboardDataDimensions(UINT uFormat
, PRECT pRc
)
252 if (!OpenClipboard(Globals
.hMainWnd
))
265 hBitmap
= (HBITMAP
)GetClipboardData(CF_BITMAP
);
266 GetObjectW(hBitmap
, sizeof(bmp
), &bmp
);
267 SetRect(pRc
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
);
275 LPBITMAPINFOHEADER lpInfoHeader
;
277 hGlobal
= GetClipboardData(uFormat
);
281 lpInfoHeader
= GlobalLock(hGlobal
);
285 if (lpInfoHeader
->biSize
== sizeof(BITMAPCOREHEADER
))
287 LPBITMAPCOREHEADER lpCoreHeader
= (LPBITMAPCOREHEADER
)lpInfoHeader
;
289 lpCoreHeader
->bcWidth
,
290 lpCoreHeader
->bcHeight
);
292 else if ((lpInfoHeader
->biSize
== sizeof(BITMAPINFOHEADER
)) ||
293 (lpInfoHeader
->biSize
== sizeof(BITMAPV4HEADER
)) ||
294 (lpInfoHeader
->biSize
== sizeof(BITMAPV5HEADER
)))
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
);
307 GlobalUnlock(hGlobal
);
320 SIZE txtSize
= {0, 0};
323 hGlobal
= GetClipboardData(uFormat
);
327 lpText
= GlobalLock(hGlobal
);
331 hDC
= GetDC(Globals
.hMainWnd
);
333 /* Find the size of the rectangle enclosing the text */
336 if (uFormat
== CF_UNICODETEXT
)
338 if (*(LPCWSTR
)lpText
== UNICODE_NULL
)
340 lineSize
= GetLineExtentW(lpText
, (LPCWSTR
*)&ptr
);
341 dwSize
= GetTabbedTextExtentW(hDC
, lpText
, lineSize
, 0, NULL
);
345 if (*(LPCSTR
)lpText
== ANSI_NULL
)
347 lineSize
= GetLineExtentA(lpText
, (LPCSTR
*)&ptr
);
348 dwSize
= GetTabbedTextExtentA(hDC
, lpText
, lineSize
, 0, NULL
);
350 txtSize
.cx
= max(txtSize
.cx
, LOWORD(dwSize
));
351 txtSize
.cy
+= HIWORD(dwSize
);
355 ReleaseDC(Globals
.hMainWnd
, hDC
);
357 GlobalUnlock(hGlobal
);
359 SetRect(pRc
, 0, 0, txtSize
.cx
, txtSize
.cy
);