]> git.saurik.com Git - wxWidgets.git/blob - src/msw/clipbrd.cpp
Various wxUniversal/wxMicroWindows fixes
[wxWidgets.git] / src / msw / clipbrd.cpp
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
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "clipbrd.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/setup.h"
33 #endif
34
35 #if wxUSE_CLIPBOARD
36
37 #ifndef WX_PRECOMP
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"
44 #include "wx/intl.h"
45 #endif
46
47 #if wxUSE_METAFILE
48 #include "wx/metafile.h"
49 #endif
50
51 #include "wx/log.h"
52 #include "wx/clipbrd.h"
53
54 #include <string.h>
55 #include <windows.h>
56
57 #include "wx/msw/private.h"
58
59 #ifndef __WXMICROWIN__
60 #include "wx/msw/dib.h"
61 #endif
62
63 // wxDataObject is tied to OLE/drag and drop implementation, therefore so are
64 // the functions using wxDataObject in wxClipboard
65 //#define wxUSE_DATAOBJ wxUSE_DRAG_AND_DROP
66
67 #if wxUSE_DATAOBJ
68 #include "wx/dataobj.h"
69
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
75 #else // !wxUSE_DATAOBJ
76 // use Win clipboard API
77 #define wxUSE_OLE_CLIPBOARD 0
78 #endif
79
80 #if wxUSE_OLE_CLIPBOARD
81 #include <ole2.h>
82 #endif // wxUSE_OLE_CLIPBOARD
83
84 #ifdef __WIN16__
85 #define memcpy hmemcpy
86 #endif
87
88 // ===========================================================================
89 // implementation
90 // ===========================================================================
91
92 // ---------------------------------------------------------------------------
93 // old-style clipboard functions using Windows API
94 // ---------------------------------------------------------------------------
95
96 static bool gs_wxClipboardIsOpen = FALSE;
97
98 bool wxOpenClipboard()
99 {
100 wxCHECK_MSG( !gs_wxClipboardIsOpen, TRUE, wxT("clipboard already opened.") );
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 {
114 wxLogDebug(wxT("Can not open clipboard without a main window."));
115
116 return FALSE;
117 }
118 }
119
120 bool wxCloseClipboard()
121 {
122 wxCHECK_MSG( gs_wxClipboardIsOpen, FALSE, wxT("clipboard is not opened") );
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;
134 }
135
136 bool wxEmptyClipboard()
137 {
138 if ( ::EmptyClipboard() == 0 )
139 {
140 wxLogSysError(_("Failed to empty the clipboard."));
141
142 return FALSE;
143 }
144
145 return TRUE;
146 }
147
148 bool wxIsClipboardOpened()
149 {
150 return gs_wxClipboardIsOpen;
151 }
152
153 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
154 {
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
168 #if wxUSE_ENH_METAFILE && !defined(__WIN16__)
169 case CF_METAFILEPICT:
170 return ::IsClipboardFormatAvailable(CF_ENHMETAFILE) != 0;
171 #endif // wxUSE_ENH_METAFILE
172
173 default:
174 return FALSE;
175 }
176 }
177
178 bool wxSetClipboardData(wxDataFormat dataFormat,
179 const void *data,
180 int width, int height)
181 {
182 HANDLE handle = 0; // return value of SetClipboardData
183
184 switch (dataFormat)
185 {
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 {
224 #if wxUSE_IMAGE_LOADING_IN_MSW
225 wxBitmap *bitmap = (wxBitmap *)data;
226 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
227 // NULL palette means to use the system one
228 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
229 handle = SetClipboardData(CF_DIB, hDIB);
230 #endif // wxUSE_IMAGE_LOADING_IN_MSW
231 break;
232 }
233
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)
238 case wxDF_METAFILE:
239 {
240 wxMetafile *wxMF = (wxMetafile *)data;
241 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
242 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
243
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);
250
251 handle = SetClipboardData(CF_METAFILEPICT, data);
252 break;
253 }
254 #endif // wxUSE_METAFILE
255
256 #if wxUSE_ENH_METAFILE && !defined(__WIN16__)
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
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 }
277
278 case wxDF_OEMTEXT:
279 dataFormat = wxDF_TEXT;
280 // fall through
281
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 {
292 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
293
294 memcpy(lpGlobalMemory, s, l);
295
296 GlobalUnlock(hGlobalMemory);
297 }
298
299 handle = SetClipboardData(dataFormat, hGlobalMemory);
300 break;
301 }
302 }
303
304 if ( handle == 0 )
305 {
306 wxLogSysError(_("Failed to set clipboard data."));
307
308 return FALSE;
309 }
310
311 return TRUE;
312 }
313
314 void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
315 {
316 void *retval = NULL;
317
318 switch ( dataFormat )
319 {
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);
361 #if WXWIN_COMPATIBILITY_2
362 wxBM->SetOk(TRUE);
363 #endif // WXWIN_COMPATIBILITY_2
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:
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;
388
389 DWORD hsize = ::GlobalSize(hGlobalMemory);
390 if (len)
391 *len = hsize;
392
393 char *s = new char[hsize];
394 if (!s)
395 break;
396
397 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
398
399 memcpy(s, lpGlobalMemory, hsize);
400
401 ::GlobalUnlock(hGlobalMemory);
402
403 retval = s;
404 break;
405 }
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 }
430 }
431
432 if ( !retval )
433 {
434 wxLogSysError(_("Failed to retrieve data from the clipboard."));
435 }
436
437 return retval;
438 }
439
440 wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
441 {
442 return (wxDataFormat::NativeFormat)::EnumClipboardFormats(dataFormat);
443 }
444
445 int wxRegisterClipboardFormat(wxChar *formatName)
446 {
447 return ::RegisterClipboardFormat(formatName);
448 }
449
450 bool wxGetClipboardFormatName(wxDataFormat dataFormat,
451 wxChar *formatName,
452 int maxCount)
453 {
454 return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
455 }
456
457 // ---------------------------------------------------------------------------
458 // wxClipboard
459 // ---------------------------------------------------------------------------
460
461 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
462
463 wxClipboard::wxClipboard()
464 {
465 m_clearOnExit = FALSE;
466 }
467
468 wxClipboard::~wxClipboard()
469 {
470 if ( m_clearOnExit )
471 {
472 Clear();
473 }
474 }
475
476 void wxClipboard::Clear()
477 {
478 #if wxUSE_OLE_CLIPBOARD
479 if ( FAILED(OleSetClipboard(NULL)) )
480 {
481 wxLogLastError(wxT("OleSetClipboard(NULL)"));
482 }
483 #endif
484 }
485
486 bool wxClipboard::Flush()
487 {
488 #if wxUSE_OLE_CLIPBOARD
489 if ( FAILED(OleFlushClipboard()) )
490 {
491 wxLogLastError(wxT("OleFlushClipboard"));
492
493 return FALSE;
494 }
495 else
496 {
497 m_clearOnExit = FALSE;
498
499 return TRUE;
500 }
501 #else // !wxUSE_OLE_CLIPBOARD
502 return FALSE;
503 #endif // wxUSE_OLE_CLIPBOARD/!wxUSE_OLE_CLIPBOARD
504 }
505
506 bool wxClipboard::Open()
507 {
508 // OLE opens clipboard for us
509 #if wxUSE_OLE_CLIPBOARD
510 return TRUE;
511 #else
512 return wxOpenClipboard();
513 #endif
514 }
515
516 bool wxClipboard::IsOpened() const
517 {
518 #if wxUSE_OLE_CLIPBOARD
519 return TRUE;
520 #else
521 return wxIsClipboardOpened();
522 #endif
523 }
524
525 bool wxClipboard::SetData( wxDataObject *data )
526 {
527 #if !wxUSE_OLE_CLIPBOARD
528 (void)wxEmptyClipboard();
529 #endif // wxUSE_OLE_CLIPBOARD
530
531 if ( data )
532 return AddData(data);
533 else
534 return TRUE;
535 }
536
537 bool wxClipboard::AddData( wxDataObject *data )
538 {
539 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
540
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
567 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
568
569 wxDataFormat format = data->GetFormat();
570
571 switch ( format )
572 {
573 case wxDF_TEXT:
574 case wxDF_OEMTEXT:
575 {
576 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
577 wxString str(textDataObject->GetText());
578 return wxSetClipboardData(format, str.c_str());
579 }
580
581 case wxDF_BITMAP:
582 case wxDF_DIB:
583 {
584 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
585 wxBitmap bitmap(bitmapDataObject->GetBitmap());
586 return wxSetClipboardData(data->GetFormat(), &bitmap);
587 }
588
589 #if wxUSE_METAFILE
590 case wxDF_METAFILE:
591 {
592 wxMetafileDataObject* metaFileDataObject =
593 (wxMetafileDataObject*) data;
594 wxMetafile metaFile = metaFileDataObject->GetMetafile();
595 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
596 metaFileDataObject->GetWidth(),
597 metaFileDataObject->GetHeight());
598 }
599 #endif // wxUSE_METAFILE
600
601 default:
602 return wxSetClipboardData(data);
603 }
604 #else // !wxUSE_DATAOBJ
605 return FALSE;
606 #endif // wxUSE_DATAOBJ/!wxUSE_DATAOBJ
607 }
608
609 void wxClipboard::Close()
610 {
611 // OLE closes clipboard for us
612 #if !wxUSE_OLE_CLIPBOARD
613 wxCloseClipboard();
614 #endif
615 }
616
617 bool wxClipboard::IsSupported( wxDataFormat format )
618 {
619 return wxIsClipboardFormatAvailable(format);
620 }
621
622 bool wxClipboard::GetData( wxDataObject& data )
623 {
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
635 size_t nFormats = data.GetFormatCount(wxDataObject::Set);
636 wxDataFormat format;
637 wxDataFormat *formats;
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
649 data.GetAllFormats(formats, wxDataObject::Set);
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;
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
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
731 case CF_ENHMETAFILE:
732 formatEtc.tymed = TYMED_ENHMF;
733 break;
734
735 default:
736 formatEtc.tymed = TYMED_HGLOBAL;
737 }
738
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
754 hr = data.GetInterface()->SetData(&formatEtc, &medium, TRUE);
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
778 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
779
780 wxDataFormat format = data.GetFormat();
781 switch ( format )
782 {
783 case wxDF_TEXT:
784 case wxDF_OEMTEXT:
785 {
786 wxTextDataObject& textDataObject = (wxTextDataObject &)data;
787 char* s = (char*)wxGetClipboardData(format);
788 if ( !s )
789 return FALSE;
790
791 textDataObject.SetText(s);
792 delete [] s;
793
794 return TRUE;
795 }
796
797 case wxDF_BITMAP:
798 case wxDF_DIB:
799 {
800 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
801 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetFormat());
802 if ( !bitmap )
803 return FALSE;
804
805 bitmapDataObject.SetBitmap(*bitmap);
806 delete bitmap;
807
808 return TRUE;
809 }
810 #if wxUSE_METAFILE
811 case wxDF_METAFILE:
812 {
813 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
814 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
815 if ( !metaFile )
816 return FALSE;
817
818 metaFileDataObject.SetMetafile(*metaFile);
819 delete metaFile;
820
821 return TRUE;
822 }
823 #endif // wxUSE_METAFILE
824 }
825 return FALSE;
826 #else // !wxUSE_DATAOBJ
827 wxFAIL_MSG( wxT("no clipboard implementation") );
828 return FALSE;
829 #endif // wxUSE_OLE_CLIPBOARD/wxUSE_DATAOBJ
830 }
831
832 #else
833 // #error "Please turn wxUSE_CLIPBOARD on to compile this file."
834 #endif // wxUSE_CLIPBOARD
835