3 * PROJECT: ReactOS user32.dll
4 * FILE: lib/user32/windows/clipboard.c
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Pablo Borobia <pborobia@gmail.com>
9 * 09-05-2001 CSH Created
13 /* INCLUDES ******************************************************************/
19 #include <wine/debug.h>
20 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
24 /* FUNCTIONS *****************************************************************/
31 OpenClipboard(HWND hWndNewOwner
)
33 return NtUserOpenClipboard(hWndNewOwner
, 0);
41 EnumClipboardFormats(UINT format
)
43 return NtUserxEnumClipboardFormats(format
);
51 GetClipboardFormatNameA(UINT format
,
58 lpBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cchMaxCount
* sizeof(WCHAR
));
61 SetLastError(ERROR_OUTOFMEMORY
);
65 /* we need a UNICODE string */
66 Length
= NtUserGetClipboardFormatName(format
, lpBuffer
, cchMaxCount
);
70 if (!WideCharToMultiByte(CP_ACP
, 0, lpBuffer
, Length
, lpszFormatName
, cchMaxCount
, NULL
, NULL
))
72 /* clear result string */
75 lpszFormatName
[Length
] = '\0';
78 RtlFreeHeap(RtlGetProcessHeap(), 0, lpBuffer
);
87 GetClipboardFormatNameW(UINT uFormat
,
88 LPWSTR lpszFormatName
,
91 return NtUserGetClipboardFormatName(uFormat
, lpszFormatName
, cchMaxCount
);
99 RegisterClipboardFormatA(LPCSTR lpszFormat
)
102 UNICODE_STRING usFormat
= {0};
104 if (lpszFormat
== NULL
)
106 SetLastError(ERROR_INVALID_PARAMETER
);
111 if (*lpszFormat
== 0) //NULL
113 SetLastError(ERROR_INVALID_NAME
);
117 ret
= RtlCreateUnicodeStringFromAsciiz(&usFormat
, lpszFormat
);
120 ret
= NtUserRegisterWindowMessage(&usFormat
); //(LPCWSTR)
121 RtlFreeUnicodeString(&usFormat
);
132 RegisterClipboardFormatW(LPCWSTR lpszFormat
)
135 UNICODE_STRING usFormat
= {0};
137 if (lpszFormat
== NULL
)
139 SetLastError(ERROR_INVALID_PARAMETER
);
144 if (*lpszFormat
== 0) //NULL
146 SetLastError(ERROR_INVALID_NAME
);
150 RtlInitUnicodeString(&usFormat
, lpszFormat
);
151 ret
= NtUserRegisterWindowMessage(&usFormat
);
157 IntSynthesizeMultiByte(PVOID pwStr
, DWORD cbStr
, BOOL bOem
)
163 cbGlobal
= WideCharToMultiByte(bOem
? CP_OEMCP
: CP_ACP
,
164 0, pwStr
, cbStr
/ sizeof(WCHAR
),
165 NULL
, 0, NULL
, NULL
);
166 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbGlobal
);
170 pGlobal
= GlobalLock(hGlobal
);
171 WideCharToMultiByte(bOem
? CP_OEMCP
: CP_ACP
,
172 0, pwStr
, cbStr
/ sizeof(WCHAR
),
173 pGlobal
, cbGlobal
, NULL
, NULL
);
178 IntSynthesizeWideChar(PVOID pwStr
, DWORD cbStr
, BOOL bOem
)
184 cbGlobal
= MultiByteToWideChar(bOem
? CP_OEMCP
: CP_ACP
,
185 0, pwStr
, cbStr
, NULL
, 0) * sizeof(WCHAR
);
186 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbGlobal
);
190 pGlobal
= GlobalLock(hGlobal
);
191 MultiByteToWideChar(bOem
? CP_OEMCP
: CP_ACP
,
192 0, pwStr
, cbStr
, pGlobal
, cbGlobal
);
201 GetClipboardData(UINT uFormat
)
208 hData
= NtUserGetClipboardData(uFormat
, &gcd
);
212 if (gcd
.fGlobalHandle
)
216 NtUserCreateLocalMemHandle(hData
, NULL
, 0, &cbData
);
217 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbData
);
218 pData
= GlobalLock(hGlobal
);
219 NtUserCreateLocalMemHandle(hData
, pData
, cbData
, NULL
);
223 if (gcd
.uFmtRet
!= uFormat
)
225 SETCLIPBDATA scd
= {FALSE
, FALSE
};
226 HANDLE hNewData
= NULL
;
227 PVOID pNewData
= NULL
;
229 /* Synthesize requested format */
233 if (gcd
.uFmtRet
== CF_UNICODETEXT
)
234 pNewData
= IntSynthesizeMultiByte(pData
, cbData
, uFormat
== CF_OEMTEXT
);
236 OemToCharBuffA(pData
, pData
, cbData
);
239 if (gcd
.uFmtRet
== CF_UNICODETEXT
)
240 pNewData
= IntSynthesizeMultiByte(pData
, cbData
, uFormat
== CF_OEMTEXT
);
242 CharToOemBuffA(pData
, pData
, cbData
);
245 pNewData
= IntSynthesizeWideChar(pData
, cbData
, gcd
.uFmtRet
== CF_OEMTEXT
);
248 FIXME("Format: %u != %u\n", uFormat
, gcd
.uFmtRet
);
251 /* Is it a global handle? */
253 hNewData
= GlobalHandle(pNewData
);
267 /* Save synthesized format in clibboard */
272 scd
.fGlobalHandle
= TRUE
;
273 hMem
= NtUserConvertMemHandle(pData
, GlobalSize(hData
));
274 NtUserSetClipboardData(uFormat
, hMem
, &scd
);
277 NtUserSetClipboardData(uFormat
, hData
, &scd
);
280 /* Unlock global handle */
292 SetClipboardData(UINT uFormat
, HANDLE hMem
)
298 SETCLIPBDATA scd
= {FALSE
, FALSE
};
300 /* Check if this is delayed render */
302 return NtUserSetClipboardData(uFormat
, NULL
, &scd
);
304 if (hMem
<= (HANDLE
)4)
305 SetLastError(ERROR_INVALID_PARAMETER
);
306 /* Bitmaps and palette does not use global handles */
307 else if (uFormat
== CF_BITMAP
|| uFormat
== CF_DSPBITMAP
|| uFormat
== CF_PALETTE
)
308 hRet
= NtUserSetClipboardData(uFormat
, hMem
, &scd
);
309 /* Meta files are probably checked for validity */
310 else if (uFormat
== CF_DSPMETAFILEPICT
|| uFormat
== CF_METAFILEPICT
||
311 uFormat
== CF_DSPENHMETAFILE
|| uFormat
== CF_ENHMETAFILE
)
312 hRet
= NULL
; // not supported yet
315 /* Some formats accept only global handles, other accept global handles or integer values */
316 pMem
= GlobalLock(hMem
);
317 dwSize
= GlobalSize(hMem
);
319 if (pMem
|| uFormat
== CF_DIB
|| uFormat
== CF_DIBV5
||
320 uFormat
== CF_DSPTEXT
|| uFormat
== CF_LOCALE
||
321 uFormat
== CF_OEMTEXT
|| uFormat
== CF_TEXT
||
322 uFormat
== CF_UNICODETEXT
)
326 /* This is a local memory. Make global memory object */
327 hGlobal
= NtUserConvertMemHandle(pMem
, dwSize
);
331 /* FIXME: free hMem when CloseClipboard is called */
336 scd
.fGlobalHandle
= TRUE
;
337 hRet
= NtUserSetClipboardData(uFormat
, hGlobal
, &scd
);
340 /* On success NtUserSetClipboardData returns pMem
341 however caller expects us to return hMem */
346 SetLastError(ERROR_INVALID_HANDLE
);
351 hRet
= NtUserSetClipboardData(uFormat
, hMem
, &scd
);
356 ERR("SetClipboardData(%u, %p) failed\n", uFormat
, hMem
);
366 AddClipboardFormatListener(HWND hwnd
)
376 RemoveClipboardFormatListener(HWND hwnd
)
387 GetUpdatedClipboardFormats(PUINT lpuiFormats
,