2 * PROJECT: ReactOS user32.dll
3 * FILE: lib/user32/windows/clipboard.c
5 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * Pablo Borobia <pborobia@gmail.com>
8 * 09-05-2001 CSH Created
12 /* INCLUDES ******************************************************************/
18 #include <wine/debug.h>
19 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
23 /* FUNCTIONS *****************************************************************/
30 OpenClipboard(HWND hWndNewOwner
)
32 return NtUserOpenClipboard(hWndNewOwner
, 0);
40 EnumClipboardFormats(UINT format
)
42 return NtUserxEnumClipboardFormats(format
);
50 GetClipboardFormatNameA(UINT format
,
57 lpBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, cchMaxCount
* sizeof(WCHAR
));
60 SetLastError(ERROR_OUTOFMEMORY
);
64 /* we need a UNICODE string */
65 Length
= NtUserGetClipboardFormatName(format
, lpBuffer
, cchMaxCount
);
69 if (!WideCharToMultiByte(CP_ACP
, 0, lpBuffer
, Length
, lpszFormatName
, cchMaxCount
, NULL
, NULL
))
71 /* clear result string */
74 lpszFormatName
[Length
] = '\0';
77 RtlFreeHeap(RtlGetProcessHeap(), 0, lpBuffer
);
86 GetClipboardFormatNameW(UINT uFormat
,
87 LPWSTR lpszFormatName
,
90 return NtUserGetClipboardFormatName(uFormat
, lpszFormatName
, cchMaxCount
);
98 RegisterClipboardFormatA(LPCSTR lpszFormat
)
101 UNICODE_STRING usFormat
= {0};
103 if (lpszFormat
== NULL
)
105 SetLastError(ERROR_INVALID_PARAMETER
);
110 if (*lpszFormat
== 0) //NULL
112 SetLastError(ERROR_INVALID_NAME
);
116 ret
= RtlCreateUnicodeStringFromAsciiz(&usFormat
, lpszFormat
);
119 ret
= NtUserRegisterWindowMessage(&usFormat
); //(LPCWSTR)
120 RtlFreeUnicodeString(&usFormat
);
131 RegisterClipboardFormatW(LPCWSTR lpszFormat
)
134 UNICODE_STRING usFormat
= {0};
136 if (lpszFormat
== NULL
)
138 SetLastError(ERROR_INVALID_PARAMETER
);
143 if (*lpszFormat
== 0) //NULL
145 SetLastError(ERROR_INVALID_NAME
);
149 RtlInitUnicodeString(&usFormat
, lpszFormat
);
150 ret
= NtUserRegisterWindowMessage(&usFormat
);
156 IntSynthesizeMultiByte(PVOID pwStr
, DWORD cbStr
, BOOL bOem
)
162 cbGlobal
= WideCharToMultiByte(bOem
? CP_OEMCP
: CP_ACP
,
163 0, pwStr
, cbStr
/ sizeof(WCHAR
),
164 NULL
, 0, NULL
, NULL
);
165 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbGlobal
);
169 pGlobal
= GlobalLock(hGlobal
);
170 WideCharToMultiByte(bOem
? CP_OEMCP
: CP_ACP
,
171 0, pwStr
, cbStr
/ sizeof(WCHAR
),
172 pGlobal
, cbGlobal
, NULL
, NULL
);
177 IntSynthesizeWideChar(PVOID pwStr
, DWORD cbStr
, BOOL bOem
)
183 cbGlobal
= MultiByteToWideChar(bOem
? CP_OEMCP
: CP_ACP
,
184 0, pwStr
, cbStr
, NULL
, 0) * sizeof(WCHAR
);
185 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbGlobal
);
189 pGlobal
= GlobalLock(hGlobal
);
190 MultiByteToWideChar(bOem
? CP_OEMCP
: CP_ACP
,
191 0, pwStr
, cbStr
, pGlobal
, cbGlobal
);
200 GetClipboardData(UINT uFormat
)
207 hData
= NtUserGetClipboardData(uFormat
, &gcd
);
211 if (gcd
.fGlobalHandle
)
215 NtUserCreateLocalMemHandle(hData
, NULL
, 0, &cbData
);
216 hGlobal
= GlobalAlloc(GMEM_DDESHARE
| GMEM_MOVEABLE
, cbData
);
217 pData
= GlobalLock(hGlobal
);
218 NtUserCreateLocalMemHandle(hData
, pData
, cbData
, NULL
);
222 if (gcd
.uFmtRet
!= uFormat
)
224 SETCLIPBDATA scd
= {FALSE
, FALSE
};
225 HANDLE hNewData
= NULL
;
226 PVOID pNewData
= NULL
;
228 /* Synthesize requested format */
232 if (gcd
.uFmtRet
== CF_UNICODETEXT
)
233 pNewData
= IntSynthesizeMultiByte(pData
, cbData
, uFormat
== CF_OEMTEXT
);
235 OemToCharBuffA(pData
, pData
, cbData
);
238 if (gcd
.uFmtRet
== CF_UNICODETEXT
)
239 pNewData
= IntSynthesizeMultiByte(pData
, cbData
, uFormat
== CF_OEMTEXT
);
241 CharToOemBuffA(pData
, pData
, cbData
);
244 pNewData
= IntSynthesizeWideChar(pData
, cbData
, gcd
.uFmtRet
== CF_OEMTEXT
);
247 FIXME("Format: %u != %u\n", uFormat
, gcd
.uFmtRet
);
250 /* Is it a global handle? */
252 hNewData
= GlobalHandle(pNewData
);
266 /* Save synthesized format in clibboard */
271 scd
.fGlobalHandle
= TRUE
;
272 hMem
= NtUserConvertMemHandle(pData
, GlobalSize(hData
));
273 NtUserSetClipboardData(uFormat
, hMem
, &scd
);
276 NtUserSetClipboardData(uFormat
, hData
, &scd
);
279 /* Unlock global handle */
291 SetClipboardData(UINT uFormat
, HANDLE hMem
)
297 SETCLIPBDATA scd
= {FALSE
, FALSE
};
299 /* Check if this is delayed render */
301 return NtUserSetClipboardData(uFormat
, NULL
, &scd
);
303 if (hMem
<= (HANDLE
)4)
304 SetLastError(ERROR_INVALID_PARAMETER
);
305 /* Bitmaps and palette does not use global handles */
306 else if (uFormat
== CF_BITMAP
|| uFormat
== CF_DSPBITMAP
|| uFormat
== CF_PALETTE
)
307 hRet
= NtUserSetClipboardData(uFormat
, hMem
, &scd
);
308 /* Meta files are probably checked for validity */
309 else if (uFormat
== CF_DSPMETAFILEPICT
|| uFormat
== CF_METAFILEPICT
||
310 uFormat
== CF_DSPENHMETAFILE
|| uFormat
== CF_ENHMETAFILE
)
311 hRet
= NULL
; // not supported yet
314 /* Some formats accept only global handles, other accept global handles or integer values */
315 pMem
= GlobalLock(hMem
);
316 dwSize
= GlobalSize(hMem
);
318 if (pMem
|| uFormat
== CF_DIB
|| uFormat
== CF_DIBV5
||
319 uFormat
== CF_DSPTEXT
|| uFormat
== CF_LOCALE
||
320 uFormat
== CF_OEMTEXT
|| uFormat
== CF_TEXT
||
321 uFormat
== CF_UNICODETEXT
)
325 /* This is a local memory. Make global memory object */
326 hGlobal
= NtUserConvertMemHandle(pMem
, dwSize
);
330 /* FIXME: free hMem when CloseClipboard is called */
335 scd
.fGlobalHandle
= TRUE
;
336 hRet
= NtUserSetClipboardData(uFormat
, hGlobal
, &scd
);
339 /* On success NtUserSetClipboardData returns pMem
340 however caller expects us to return hMem */
345 SetLastError(ERROR_INVALID_HANDLE
);
350 hRet
= NtUserSetClipboardData(uFormat
, hMem
, &scd
);
355 ERR("SetClipboardData(%u, %p) failed\n", uFormat
, hMem
);
365 AddClipboardFormatListener(HWND hwnd
)
375 RemoveClipboardFormatListener(HWND hwnd
)
386 GetUpdatedClipboardFormats(PUINT lpuiFormats
,