]> git.saurik.com Git - wxWidgets.git/blame - src/msw/clipbrd.cpp
added common notebookbase source file
[wxWidgets.git] / src / msw / clipbrd.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: clipbrd.cpp
3// Purpose: Clipboard functionality
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
26f86486 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
26f86486
VZ
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
26f86486 21 #pragma implementation "clipbrd.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
26f86486 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
26f86486 32 #include "wx/setup.h"
2bda0e17
KB
33#endif
34
47d67540 35#if wxUSE_CLIPBOARD
2bda0e17
KB
36
37#ifndef WX_PRECOMP
26f86486
VZ
38 #include "wx/object.h"
39 #include "wx/event.h"
40 #include "wx/app.h"
41 #include "wx/frame.h"
42 #include "wx/bitmap.h"
43 #include "wx/utils.h"
0c589ad0 44 #include "wx/intl.h"
2bda0e17
KB
45#endif
46
06e43511 47#if wxUSE_METAFILE
26f86486 48 #include "wx/metafile.h"
06e43511
JS
49#endif
50
dbda9e86 51#include "wx/log.h"
2bda0e17 52#include "wx/clipbrd.h"
06e43511 53
3f480da3 54#include <string.h>
06e43511
JS
55#include <windows.h>
56
2bda0e17 57#include "wx/msw/private.h"
8cb172b4
JS
58
59#ifndef __WXMICROWIN__
2bda0e17 60#include "wx/msw/dib.h"
8cb172b4 61#endif
2bda0e17 62
d59ceba5
VZ
63// wxDataObject is tied to OLE/drag and drop implementation, therefore so are
64// the functions using wxDataObject in wxClipboard
1e6feb95 65//#define wxUSE_DATAOBJ wxUSE_DRAG_AND_DROP
d59ceba5
VZ
66
67#if wxUSE_DATAOBJ
26f86486 68 #include "wx/dataobj.h"
3f480da3 69
8cb172b4
JS
70// No: don't necessarily use OLE clipboard with data object
71#if 0
72 // use OLE clipboard
73 #define wxUSE_OLE_CLIPBOARD 1
74#endif
d59ceba5
VZ
75#else // !wxUSE_DATAOBJ
76 // use Win clipboard API
77 #define wxUSE_OLE_CLIPBOARD 0
2bda0e17
KB
78#endif
79
d59ceba5
VZ
80#if wxUSE_OLE_CLIPBOARD
81 #include <ole2.h>
82#endif // wxUSE_OLE_CLIPBOARD
83
3f480da3
VZ
84#ifdef __WIN16__
85 #define memcpy hmemcpy
86#endif
06e43511 87
26f86486
VZ
88// ===========================================================================
89// implementation
90// ===========================================================================
91
92// ---------------------------------------------------------------------------
93// old-style clipboard functions using Windows API
94// ---------------------------------------------------------------------------
2bda0e17 95
26f86486
VZ
96static bool gs_wxClipboardIsOpen = FALSE;
97
98bool wxOpenClipboard()
2bda0e17 99{
223d09f6 100 wxCHECK_MSG( !gs_wxClipboardIsOpen, TRUE, wxT("clipboard already opened.") );
26f86486
VZ
101
102 wxWindow *win = wxTheApp->GetTopWindow();
103 if ( win )
104 {
105 gs_wxClipboardIsOpen = ::OpenClipboard((HWND)win->GetHWND()) != 0;
106
107 if ( !gs_wxClipboardIsOpen )
108 wxLogSysError(_("Failed to open the clipboard."));
109
110 return gs_wxClipboardIsOpen;
111 }
112 else
113 {
223d09f6 114 wxLogDebug(wxT("Can not open clipboard without a main window."));
26f86486
VZ
115
116 return FALSE;
117 }
2bda0e17
KB
118}
119
26f86486 120bool wxCloseClipboard()
2bda0e17 121{
223d09f6 122 wxCHECK_MSG( gs_wxClipboardIsOpen, FALSE, wxT("clipboard is not opened") );
26f86486
VZ
123
124 gs_wxClipboardIsOpen = FALSE;
125
126 if ( ::CloseClipboard() == 0 )
127 {
128 wxLogSysError(_("Failed to close the clipboard."));
129
130 return FALSE;
131 }
132
133 return TRUE;
2bda0e17
KB
134}
135
26f86486 136bool wxEmptyClipboard()
2bda0e17 137{
26f86486
VZ
138 if ( ::EmptyClipboard() == 0 )
139 {
140 wxLogSysError(_("Failed to empty the clipboard."));
141
142 return FALSE;
143 }
144
145 return TRUE;
2bda0e17
KB
146}
147
26f86486 148bool wxIsClipboardOpened()
2bda0e17 149{
26f86486 150 return gs_wxClipboardIsOpen;
2bda0e17
KB
151}
152
06e43511 153bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
2bda0e17 154{
d9317fd4
VZ
155 if ( ::IsClipboardFormatAvailable(dataFormat) )
156 {
157 // ok from the first try
158 return TRUE;
159 }
160
161 // for several standard formats, we can convert from some other ones too
162 switch ( dataFormat.GetFormatId() )
163 {
164 // for bitmaps, DIBs will also do
165 case CF_BITMAP:
166 return ::IsClipboardFormatAvailable(CF_DIB) != 0;
167
5dd26b08 168#if wxUSE_ENH_METAFILE && !defined(__WIN16__)
d9317fd4
VZ
169 case CF_METAFILEPICT:
170 return ::IsClipboardFormatAvailable(CF_ENHMETAFILE) != 0;
171#endif // wxUSE_ENH_METAFILE
172
173 default:
174 return FALSE;
175 }
2bda0e17
KB
176}
177
26f86486
VZ
178bool wxSetClipboardData(wxDataFormat dataFormat,
179 const void *data,
180 int width, int height)
2bda0e17 181{
26f86486
VZ
182 HANDLE handle = 0; // return value of SetClipboardData
183
184 switch (dataFormat)
2bda0e17 185 {
26f86486
VZ
186 case wxDF_BITMAP:
187 {
188 wxBitmap *bitmap = (wxBitmap *)data;
189
190 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
191 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
192 HBITMAP old = (HBITMAP)
193 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
194 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
195 bitmap->GetWidth(),
196 bitmap->GetHeight());
197 if (!hBitmap)
198 {
199 SelectObject(hdcSrc, old);
200 DeleteDC(hdcMem);
201 DeleteDC(hdcSrc);
202 return FALSE;
203 }
204
205 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
206 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
207 hdcSrc, 0, 0, SRCCOPY);
208
209 // Select new bitmap out of memory DC
210 SelectObject(hdcMem, old1);
211
212 // Set the data
213 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
214
215 // Clean up
216 SelectObject(hdcSrc, old);
217 DeleteDC(hdcSrc);
218 DeleteDC(hdcMem);
219 break;
220 }
221
222 case wxDF_DIB:
223 {
47d67540 224#if wxUSE_IMAGE_LOADING_IN_MSW
26f86486
VZ
225 wxBitmap *bitmap = (wxBitmap *)data;
226 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
227 // NULL palette means to use the system one
33ac7e6f 228 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
26f86486 229 handle = SetClipboardData(CF_DIB, hDIB);
d59ceba5 230#endif // wxUSE_IMAGE_LOADING_IN_MSW
26f86486
VZ
231 break;
232 }
233
d9317fd4
VZ
234 // VZ: I'm told that this code works, but it doesn't seem to work for me
235 // and, anyhow, I'd be highly surprized if it did. So I leave it here
236 // but IMNSHO it is completely broken.
237#if wxUSE_METAFILE && !defined(wxMETAFILE_IS_ENH)
26f86486
VZ
238 case wxDF_METAFILE:
239 {
240 wxMetafile *wxMF = (wxMetafile *)data;
241 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
26f86486 242 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
2bda0e17 243
26f86486
VZ
244 mf->mm = wxMF->GetWindowsMappingMode();
245 mf->xExt = width;
246 mf->yExt = height;
247 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
248 GlobalUnlock(data);
249 wxMF->SetHMETAFILE((WXHANDLE) NULL);
2bda0e17 250
26f86486
VZ
251 handle = SetClipboardData(CF_METAFILEPICT, data);
252 break;
253 }
d9317fd4
VZ
254#endif // wxUSE_METAFILE
255
5dd26b08 256#if wxUSE_ENH_METAFILE && !defined(__WIN16__)
d9317fd4
VZ
257 case wxDF_ENHMETAFILE:
258 {
259 wxEnhMetaFile *emf = (wxEnhMetaFile *)data;
260 wxEnhMetaFile emfCopy = *emf;
261
262 handle = SetClipboardData(CF_ENHMETAFILE,
263 (void *)emfCopy.GetHENHMETAFILE());
264 }
265 break;
266#endif // wxUSE_ENH_METAFILE
267
26f86486
VZ
268 case CF_SYLK:
269 case CF_DIF:
270 case CF_TIFF:
271 case CF_PALETTE:
272 default:
273 {
274 wxLogError(_("Unsupported clipboard format."));
275 return FALSE;
276 }
2bda0e17 277
26f86486
VZ
278 case wxDF_OEMTEXT:
279 dataFormat = wxDF_TEXT;
280 // fall through
2bda0e17 281
26f86486
VZ
282 case wxDF_TEXT:
283 {
284 char *s = (char *)data;
285
286 width = strlen(s) + 1;
287 height = 1;
288 DWORD l = (width * height);
289 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
290 if ( hGlobalMemory )
291 {
26f86486 292 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
2bda0e17 293
26f86486 294 memcpy(lpGlobalMemory, s, l);
2bda0e17 295
26f86486
VZ
296 GlobalUnlock(hGlobalMemory);
297 }
2bda0e17 298
26f86486
VZ
299 handle = SetClipboardData(dataFormat, hGlobalMemory);
300 break;
301 }
2bda0e17 302 }
26f86486
VZ
303
304 if ( handle == 0 )
2bda0e17 305 {
26f86486
VZ
306 wxLogSysError(_("Failed to set clipboard data."));
307
308 return FALSE;
2bda0e17 309 }
26f86486
VZ
310
311 return TRUE;
312}
313
314void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
315{
316 void *retval = NULL;
317
318 switch ( dataFormat )
2bda0e17 319 {
26f86486
VZ
320 case wxDF_BITMAP:
321 {
322 BITMAP bm;
323 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
324 if (!hBitmap)
325 break;
326
327 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
328 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
329
330 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
331 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
332
333 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
334
335 if (!hNewBitmap)
336 {
337 SelectObject(hdcSrc, old);
338 DeleteDC(hdcMem);
339 DeleteDC(hdcSrc);
340 break;
341 }
342
343 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
344 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
345 hdcSrc, 0, 0, SRCCOPY);
346
347 // Select new bitmap out of memory DC
348 SelectObject(hdcMem, old1);
349
350 // Clean up
351 SelectObject(hdcSrc, old);
352 DeleteDC(hdcSrc);
353 DeleteDC(hdcMem);
354
355 // Create and return a new wxBitmap
356 wxBitmap *wxBM = new wxBitmap;
357 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
358 wxBM->SetWidth(bm.bmWidth);
359 wxBM->SetHeight(bm.bmHeight);
360 wxBM->SetDepth(bm.bmPlanes);
6d167489 361#if WXWIN_COMPATIBILITY_2
26f86486 362 wxBM->SetOk(TRUE);
6d167489 363#endif // WXWIN_COMPATIBILITY_2
26f86486
VZ
364 retval = wxBM;
365 break;
366 }
367
368 case wxDF_METAFILE:
369 case CF_SYLK:
370 case CF_DIF:
371 case CF_TIFF:
372 case CF_PALETTE:
373 case wxDF_DIB:
26f86486
VZ
374 {
375 wxLogError(_("Unsupported clipboard format."));
376 return FALSE;
377 }
378
379 case wxDF_OEMTEXT:
380 dataFormat = wxDF_TEXT;
381 // fall through
382
383 case wxDF_TEXT:
384 {
385 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
386 if (!hGlobalMemory)
387 break;
2bda0e17 388
26f86486
VZ
389 DWORD hsize = ::GlobalSize(hGlobalMemory);
390 if (len)
391 *len = hsize;
2bda0e17 392
26f86486
VZ
393 char *s = new char[hsize];
394 if (!s)
395 break;
2bda0e17 396
26f86486 397 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
2bda0e17 398
26f86486 399 memcpy(s, lpGlobalMemory, hsize);
2bda0e17 400
26f86486
VZ
401 ::GlobalUnlock(hGlobalMemory);
402
403 retval = s;
404 break;
405 }
3f480da3
VZ
406
407 default:
408 {
409 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
410 if ( !hGlobalMemory )
411 break;
412
413 DWORD size = ::GlobalSize(hGlobalMemory);
414 if ( len )
415 *len = size;
416
417 void *buf = malloc(size);
418 if ( !buf )
419 break;
420
421 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
422
423 memcpy(buf, lpGlobalMemory, size);
424
425 ::GlobalUnlock(hGlobalMemory);
426
427 retval = buf;
428 break;
429 }
26f86486 430 }
2bda0e17 431
26f86486
VZ
432 if ( !retval )
433 {
434 wxLogSysError(_("Failed to retrieve data from the clipboard."));
2bda0e17 435 }
26f86486
VZ
436
437 return retval;
2bda0e17
KB
438}
439
3f480da3 440wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
2bda0e17 441{
33ac7e6f 442 return (wxDataFormat::NativeFormat)::EnumClipboardFormats(dataFormat);
2bda0e17
KB
443}
444
837e5743 445int wxRegisterClipboardFormat(wxChar *formatName)
2bda0e17
KB
446{
447 return ::RegisterClipboardFormat(formatName);
448}
449
26f86486 450bool wxGetClipboardFormatName(wxDataFormat dataFormat,
837e5743 451 wxChar *formatName,
26f86486 452 int maxCount)
2bda0e17 453{
26f86486 454 return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
2bda0e17
KB
455}
456
26f86486 457// ---------------------------------------------------------------------------
06e43511 458// wxClipboard
26f86486 459// ---------------------------------------------------------------------------
2bda0e17 460
26f86486 461IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
2bda0e17
KB
462
463wxClipboard::wxClipboard()
464{
d59ceba5 465 m_clearOnExit = FALSE;
2bda0e17
KB
466}
467
468wxClipboard::~wxClipboard()
469{
d59ceba5
VZ
470 if ( m_clearOnExit )
471 {
472 Clear();
473 }
2bda0e17
KB
474}
475
06e43511 476void wxClipboard::Clear()
2bda0e17 477{
d59ceba5
VZ
478#if wxUSE_OLE_CLIPBOARD
479 if ( FAILED(OleSetClipboard(NULL)) )
480 {
f6bcfd97 481 wxLogLastError(wxT("OleSetClipboard(NULL)"));
d59ceba5
VZ
482 }
483#endif
484}
485
486bool wxClipboard::Flush()
487{
7ffdaf81 488#if wxUSE_OLE_CLIPBOARD
d59ceba5
VZ
489 if ( FAILED(OleFlushClipboard()) )
490 {
f6bcfd97 491 wxLogLastError(wxT("OleFlushClipboard"));
d59ceba5
VZ
492
493 return FALSE;
494 }
495 else
496 {
497 m_clearOnExit = FALSE;
498
499 return TRUE;
500 }
7ffdaf81
VZ
501#else // !wxUSE_OLE_CLIPBOARD
502 return FALSE;
503#endif // wxUSE_OLE_CLIPBOARD/!wxUSE_OLE_CLIPBOARD
2bda0e17
KB
504}
505
06e43511 506bool wxClipboard::Open()
2bda0e17 507{
d59ceba5
VZ
508 // OLE opens clipboard for us
509#if wxUSE_OLE_CLIPBOARD
510 return TRUE;
511#else
06e43511 512 return wxOpenClipboard();
d59ceba5 513#endif
2bda0e17
KB
514}
515
f536e0f2
VZ
516bool wxClipboard::IsOpened() const
517{
518#if wxUSE_OLE_CLIPBOARD
519 return TRUE;
520#else
521 return wxIsClipboardOpened();
522#endif
523}
524
06e43511 525bool wxClipboard::SetData( wxDataObject *data )
2bda0e17 526{
51edda6a 527#if !wxUSE_OLE_CLIPBOARD
26f86486 528 (void)wxEmptyClipboard();
51edda6a 529#endif // wxUSE_OLE_CLIPBOARD
26f86486
VZ
530
531 if ( data )
532 return AddData(data);
533 else
534 return TRUE;
535}
536
537bool wxClipboard::AddData( wxDataObject *data )
538{
223d09f6 539 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
06e43511 540
d59ceba5
VZ
541#if wxUSE_OLE_CLIPBOARD
542 HRESULT hr = OleSetClipboard(data->GetInterface());
543 if ( FAILED(hr) )
544 {
545 wxLogSysError(hr, _("Failed to put data on the clipboard"));
546
547 // don't free anything in this case
548
549 return FALSE;
550 }
551
552 // we have a problem here because we should delete wxDataObject, but we
553 // can't do it because IDataObject which we just gave to the clipboard
554 // would try to use it when it will need the data. IDataObject is ref
555 // counted and so doesn't suffer from such problem, so we release it now
556 // and tell it to delete wxDataObject when it is deleted itself.
557 data->SetAutoDelete();
558
559 // we have to call either OleSetClipboard(NULL) or OleFlushClipboard() when
560 // using OLE clipboard when the app terminates - by default, we call
561 // OleSetClipboard(NULL) which won't waste RAM, but the app can call
562 // wxClipboard::Flush() to chaneg this
563 m_clearOnExit = TRUE;
564
565 return TRUE;
566#elif wxUSE_DATAOBJ
223d09f6 567 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
26f86486
VZ
568
569 wxDataFormat format = data->GetFormat();
570
571 switch ( format )
06e43511
JS
572 {
573 case wxDF_TEXT:
574 case wxDF_OEMTEXT:
575 {
576 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
577 wxString str(textDataObject->GetText());
26f86486 578 return wxSetClipboardData(format, str.c_str());
06e43511 579 }
26f86486 580
06e43511
JS
581 case wxDF_BITMAP:
582 case wxDF_DIB:
583 {
584 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
585 wxBitmap bitmap(bitmapDataObject->GetBitmap());
26f86486 586 return wxSetClipboardData(data->GetFormat(), &bitmap);
06e43511 587 }
26f86486 588
06e43511
JS
589#if wxUSE_METAFILE
590 case wxDF_METAFILE:
591 {
33ac7e6f 592 wxMetafileDataObject* metaFileDataObject =
26f86486 593 (wxMetafileDataObject*) data;
06e43511 594 wxMetafile metaFile = metaFileDataObject->GetMetafile();
26f86486
VZ
595 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
596 metaFileDataObject->GetWidth(),
597 metaFileDataObject->GetHeight());
06e43511 598 }
26f86486
VZ
599#endif // wxUSE_METAFILE
600
06e43511 601 default:
3f480da3 602 return wxSetClipboardData(data);
06e43511 603 }
d59ceba5 604#else // !wxUSE_DATAOBJ
06e43511 605 return FALSE;
d59ceba5 606#endif // wxUSE_DATAOBJ/!wxUSE_DATAOBJ
2bda0e17
KB
607}
608
06e43511 609void wxClipboard::Close()
2bda0e17 610{
d59ceba5
VZ
611 // OLE closes clipboard for us
612#if !wxUSE_OLE_CLIPBOARD
06e43511 613 wxCloseClipboard();
d59ceba5 614#endif
2bda0e17
KB
615}
616
26f86486 617bool wxClipboard::IsSupported( wxDataFormat format )
2bda0e17 618{
06e43511 619 return wxIsClipboardFormatAvailable(format);
2bda0e17
KB
620}
621
1e8335b0 622bool wxClipboard::GetData( wxDataObject& data )
2bda0e17 623{
d59ceba5
VZ
624#if wxUSE_OLE_CLIPBOARD
625 IDataObject *pDataObject = NULL;
626 HRESULT hr = OleGetClipboard(&pDataObject);
627 if ( FAILED(hr) || !pDataObject )
628 {
629 wxLogSysError(hr, _("Failed to get data from the clipboard"));
630
631 return FALSE;
632 }
633
634 // build the list of supported formats
1e8335b0 635 size_t nFormats = data.GetFormatCount(wxDataObject::Set);
33ac7e6f
KB
636 wxDataFormat format;
637 wxDataFormat *formats;
d59ceba5
VZ
638 if ( nFormats == 1 )
639 {
640 // the most common case
641 formats = &format;
642 }
643 else
644 {
645 // bad luck, need to alloc mem
646 formats = new wxDataFormat[nFormats];
647 }
648
1e8335b0 649 data.GetAllFormats(formats, wxDataObject::Set);
d59ceba5
VZ
650
651 // get the format enumerator
652 bool result = FALSE;
653 wxArrayInt supportedFormats;
654 IEnumFORMATETC *pEnumFormatEtc = NULL;
655 hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
656 if ( FAILED(hr) || !pEnumFormatEtc )
657 {
658 wxLogSysError(hr,
659 _("Failed to retrieve the supported clipboard formats"));
660 }
661 else
662 {
663 // ask for the supported formats and see if there are any we support
664 FORMATETC formatEtc;
665 for ( ;; )
666 {
667 ULONG nCount;
668 hr = pEnumFormatEtc->Next(1, &formatEtc, &nCount);
669
670 // don't use FAILED() because S_FALSE would pass it
671 if ( hr != S_OK )
672 {
673 // no more formats
674 break;
675 }
676
677 CLIPFORMAT cf = formatEtc.cfFormat;
678
679#ifdef __WXDEBUG__
680 wxLogTrace(wxTRACE_OleCalls,
681 wxT("Object on the clipboard supports format %s."),
682 wxDataObject::GetFormatName(cf));
683#endif // Debug
684
685 // is supported?
686 for ( size_t n = 0; n < nFormats; n++ )
687 {
688 if ( formats[n].GetFormatId() == cf )
689 {
690 if ( supportedFormats.Index(cf) == wxNOT_FOUND )
691 {
692 supportedFormats.Add(cf);
693 }
694 }
695 }
696 }
697
698 pEnumFormatEtc->Release();
699 }
700
701 if ( formats != &format )
702 {
703 delete [] formats;
704 }
705 //else: we didn't allocate any memory
706
707 if ( !supportedFormats.IsEmpty() )
708 {
709 FORMATETC formatEtc;
710 formatEtc.ptd = NULL;
711 formatEtc.dwAspect = DVASPECT_CONTENT;
712 formatEtc.lindex = -1;
d59ceba5
VZ
713
714 size_t nSupportedFormats = supportedFormats.GetCount();
715 for ( size_t n = 0; !result && (n < nSupportedFormats); n++ )
716 {
717 STGMEDIUM medium;
718 formatEtc.cfFormat = supportedFormats[n];
719
265b0c07
VZ
720 // use the appropriate tymed
721 switch ( formatEtc.cfFormat )
722 {
723 case CF_BITMAP:
724 formatEtc.tymed = TYMED_GDI;
725 break;
726
727 case CF_METAFILEPICT:
728 formatEtc.tymed = TYMED_MFPICT;
729 break;
730
d9317fd4
VZ
731 case CF_ENHMETAFILE:
732 formatEtc.tymed = TYMED_ENHMF;
733 break;
734
265b0c07
VZ
735 default:
736 formatEtc.tymed = TYMED_HGLOBAL;
737 }
738
d59ceba5
VZ
739 // try to get data
740 hr = pDataObject->GetData(&formatEtc, &medium);
741 if ( FAILED(hr) )
742 {
743 // try other tymed for GDI objects
744 if ( formatEtc.cfFormat == CF_BITMAP )
745 {
746 formatEtc.tymed = TYMED_HGLOBAL;
747 hr = pDataObject->GetData(&formatEtc, &medium);
748 }
749 }
750
751 if ( SUCCEEDED(hr) )
752 {
753 // pass the data to the data object
1e8335b0 754 hr = data.GetInterface()->SetData(&formatEtc, &medium, TRUE);
d59ceba5
VZ
755 if ( FAILED(hr) )
756 {
757 wxLogDebug(wxT("Failed to set data in wxIDataObject"));
758
759 // IDataObject only takes the ownership of data if it
760 // successfully got it - which is not the case here
761 ReleaseStgMedium(&medium);
762 }
763 else
764 {
765 result = TRUE;
766 }
767 }
768 //else: unsupported tymed?
769 }
770 }
771 //else: unsupported format
772
773 // clean up and return
774 pDataObject->Release();
775
776 return result;
777#elif wxUSE_DATAOBJ
223d09f6 778 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
26f86486 779
1e8335b0 780 wxDataFormat format = data.GetFormat();
26f86486 781 switch ( format )
06e43511
JS
782 {
783 case wxDF_TEXT:
784 case wxDF_OEMTEXT:
785 {
1e8335b0
VZ
786 wxTextDataObject& textDataObject = (wxTextDataObject &)data;
787 char* s = (char*)wxGetClipboardData(format);
788 if ( !s )
06e43511 789 return FALSE;
1e8335b0
VZ
790
791 textDataObject.SetText(s);
792 delete [] s;
793
794 return TRUE;
06e43511 795 }
26f86486 796
06e43511
JS
797 case wxDF_BITMAP:
798 case wxDF_DIB:
799 {
1e8335b0 800 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
26f86486 801 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetFormat());
1e8335b0 802 if ( !bitmap )
06e43511 803 return FALSE;
1e8335b0
VZ
804
805 bitmapDataObject.SetBitmap(*bitmap);
806 delete bitmap;
807
808 return TRUE;
06e43511
JS
809 }
810#if wxUSE_METAFILE
811 case wxDF_METAFILE:
812 {
1e8335b0 813 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
26f86486 814 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
1e8335b0 815 if ( !metaFile )
06e43511 816 return FALSE;
3f480da3 817
1e8335b0
VZ
818 metaFileDataObject.SetMetafile(*metaFile);
819 delete metaFile;
26f86486 820
1e8335b0
VZ
821 return TRUE;
822 }
823#endif // wxUSE_METAFILE
06e43511 824 }
3897b707 825 return FALSE;
d59ceba5 826#else // !wxUSE_DATAOBJ
1e8335b0 827 wxFAIL_MSG( wxT("no clipboard implementation") );
06e43511 828 return FALSE;
3897b707 829#endif // wxUSE_OLE_CLIPBOARD/wxUSE_DATAOBJ
2bda0e17
KB
830}
831
26f86486 832#else
f6bcfd97 833// #error "Please turn wxUSE_CLIPBOARD on to compile this file."
47d67540 834#endif // wxUSE_CLIPBOARD
4ce81a75 835