]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
21 #pragma implementation "clipbrd.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
38 #include "wx/object.h"
42 #include "wx/bitmap.h"
47 #include "wx/metafile.h"
51 #include "wx/clipbrd.h"
56 #include "wx/msw/private.h"
57 #include "wx/msw/dib.h"
59 // wxDataObject is tied to OLE/drag and drop implementation,
60 // therefore so is wxClipboard :-(
61 #if wxUSE_DRAG_AND_DROP
62 #include "wx/dataobj.h"
64 static bool wxSetClipboardData(wxDataObject
*data
);
68 #define memcpy hmemcpy
71 // ===========================================================================
73 // ===========================================================================
75 // ---------------------------------------------------------------------------
76 // old-style clipboard functions using Windows API
77 // ---------------------------------------------------------------------------
79 static bool gs_wxClipboardIsOpen
= FALSE
;
81 bool wxOpenClipboard()
83 wxCHECK_MSG( !gs_wxClipboardIsOpen
, TRUE
, "clipboard already opened." );
85 wxWindow
*win
= wxTheApp
->GetTopWindow();
88 gs_wxClipboardIsOpen
= ::OpenClipboard((HWND
)win
->GetHWND()) != 0;
90 if ( !gs_wxClipboardIsOpen
)
91 wxLogSysError(_("Failed to open the clipboard."));
93 return gs_wxClipboardIsOpen
;
97 wxLogDebug("Can not open clipboard without a main window,");
103 bool wxCloseClipboard()
105 wxCHECK_MSG( gs_wxClipboardIsOpen
, FALSE
, "clipboard is not opened" );
107 gs_wxClipboardIsOpen
= FALSE
;
109 if ( ::CloseClipboard() == 0 )
111 wxLogSysError(_("Failed to close the clipboard."));
119 bool wxEmptyClipboard()
121 if ( ::EmptyClipboard() == 0 )
123 wxLogSysError(_("Failed to empty the clipboard."));
131 bool wxIsClipboardOpened()
133 return gs_wxClipboardIsOpen
;
136 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat
)
138 return ::IsClipboardFormatAvailable(dataFormat
) != 0;
141 #if wxUSE_DRAG_AND_DROP
142 static bool wxSetClipboardData(wxDataObject
*data
)
144 size_t size
= data
->GetDataSize();
145 HANDLE hGlobal
= ::GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
, size
);
148 wxLogSysError(_("Failed to allocate %dKb of memory for clipboard "
149 "transfer."), size
/ 1024);
154 LPVOID lpGlobalMemory
= ::GlobalLock(hGlobal
);
156 data
->GetDataHere(lpGlobalMemory
);
158 GlobalUnlock(hGlobal
);
160 wxDataFormat format
= data
->GetPreferredFormat();
161 if ( !::SetClipboardData(format
, hGlobal
) )
163 wxLogSysError(_("Failed to set clipboard data in format %s"),
164 wxDataObject::GetFormatName(format
));
171 #endif // wxUSE_DRAG_AND_DROP
173 bool wxSetClipboardData(wxDataFormat dataFormat
,
175 int width
, int height
)
177 HANDLE handle
= 0; // return value of SetClipboardData
183 wxBitmap
*bitmap
= (wxBitmap
*)data
;
185 HDC hdcMem
= CreateCompatibleDC((HDC
) NULL
);
186 HDC hdcSrc
= CreateCompatibleDC((HDC
) NULL
);
187 HBITMAP old
= (HBITMAP
)
188 ::SelectObject(hdcSrc
, (HBITMAP
)bitmap
->GetHBITMAP());
189 HBITMAP hBitmap
= CreateCompatibleBitmap(hdcSrc
,
191 bitmap
->GetHeight());
194 SelectObject(hdcSrc
, old
);
200 HBITMAP old1
= (HBITMAP
) SelectObject(hdcMem
, hBitmap
);
201 BitBlt(hdcMem
, 0, 0, bitmap
->GetWidth(), bitmap
->GetHeight(),
202 hdcSrc
, 0, 0, SRCCOPY
);
204 // Select new bitmap out of memory DC
205 SelectObject(hdcMem
, old1
);
208 handle
= ::SetClipboardData(CF_BITMAP
, hBitmap
);
211 SelectObject(hdcSrc
, old
);
219 #if wxUSE_IMAGE_LOADING_IN_MSW
220 wxBitmap
*bitmap
= (wxBitmap
*)data
;
221 HBITMAP hBitmap
= (HBITMAP
)bitmap
->GetHBITMAP();
222 // NULL palette means to use the system one
223 HANDLE hDIB
= BitmapToDIB(hBitmap
, (HPALETTE
)NULL
);
224 handle
= SetClipboardData(CF_DIB
, hDIB
);
232 wxMetafile
*wxMF
= (wxMetafile
*)data
;
233 HANDLE data
= GlobalAlloc(GHND
, sizeof(METAFILEPICT
) + 1);
234 METAFILEPICT
*mf
= (METAFILEPICT
*)GlobalLock(data
);
236 mf
->mm
= wxMF
->GetWindowsMappingMode();
239 mf
->hMF
= (HMETAFILE
) wxMF
->GetHMETAFILE();
241 wxMF
->SetHMETAFILE((WXHANDLE
) NULL
);
243 handle
= SetClipboardData(CF_METAFILEPICT
, data
);
253 wxLogError(_("Unsupported clipboard format."));
258 dataFormat
= wxDF_TEXT
;
263 char *s
= (char *)data
;
265 width
= strlen(s
) + 1;
267 DWORD l
= (width
* height
);
268 HANDLE hGlobalMemory
= GlobalAlloc(GHND
, l
);
271 LPSTR lpGlobalMemory
= (LPSTR
)GlobalLock(hGlobalMemory
);
273 memcpy(lpGlobalMemory
, s
, l
);
275 GlobalUnlock(hGlobalMemory
);
278 handle
= SetClipboardData(dataFormat
, hGlobalMemory
);
285 wxLogSysError(_("Failed to set clipboard data."));
293 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
)
297 switch ( dataFormat
)
302 HBITMAP hBitmap
= (HBITMAP
) GetClipboardData(CF_BITMAP
);
306 HDC hdcMem
= CreateCompatibleDC((HDC
) NULL
);
307 HDC hdcSrc
= CreateCompatibleDC((HDC
) NULL
);
309 HBITMAP old
= (HBITMAP
) ::SelectObject(hdcSrc
, hBitmap
);
310 GetObject(hBitmap
, sizeof(BITMAP
), (LPSTR
)&bm
);
312 HBITMAP hNewBitmap
= CreateBitmapIndirect(&bm
);
316 SelectObject(hdcSrc
, old
);
322 HBITMAP old1
= (HBITMAP
) SelectObject(hdcMem
, hNewBitmap
);
323 BitBlt(hdcMem
, 0, 0, bm
.bmWidth
, bm
.bmHeight
,
324 hdcSrc
, 0, 0, SRCCOPY
);
326 // Select new bitmap out of memory DC
327 SelectObject(hdcMem
, old1
);
330 SelectObject(hdcSrc
, old
);
334 // Create and return a new wxBitmap
335 wxBitmap
*wxBM
= new wxBitmap
;
336 wxBM
->SetHBITMAP((WXHBITMAP
) hNewBitmap
);
337 wxBM
->SetWidth(bm
.bmWidth
);
338 wxBM
->SetHeight(bm
.bmHeight
);
339 wxBM
->SetDepth(bm
.bmPlanes
);
352 wxLogError(_("Unsupported clipboard format."));
357 dataFormat
= wxDF_TEXT
;
362 HANDLE hGlobalMemory
= ::GetClipboardData(dataFormat
);
366 DWORD hsize
= ::GlobalSize(hGlobalMemory
);
370 char *s
= new char[hsize
];
374 LPSTR lpGlobalMemory
= (LPSTR
)::GlobalLock(hGlobalMemory
);
376 memcpy(s
, lpGlobalMemory
, hsize
);
378 ::GlobalUnlock(hGlobalMemory
);
386 HANDLE hGlobalMemory
= ::GetClipboardData(dataFormat
);
387 if ( !hGlobalMemory
)
390 DWORD size
= ::GlobalSize(hGlobalMemory
);
394 void *buf
= malloc(size
);
398 LPSTR lpGlobalMemory
= (LPSTR
)::GlobalLock(hGlobalMemory
);
400 memcpy(buf
, lpGlobalMemory
, size
);
402 ::GlobalUnlock(hGlobalMemory
);
411 wxLogSysError(_("Failed to retrieve data from the clipboard."));
417 wxDataFormat
wxEnumClipboardFormats(wxDataFormat dataFormat
)
419 return ::EnumClipboardFormats(dataFormat
);
422 int wxRegisterClipboardFormat(char *formatName
)
424 return ::RegisterClipboardFormat(formatName
);
427 bool wxGetClipboardFormatName(wxDataFormat dataFormat
,
431 return ::GetClipboardFormatName((int)dataFormat
, formatName
, maxCount
) > 0;
434 // ---------------------------------------------------------------------------
436 // ---------------------------------------------------------------------------
438 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
440 wxClipboard
* wxTheClipboard
= (wxClipboard
*)NULL
;
442 wxClipboard::wxClipboard()
446 wxClipboard::~wxClipboard()
451 void wxClipboard::Clear()
455 bool wxClipboard::Open()
457 return wxOpenClipboard();
460 bool wxClipboard::SetData( wxDataObject
*data
)
462 (void)wxEmptyClipboard();
465 return AddData(data
);
470 bool wxClipboard::AddData( wxDataObject
*data
)
472 wxCHECK_MSG( data
, FALSE
, "data is invalid" );
474 #if wxUSE_DRAG_AND_DROP
475 wxCHECK_MSG( wxIsClipboardOpened(), FALSE
, "clipboard not open" );
477 wxDataFormat format
= data
->GetFormat();
484 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
485 wxString
str(textDataObject
->GetText());
486 return wxSetClipboardData(format
, str
.c_str());
492 wxBitmapDataObject
* bitmapDataObject
= (wxBitmapDataObject
*) data
;
493 wxBitmap
bitmap(bitmapDataObject
->GetBitmap());
494 return wxSetClipboardData(data
->GetFormat(), &bitmap
);
500 wxMetafileDataObject
* metaFileDataObject
=
501 (wxMetafileDataObject
*) data
;
502 wxMetafile metaFile
= metaFileDataObject
->GetMetafile();
503 return wxSetClipboardData(wxDF_METAFILE
, &metaFile
,
504 metaFileDataObject
->GetWidth(),
505 metaFileDataObject
->GetHeight());
507 #endif // wxUSE_METAFILE
510 return wxSetClipboardData(data
);
512 #else // !wxUSE_DRAG_AND_DROP
514 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
517 void wxClipboard::Close()
522 bool wxClipboard::IsSupported( wxDataFormat format
)
524 return wxIsClipboardFormatAvailable(format
);
527 bool wxClipboard::GetData( wxDataObject
*data
)
529 wxCHECK_MSG( wxIsClipboardOpened(), FALSE
, "clipboard not open" );
531 #if wxUSE_DRAG_AND_DROP
532 wxDataFormat format
= data
->GetFormat();
538 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
539 char* s
= (char*) wxGetClipboardData(format
);
542 textDataObject
->SetText(s
);
553 wxBitmapDataObject
* bitmapDataObject
= (wxBitmapDataObject
*)data
;
554 wxBitmap
* bitmap
= (wxBitmap
*)wxGetClipboardData(data
->GetFormat());
557 bitmapDataObject
->SetBitmap(* bitmap
);
567 wxMetafileDataObject
* metaFileDataObject
= (wxMetafileDataObject
*)data
;
568 wxMetafile
* metaFile
= (wxMetafile
*)wxGetClipboardData(wxDF_METAFILE
);
571 metaFileDataObject
->SetMetafile(*metaFile
);
582 void *buf
= wxGetClipboardData(format
, &len
);
585 // FIXME this is for testing only!!
586 ((wxPrivateDataObject
*)data
)->SetData(buf
, len
);
600 //-----------------------------------------------------------------------------
602 //-----------------------------------------------------------------------------
604 IMPLEMENT_DYNAMIC_CLASS(wxClipboardModule
,wxModule
)
606 bool wxClipboardModule::OnInit()
608 wxTheClipboard
= new wxClipboard();
613 void wxClipboardModule::OnExit()
615 if (wxTheClipboard
) delete wxTheClipboard
;
616 wxTheClipboard
= (wxClipboard
*) NULL
;
620 #error "Please turn wxUSE_CLIPBOARD on to compile this file."
621 #endif // wxUSE_CLIPBOARD