ReactOS 0.4.15-dev-7788-g1ad9096
winutils.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: Display helper functions.
5 * COPYRIGHT: Copyright 2015-2018 Ricardo Hanke
6 * Copyright 2015-2018 Hermes Belusca-Maito
7 */
8
9#include "precomp.h"
10
12{
13 DWORD dwError;
14 LPWSTR lpMsgBuf = NULL;
15
16 dwError = GetLastError();
17 if (dwError == ERROR_SUCCESS)
18 return;
19
23 NULL,
24 dwError,
26 (LPWSTR)&lpMsgBuf,
27 0, NULL))
28 {
29 return;
30 }
31
33 LocalFree(lpMsgBuf);
34}
35
37{
38 if (IsIconic(hWnd))
39 {
42 }
43 else
44 {
46 }
47}
48
49int MessageBoxRes(HWND hWnd, HINSTANCE hInstance, UINT uText, UINT uCaption, UINT uType)
50{
52
53 ZeroMemory(&mb, sizeof(mb));
54 mb.cbSize = sizeof(mb);
55 mb.hwndOwner = hWnd;
57 mb.lpszText = MAKEINTRESOURCEW(uText);
58 mb.lpszCaption = MAKEINTRESOURCEW(uCaption);
59 mb.dwStyle = uType;
61
62 return MessageBoxIndirectW(&mb);
63}
64
66{
68 int nCount;
69
70 nCount = LoadStringW(hInstance, uID, (LPWSTR)&lpBuffer, 0);
71 if (nCount)
72 DrawTextW(hDC, lpBuffer, nCount, lpRect, uFormat);
73}
74
76{
77 POINT ptOrg;
78 HGLOBAL hGlobal;
79 PVOID lpText, ptr;
80 SIZE_T lineSize;
81 INT FirstLine, LastLine;
82
83 hGlobal = GetClipboardData(uFormat);
84 if (!hGlobal)
85 return;
86
87 lpText = GlobalLock(hGlobal);
88 if (!lpText)
89 return;
90
91 /* Find the first and last line indices to display (Note that CurrentX/Y are in pixels!) */
92 FirstLine = max(0, (state.CurrentY + ps.rcPaint.top) / Globals.CharHeight);
93 // LastLine = min(LINES - 1, (state.CurrentY + ps.rcPaint.bottom) / Globals.CharHeight);
94 // NOTE: Can be less or greater than the actual number of lines in the text.
95 LastLine = (state.CurrentY + ps.rcPaint.bottom) / Globals.CharHeight;
96
97 /* Find the first text line to display */
98 while (FirstLine > 0)
99 {
100 if (uFormat == CF_UNICODETEXT)
101 {
102 if (*(LPCWSTR)lpText == UNICODE_NULL)
103 break;
104 GetLineExtentW(lpText, (LPCWSTR*)&ptr);
105 }
106 else
107 {
108 if (*(LPCSTR)lpText == ANSI_NULL)
109 break;
110 GetLineExtentA(lpText, (LPCSTR*)&ptr);
111 }
112
113 --FirstLine;
114 --LastLine;
115
116 lpText = ptr;
117 }
118
119 ptOrg.x = ps.rcPaint.left;
120 ptOrg.y = /* FirstLine */ max(0, (state.CurrentY + ps.rcPaint.top) / Globals.CharHeight)
121 * Globals.CharHeight - state.CurrentY;
122
123 /* Display each line from the current one up to the last one */
124 ++LastLine;
125 while (LastLine >= 0)
126 {
127 if (uFormat == CF_UNICODETEXT)
128 {
129 if (*(LPCWSTR)lpText == UNICODE_NULL)
130 break;
131 lineSize = GetLineExtentW(lpText, (LPCWSTR*)&ptr);
132 TabbedTextOutW(ps.hdc, /*ptOrg.x*/0 - state.CurrentX, ptOrg.y,
133 lpText, lineSize, 0, NULL,
134 /*ptOrg.x*/0 - state.CurrentX);
135 }
136 else
137 {
138 if (*(LPCSTR)lpText == ANSI_NULL)
139 break;
140 lineSize = GetLineExtentA(lpText, (LPCSTR*)&ptr);
141 TabbedTextOutA(ps.hdc, /*ptOrg.x*/0 - state.CurrentX, ptOrg.y,
142 lpText, lineSize, 0, NULL,
143 /*ptOrg.x*/0 - state.CurrentX);
144 }
145
146 --LastLine;
147
148 ptOrg.y += Globals.CharHeight;
149 lpText = ptr;
150 }
151
152 GlobalUnlock(hGlobal);
153}
154
156{
157 HDC hdcMem;
159 BITMAP bmp;
160 LONG bmWidth, bmHeight;
161
163 if (!hdcMem)
164 return;
165
167 GetObjectW(hBitmap, sizeof(bmp), &bmp);
168
170
171 bmWidth = min(ps.rcPaint.right - ps.rcPaint.left, bmp.bmWidth - ps.rcPaint.left - state.CurrentX);
172 bmHeight = min(ps.rcPaint.bottom - ps.rcPaint.top , bmp.bmHeight - ps.rcPaint.top - state.CurrentY);
173
174 BitBlt(ps.hdc,
175 ps.rcPaint.left,
176 ps.rcPaint.top,
177 bmWidth,
178 bmHeight,
179 hdcMem,
180 ps.rcPaint.left + state.CurrentX,
181 ps.rcPaint.top + state.CurrentY,
182 dwRop);
183
185}
186
188{
189 HGLOBAL hGlobal;
190 LPBITMAPINFOHEADER lpInfoHeader;
191 LPBYTE lpBits;
192 LONG bmWidth, bmHeight;
193 DWORD dwPalSize = 0;
194
195 hGlobal = GetClipboardData(uFormat);
196 if (!hGlobal)
197 return;
198
199 lpInfoHeader = GlobalLock(hGlobal);
200 if (!lpInfoHeader)
201 return;
202
203 if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
204 {
205 LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
206
207 dwPalSize = 0;
208
209 if (lpCoreHeader->bcBitCount <= 8)
210 {
211 dwPalSize = (1 << lpCoreHeader->bcBitCount);
212
213 if (fuColorUse == DIB_RGB_COLORS)
214 dwPalSize *= sizeof(RGBTRIPLE);
215 else
216 dwPalSize *= sizeof(WORD);
217 }
218
219 bmWidth = lpCoreHeader->bcWidth;
220 bmHeight = lpCoreHeader->bcHeight;
221 }
222 else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
223 (lpInfoHeader->biSize == sizeof(BITMAPV4HEADER)) ||
224 (lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
225 {
226 dwPalSize = lpInfoHeader->biClrUsed;
227
228 if ((dwPalSize == 0) && (lpInfoHeader->biBitCount <= 8))
229 dwPalSize = (1 << lpInfoHeader->biBitCount);
230
231 if (fuColorUse == DIB_RGB_COLORS)
232 dwPalSize *= sizeof(RGBQUAD);
233 else
234 dwPalSize *= sizeof(WORD);
235
236 if (/*(lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&*/
237 (lpInfoHeader->biCompression == BI_BITFIELDS))
238 {
239 dwPalSize += 3 * sizeof(DWORD);
240 }
241
242 /*
243 * This is a (disabled) hack for Windows, when uFormat == CF_DIB
244 * it needs yet another extra 3 DWORDs, in addition to the
245 * ones already taken into account in via the compression.
246 * This problem doesn't happen when uFormat == CF_DIBV5
247 * (in that case, when compression is taken into account,
248 * everything is nice).
249 *
250 * NOTE 1: This fix is only for us, because when one pastes DIBs
251 * directly in apps, the bitmap offset problem is still present.
252 *
253 * NOTE 2: The problem can be seen with Windows' clipbrd.exe if
254 * one copies a CF_DIB image in the clipboard. By default Windows'
255 * clipbrd.exe works with CF_DIBV5 and CF_BITMAP, so the problem
256 * is unseen, and the clipboard doesn't have to convert to CF_DIB.
257 *
258 * FIXME: investigate!!
259 * ANSWER: this is a Windows bug; part of the answer is there:
260 * https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ac7ab3b5-8609-4478-b86a-976dab44c271/bug-clipboard-format-conversions-cfdib-cfdibv5-cfdib
261 * May be related:
262 * https://blog.talosintelligence.com/2015/10/dangerous-clipboard.html
263 */
264#if 0
265 if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&
266 (lpInfoHeader->biCompression == BI_BITFIELDS))
267 {
268 dwPalSize += 3 * sizeof(DWORD);
269 }
270#endif
271
272 bmWidth = lpInfoHeader->biWidth;
273 /* NOTE: biHeight < 0 for bottom-up DIBs, or > 0 for top-down DIBs */
274 bmHeight = lpInfoHeader->biHeight;
275 }
276 else
277 {
278 /* Invalid format */
279 GlobalUnlock(hGlobal);
280 return;
281 }
282
283 lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + dwPalSize;
284
285 /*
286 * The seventh parameter (YSrc) of SetDIBitsToDevice always designates
287 * the Y-coordinate of the "lower-left corner" of the image, be the DIB
288 * in bottom-up or top-down mode.
289 */
291 -state.CurrentX, // ps.rcPaint.left,
292 -state.CurrentY, // ps.rcPaint.top,
293 bmWidth,
294 bmHeight,
295 0, // ps.rcPaint.left + state.CurrentX,
296 0, // -(ps.rcPaint.top + state.CurrentY),
297 0, // uStartScan,
298 bmHeight,
299 lpBits,
300 (LPBITMAPINFO)lpInfoHeader,
301 fuColorUse);
302
303 GlobalUnlock(hGlobal);
304}
305
307{
309 HGLOBAL hGlobal;
310
312 if (!hGlobal)
313 return;
314
315 mp = (LPMETAFILEPICT)GlobalLock(hGlobal);
316 if (!mp)
317 return;
318
319 SetMapMode(hdc, mp->mm);
320 SetViewportExtEx(hdc, lpRect->right, lpRect->bottom, NULL);
321 SetViewportOrgEx(hdc, lpRect->left, lpRect->top, NULL);
322 PlayMetaFile(hdc, mp->hMF);
323 GlobalUnlock(hGlobal);
324}
325
327{
328 HENHMETAFILE hEmf;
329
331 PlayEnhMetaFile(hdc, hEmf, lpRect);
332}
333
335{
336 INT cch;
337 LPWSTR pszNew;
338
339 if (psz == NULL)
340 return _wcsdup(cat);
341
342 cch = lstrlenW(psz) + lstrlenW(cat) + 1;
343 pszNew = realloc(psz, cch * sizeof(WCHAR));
344 if (!pszNew)
345 return psz;
346
347 lstrcatW(pszNew, cat);
348 return pszNew;
349}
350
351void HDropFromClipboard(HDC hdc, const RECT *lpRect)
352{
353 LPWSTR pszAlloc = NULL;
354 WCHAR szFile[MAX_PATH + 2];
355 HDROP hDrop = (HDROP)GetClipboardData(CF_HDROP);
356 UINT iFile, cFiles = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
357 RECT rc = *lpRect;
358
359 FillRect(hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1));
360
361 for (iFile = 0; iFile < cFiles; ++iFile)
362 {
363 DragQueryFileW(hDrop, iFile, szFile, _countof(szFile));
364 lstrcatW(szFile, L"\r\n");
365 pszAlloc = AllocStrCat(pszAlloc, szFile);
366 }
367
368 DrawTextW(hdc, pszAlloc, -1, &rc,
370 free(pszAlloc);
371}
372
374{
376 HPALETTE hPalette, hOldPalette;
377
379 return FALSE;
380
381 hPalette = GetClipboardData(CF_PALETTE);
382 if (!hPalette)
383 return FALSE;
384
385 hOldPalette = SelectPalette(hdc, hPalette, FALSE);
386 if (!hOldPalette)
387 return FALSE;
388
390
391 SelectPalette(hdc, hOldPalette, FALSE);
392
393 return Success;
394}
static HDC hDC
Definition: 3dtext.c:33
static int state
Definition: maze.c:121
HWND hWnd
Definition: settings.c:17
#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_HDROP
Definition: constants.h:410
#define CF_ENHMETAFILE
Definition: constants.h:409
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
HINSTANCE hInstance
Definition: charmap.c:19
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
SIZE_T GetLineExtentA(IN LPCSTR lpText, OUT LPCSTR *lpNextLine)
Definition: cliputils.c:225
SIZE_T GetLineExtentW(IN LPCWSTR lpText, OUT LPCWSTR *lpNextLine)
Definition: cliputils.c:200
static HWND hwndParent
Definition: cryptui.c:300
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
#define MAX_PATH
Definition: compat.h:34
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:622
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
ULONG RGBQUAD
Definition: precomp.h:50
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define BI_BITFIELDS
Definition: mmreg.h:507
static PVOID ptr
Definition: dispmode.c:27
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
#define ANSI_NULL
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:16
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define _countof(array)
Definition: sndvol32.h:68
DWORD biCompression
Definition: amvideo.idl:35
DWORD dwLanguageId
Definition: winuser.h:3345
LPCWSTR lpszCaption
Definition: winuser.h:3340
HWND hwndOwner
Definition: winuser.h:3337
LPCWSTR lpszText
Definition: winuser.h:3339
HINSTANCE hInstance
Definition: winuser.h:3338
DWORD dwStyle
Definition: winuser.h:3341
Definition: bl.h:1331
HMETAFILE hMF
Definition: wingdi.h:2608
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define max(a, b)
Definition: svc.c:63
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
HDC hdcMem
Definition: welcome.c:104
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
_In_ ULONG_PTR iFile
Definition: winddi.h:3835
int WINAPI SetMapMode(_In_ HDC, _In_ int)
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI SetDIBitsToDevice(_In_ HDC, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ int, _In_ int, _In_ UINT, _In_ UINT, _In_ CONST VOID *, _In_ CONST BITMAPINFO *, _In_ UINT)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
UINT WINAPI RealizePalette(_In_ HDC)
Definition: palette.c:138
struct tagRGBTRIPLE RGBTRIPLE
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
HPALETTE WINAPI SelectPalette(_In_ HDC, _In_ HPALETTE, _In_ BOOL)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
struct tagMETAFILEPICT * LPMETAFILEPICT
BOOL WINAPI SetViewportOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:655
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
struct tagBITMAPCOREHEADER * LPBITMAPCOREHEADER
#define GDI_ERROR
Definition: wingdi.h:1309
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI PlayMetaFile(_In_ HDC, _In_ HMETAFILE)
BOOL WINAPI PlayEnhMetaFile(_In_ HDC, _In_ HENHMETAFILE, _In_ LPCRECT)
#define DT_NOPREFIX
Definition: winuser.h:537
#define COLOR_WINDOW
Definition: winuser.h:918
#define DT_EXTERNALLEADING
Definition: winuser.h:533
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
HANDLE WINAPI GetClipboardData(_In_ UINT)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
BOOL WINAPI IsIconic(_In_ HWND)
#define MB_ICONERROR
Definition: winuser.h:787
#define DT_LEFT
Definition: winuser.h:534
#define MB_OK
Definition: winuser.h:790
LONG WINAPI TabbedTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(chCount) LPCSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions, _In_ int nTabOrigin)
#define SW_RESTORE
Definition: winuser.h:779
int WINAPI MessageBoxIndirectW(_In_ CONST MSGBOXPARAMSW *lpmbp)
#define DT_WORD_ELLIPSIS
Definition: winuser.h:531
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
BOOL WINAPI IsClipboardFormatAvailable(_In_ UINT)
LONG WINAPI TabbedTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(chCount) LPCWSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions, _In_ int nTabOrigin)
void HDropFromClipboard(HDC hdc, const RECT *lpRect)
Definition: winutils.c:351
static LPWSTR AllocStrCat(LPWSTR psz, LPCWSTR cat)
Definition: winutils.c:334
int MessageBoxRes(HWND hWnd, HINSTANCE hInstance, UINT uText, UINT uCaption, UINT uType)
Definition: winutils.c:49
void DrawTextFromClipboard(UINT uFormat, PAINTSTRUCT ps, SCROLLSTATE state)
Definition: winutils.c:75
void BringWindowToFront(HWND hWnd)
Definition: winutils.c:36
BOOL RealizeClipboardPalette(HDC hdc)
Definition: winutils.c:373
void PlayEnhMetaFileFromClipboard(HDC hdc, const RECT *lpRect)
Definition: winutils.c:326
void DrawTextFromResource(HINSTANCE hInstance, UINT uID, HDC hDC, LPRECT lpRect, UINT uFormat)
Definition: winutils.c:65
void SetDIBitsToDeviceFromClipboard(UINT uFormat, PAINTSTRUCT ps, SCROLLSTATE state, UINT fuColorUse)
Definition: winutils.c:187
void BitBltFromClipboard(PAINTSTRUCT ps, SCROLLSTATE state, DWORD dwRop)
Definition: winutils.c:155
void ShowLastWin32Error(HWND hwndParent)
Definition: winutils.c:11
void PlayMetaFileFromClipboard(HDC hdc, const RECT *lpRect)
Definition: winutils.c:306
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185