ReactOS  0.4.14-dev-77-gd9e7c48
clipboard.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS user32.dll
3  * FILE: win32ss/user/user32/windows/clipboard.c
4  * PURPOSE: Input
5  * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
6  * Pablo Borobia <pborobia@gmail.com>
7  * UPDATE HISTORY:
8  * 09-05-2001 CSH Created
9  *
10  */
11 
12 #include <user32.h>
13 
14 #define NDEBUG
15 
17 
22 
23 
24 /*
25  * @implemented
26  */
27 BOOL
28 WINAPI
29 OpenClipboard(HWND hWndNewOwner)
30 {
31  return NtUserOpenClipboard(hWndNewOwner, 0);
32 }
33 
34 /*
35  * @implemented
36  */
37 UINT
38 WINAPI
40 {
43 }
44 
45 /*
46  * @implemented
47  */
48 INT
49 WINAPI
51  LPSTR lpszFormatName,
52  int cchMaxCount)
53 {
55  INT Length;
56 
57  lpBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchMaxCount * sizeof(WCHAR));
58  if (!lpBuffer)
59  {
61  return 0;
62  }
63 
64  /* we need a UNICODE string */
66 
67  if (Length != 0)
68  {
69  if (!WideCharToMultiByte(CP_ACP, 0, lpBuffer, Length, lpszFormatName, cchMaxCount, NULL, NULL))
70  {
71  /* clear result string */
72  Length = 0;
73  }
74  lpszFormatName[Length] = ANSI_NULL;
75  }
76 
77  RtlFreeHeap(RtlGetProcessHeap(), 0, lpBuffer);
78  return Length;
79 }
80 
81 /*
82  * @implemented
83  */
84 INT
85 WINAPI
87  LPWSTR lpszFormatName,
88  INT cchMaxCount)
89 {
90  return NtUserGetClipboardFormatName(uFormat, lpszFormatName, cchMaxCount);
91 }
92 
93 /*
94  * @implemented
95  */
96 UINT
97 WINAPI
99 {
100  UINT ret;
101  UNICODE_STRING usFormat = {0};
102 
103  if (lpszFormat == NULL)
104  {
106  return 0;
107  }
108 
109  if (*lpszFormat == ANSI_NULL)
110  {
112  return 0;
113  }
114 
115  if (!RtlCreateUnicodeStringFromAsciiz(&usFormat, lpszFormat))
116  {
118  return 0;
119  }
120 
121  ret = NtUserRegisterWindowMessage(&usFormat); //(LPCWSTR)
122 
123  RtlFreeUnicodeString(&usFormat);
124 
125  return ret;
126 }
127 
128 /*
129  * @implemented
130  */
131 UINT
132 WINAPI
134 {
135  UNICODE_STRING usFormat = {0};
136 
137  if (lpszFormat == NULL)
138  {
140  return 0;
141  }
142 
143  if (*lpszFormat == UNICODE_NULL)
144  {
146  return 0;
147  }
148 
149  RtlInitUnicodeString(&usFormat, lpszFormat);
150  return NtUserRegisterWindowMessage(&usFormat);
151 }
152 
153 static PVOID WINAPI
155 {
156  HANDLE hGlobal;
157  PVOID pGlobal;
158  INT cbGlobal;
159 
160  cbGlobal = WideCharToMultiByte(bOem ? CP_OEMCP : CP_ACP,
161  0, pwStr, cbStr / sizeof(WCHAR),
162  NULL, 0, NULL, NULL);
163  hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbGlobal);
164  if (!hGlobal)
165  return NULL;
166 
167  pGlobal = GlobalLock(hGlobal);
169  0, pwStr, cbStr / sizeof(WCHAR),
170  pGlobal, cbGlobal, NULL, NULL);
171  return pGlobal;
172 }
173 
174 static PVOID WINAPI
176 {
177  HANDLE hGlobal;
178  PVOID pGlobal;
179  INT cbGlobal;
180 
181  cbGlobal = MultiByteToWideChar(bOem ? CP_OEMCP : CP_ACP,
182  0, pwStr, cbStr, NULL, 0) * sizeof(WCHAR);
183  hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbGlobal);
184  if (!hGlobal)
185  return NULL;
186 
187  pGlobal = GlobalLock(hGlobal);
189  0, pwStr, cbStr, pGlobal, cbGlobal);
190  return pGlobal;
191 }
192 
193 /*
194  * @implemented
195  */
196 HANDLE
197 WINAPI
199 {
200  HANDLE hData = NULL;
201  PVOID pData = NULL;
202  DWORD cbData = 0;
204 
205  hData = NtUserGetClipboardData(uFormat, &gcd);
206  if (!hData)
207  return NULL;
208 
209  switch (uFormat)
210  {
211  case CF_DSPMETAFILEPICT:
212  case CF_METAFILEPICT:
213  return GdiCreateLocalMetaFilePict(hData);
214  case CF_DSPENHMETAFILE:
215  case CF_ENHMETAFILE:
216  return GdiCreateLocalEnhMetaFile(hData);
217  }
218 
219  if (gcd.fGlobalHandle)
220  {
221  HANDLE hGlobal;
222 
223  NtUserCreateLocalMemHandle(hData, NULL, 0, &cbData);
224  hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbData);
225  pData = GlobalLock(hGlobal);
226  NtUserCreateLocalMemHandle(hData, pData, cbData, NULL);
227  hData = hGlobal;
228  }
229 
230  if (gcd.uFmtRet != uFormat)
231  {
232  SETCLIPBDATA scd = {FALSE, FALSE};
233  HANDLE hNewData = NULL;
234  PVOID pNewData = NULL;
235 
236  /* Synthesize requested format */
237  switch (uFormat)
238  {
239  case CF_TEXT:
240  if (gcd.uFmtRet == CF_UNICODETEXT)
241  pNewData = IntSynthesizeMultiByte(pData, cbData, uFormat == CF_OEMTEXT);
242  else // CF_OEMTEXT
243  OemToCharBuffA(pData, pData, cbData);
244  break;
245  case CF_OEMTEXT:
246  if (gcd.uFmtRet == CF_UNICODETEXT)
247  pNewData = IntSynthesizeMultiByte(pData, cbData, uFormat == CF_OEMTEXT);
248  else
249  CharToOemBuffA(pData, pData, cbData);
250  break;
251  case CF_UNICODETEXT:
252  pNewData = IntSynthesizeWideChar(pData, cbData, gcd.uFmtRet == CF_OEMTEXT);
253  break;
254  default:
255  FIXME("Format: %u != %u\n", uFormat, gcd.uFmtRet);
256  }
257 
258  /* Is it a global handle? */
259  if (pNewData)
260  hNewData = GlobalHandle(pNewData);
261 
262  if (hNewData)
263  {
264  /* Free old data */
265  if (pData)
266  {
267  GlobalUnlock(hData);
268  GlobalFree(hData);
269  }
270  hData = hNewData;
271  pData = pNewData;
272  }
273 
274  /* Save synthesized format in clipboard */
275  if (pData)
276  {
277  HANDLE hMem;
278 
279  scd.fGlobalHandle = TRUE;
280  hMem = NtUserConvertMemHandle(pData, GlobalSize(hData));
281  NtUserSetClipboardData(uFormat, hMem, &scd);
282  }
283  else if (hData)
284  NtUserSetClipboardData(uFormat, hData, &scd);
285  }
286 
287  /* Unlock global handle */
288  if (pData)
289  GlobalUnlock(hData);
290 
291  return hData;
292 }
293 
294 /*
295  * @implemented
296  */
297 HANDLE
298 WINAPI
300 {
301  DWORD dwSize;
302  HANDLE hGlobal;
303  LPVOID pMem;
304  HANDLE hRet = NULL, hTemp;
305  SETCLIPBDATA scd = {FALSE, FALSE};
306 
307  /* Check if this is a delayed rendering */
308  if (hMem == NULL)
309  return NtUserSetClipboardData(uFormat, NULL, &scd);
310 
311  if (hMem <= (HANDLE)4)
313  /* Bitmaps and palette does not use global handles */
314  else if (uFormat == CF_BITMAP || uFormat == CF_DSPBITMAP || uFormat == CF_PALETTE)
315  hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
316  /* Meta files are probably checked for validity */
317  else if (uFormat == CF_DSPMETAFILEPICT || uFormat == CF_METAFILEPICT )
318  {
319  hTemp = GdiConvertMetaFilePict( hMem );
320  hRet = NtUserSetClipboardData(uFormat, hTemp, &scd); // Note : LOL, it returns a BOOL not a HANDLE!!!!
321  if (hRet == hTemp) hRet = hMem; // If successful "TRUE", return the original handle.
322  }
323  else if (uFormat == CF_DSPENHMETAFILE || uFormat == CF_ENHMETAFILE)
324  {
325  hTemp = GdiConvertEnhMetaFile( hMem );
326  hRet = NtUserSetClipboardData(uFormat, hTemp, &scd);
327  if (hRet == hTemp) hRet = hMem;
328  }
329  else
330  {
331  /* Some formats accept only global handles, other accept global handles or integer values */
332  pMem = GlobalLock(hMem);
333  dwSize = GlobalSize(hMem);
334 
335  if (pMem || uFormat == CF_DIB || uFormat == CF_DIBV5 ||
336  uFormat == CF_DSPTEXT || uFormat == CF_LOCALE ||
337  uFormat == CF_OEMTEXT || uFormat == CF_TEXT ||
338  uFormat == CF_UNICODETEXT)
339  {
340  if (pMem)
341  {
342  /* This is a local memory. Make global memory object */
343  hGlobal = NtUserConvertMemHandle(pMem, dwSize);
344 
345  /* Unlock memory */
346  GlobalUnlock(hMem);
347  /* FIXME: free hMem when CloseClipboard is called */
348 
349  if (hGlobal)
350  {
351  /* Save data */
352  scd.fGlobalHandle = TRUE;
353  hRet = NtUserSetClipboardData(uFormat, hGlobal, &scd);
354  }
355 
356  /* On success NtUserSetClipboardData returns pMem
357  however caller expects us to return hMem */
358  if (hRet == hGlobal)
359  hRet = hMem;
360  }
361  else
363  }
364  else
365  {
366  /* Save a number */
367  hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
368  }
369  }
370 
371  if (!hRet)
372  ERR("SetClipboardData(%u, %p) failed\n", uFormat, hMem);
373 
374  return hRet;
375 }
376 
377 /*
378  * @unimplemented
379  */
380 BOOL
381 WINAPI
383 {
385  return FALSE;
386 }
387 /*
388  * @unimplemented
389  */
390 BOOL
391 WINAPI
393 {
395  return FALSE;
396 }
397 
398 /*
399  * @unimplemented
400  */
401 BOOL
402 WINAPI
404  UINT cFormats,
405  PUINT pcFormatsOut)
406 {
408  return FALSE;
409 }
INT APIENTRY NtUserGetClipboardFormatName(UINT fmt, LPWSTR lpszFormatName, INT cchMaxCount)
Definition: clipboard.c:733
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI AddClipboardFormatListener(HWND hwnd)
Definition: clipboard.c:382
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define WideCharToMultiByte
Definition: compat.h:101
#define CF_ENHMETAFILE
Definition: constants.h:409
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define CP_ACP
Definition: compat.h:99
#define CF_DSPMETAFILEPICT
Definition: constants.h:416
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE WINAPI GdiCreateLocalMetaFilePict(HANDLE)
Definition: metafile.c:106
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
HANDLE WINAPI GetClipboardData(UINT uFormat)
Definition: clipboard.c:198
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
#define CF_METAFILEPICT
Definition: constants.h:398
char * LPSTR
Definition: xmlstorage.h:182
#define NO_ERROR
Definition: dderror.h:5
int32_t INT
Definition: typedefs.h:56
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
BOOL WINAPI GetUpdatedClipboardFormats(PUINT lpuiFormats, UINT cFormats, PUINT pcFormatsOut)
Definition: clipboard.c:403
BOOL WINAPI CharToOemBuffA(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPSTR lpszDst, _In_ DWORD cchDstLength)
#define UNICODE_NULL
#define ANSI_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE APIENTRY NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd)
Definition: clipboard.c:894
#define FIXME(fmt,...)
Definition: debug.h:110
UINT WINAPI RegisterClipboardFormatW(LPCWSTR lpszFormat)
Definition: clipboard.c:133
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
#define CF_DSPENHMETAFILE
Definition: constants.h:417
BOOL fGlobalHandle
Definition: ntuser.h:1117
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_BITMAP
Definition: constants.h:397
smooth NULL
Definition: ftsmooth.c:416
WINE_DEFAULT_DEBUG_CHANNEL(ole)
NTSTATUS APIENTRY NtUserCreateLocalMemHandle(HANDLE hMem, PVOID pData, DWORD cbData, DWORD *pcbData)
Definition: clipboard.c:1229
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
const char * LPCSTR
Definition: xmlstorage.h:183
#define CF_TEXT
Definition: constants.h:396
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
INT WINAPI GetClipboardFormatNameW(UINT uFormat, LPWSTR lpszFormatName, INT cchMaxCount)
Definition: clipboard.c:86
static PVOID WINAPI IntSynthesizeMultiByte(PVOID pwStr, DWORD cbStr, BOOL bOem)
Definition: clipboard.c:154
HANDLE WINAPI SetClipboardData(UINT uFormat, HANDLE hMem)
Definition: clipboard.c:299
BOOL WINAPI OpenClipboard(HWND hWndNewOwner)
Definition: clipboard.c:29
static PVOID WINAPI IntSynthesizeWideChar(PVOID pwStr, DWORD cbStr, BOOL bOem)
Definition: clipboard.c:175
HANDLE APIENTRY NtUserSetClipboardData(UINT fmt, HANDLE hData, PSETCLIPBDATA pUnsafeScd)
Definition: clipboard.c:1081
__wchar_t WCHAR
Definition: xmlstorage.h:180
HANDLE APIENTRY NtUserConvertMemHandle(PVOID pData, DWORD cbData)
Definition: clipboard.c:1184
#define CF_DSPBITMAP
Definition: constants.h:415
#define WINAPI
Definition: msvc.h:8
HANDLE WINAPI GdiConvertMetaFilePict(HANDLE)
Definition: metafile.c:212
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:409
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
int ret
UINT NTAPI NtUserRegisterWindowMessage(PUNICODE_STRING MessageName)
Definition: window.c:4084
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define CF_PALETTE
Definition: constants.h:404
UINT WINAPI RegisterClipboardFormatA(LPCSTR lpszFormat)
Definition: clipboard.c:98
#define CF_LOCALE
Definition: constants.h:411
#define ERR(fmt,...)
Definition: debug.h:109
#define CF_OEMTEXT
Definition: constants.h:402
INT WINAPI GetClipboardFormatNameA(UINT format, LPSTR lpszFormatName, int cchMaxCount)
Definition: clipboard.c:50
BOOL APIENTRY NtUserOpenClipboard(HWND hWnd, DWORD Unknown1)
Definition: clipboard.c:530
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
BOOL WINAPI RemoveClipboardFormatListener(HWND hwnd)
Definition: clipboard.c:392
#define MultiByteToWideChar
Definition: compat.h:100
EXTINLINE UINT NtUserxEnumClipboardFormats(UINT format)
Definition: ntwrapper.h:611
UINT WINAPI EnumClipboardFormats(UINT format)
Definition: clipboard.c:39
#define GMEM_DDESHARE
Definition: winbase.h:295
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define ERROR_INVALID_NAME
Definition: compat.h:93
#define CF_DSPTEXT
Definition: constants.h:414
WCHAR * LPWSTR
Definition: xmlstorage.h:184
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
BOOL WINAPI OemToCharBuffA(_In_ LPCSTR lpszSrc, _Out_writes_(cchDstLength) LPSTR lpszDst, _In_ DWORD cchDstLength)
HANDLE WINAPI GdiConvertEnhMetaFile(HANDLE)
HANDLE WINAPI GdiCreateLocalEnhMetaFile(HANDLE)
Definition: enhmfile.c:78
#define CP_OEMCP
Definition: winnls.h:228
#define GMEM_MOVEABLE
Definition: winbase.h:291
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
unsigned int * PUINT
Definition: ndis.h:50
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static int gcd(int, int)
Definition: getopt.c:86
#define CF_DIB
Definition: constants.h:403