]> git.saurik.com Git - wxWidgets.git/blame - src/msw/clipbrd.cpp
unneeded line removed
[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"
2bda0e17
KB
44#endif
45
06e43511 46#if wxUSE_METAFILE
26f86486 47 #include "wx/metafile.h"
06e43511
JS
48#endif
49
2bda0e17 50#include "wx/clipbrd.h"
06e43511
JS
51
52#include <windows.h>
53
2bda0e17
KB
54#include "wx/msw/private.h"
55#include "wx/msw/dib.h"
56
06e43511
JS
57// wxDataObject is tied to OLE/drag and drop implementation,
58// therefore so is wxClipboard :-(
59#if wxUSE_DRAG_AND_DROP
26f86486 60 #include "wx/dataobj.h"
2bda0e17
KB
61#endif
62
06e43511
JS
63#include <string.h>
64
26f86486
VZ
65// ===========================================================================
66// implementation
67// ===========================================================================
68
69// ---------------------------------------------------------------------------
70// old-style clipboard functions using Windows API
71// ---------------------------------------------------------------------------
2bda0e17 72
26f86486
VZ
73static bool gs_wxClipboardIsOpen = FALSE;
74
75bool wxOpenClipboard()
2bda0e17 76{
26f86486
VZ
77 wxCHECK_MSG( !gs_wxClipboardIsOpen, TRUE, "clipboard already opened." );
78
79 wxWindow *win = wxTheApp->GetTopWindow();
80 if ( win )
81 {
82 gs_wxClipboardIsOpen = ::OpenClipboard((HWND)win->GetHWND()) != 0;
83
84 if ( !gs_wxClipboardIsOpen )
85 wxLogSysError(_("Failed to open the clipboard."));
86
87 return gs_wxClipboardIsOpen;
88 }
89 else
90 {
91 wxLogDebug("Can not open clipboard without a main window,");
92
93 return FALSE;
94 }
2bda0e17
KB
95}
96
26f86486 97bool wxCloseClipboard()
2bda0e17 98{
26f86486
VZ
99 wxCHECK_MSG( gs_wxClipboardIsOpen, FALSE, "clipboard is not opened" );
100
101 gs_wxClipboardIsOpen = FALSE;
102
103 if ( ::CloseClipboard() == 0 )
104 {
105 wxLogSysError(_("Failed to close the clipboard."));
106
107 return FALSE;
108 }
109
110 return TRUE;
2bda0e17
KB
111}
112
26f86486 113bool wxEmptyClipboard()
2bda0e17 114{
26f86486
VZ
115 if ( ::EmptyClipboard() == 0 )
116 {
117 wxLogSysError(_("Failed to empty the clipboard."));
118
119 return FALSE;
120 }
121
122 return TRUE;
2bda0e17
KB
123}
124
26f86486 125bool wxIsClipboardOpened()
2bda0e17 126{
26f86486 127 return gs_wxClipboardIsOpen;
2bda0e17
KB
128}
129
06e43511 130bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
2bda0e17 131{
26f86486 132 return ::IsClipboardFormatAvailable(dataFormat) != 0;
2bda0e17
KB
133}
134
26f86486
VZ
135bool wxSetClipboardData(wxDataFormat dataFormat,
136 const void *data,
137 int width, int height)
2bda0e17 138{
26f86486
VZ
139 HANDLE handle = 0; // return value of SetClipboardData
140
141 switch (dataFormat)
2bda0e17 142 {
26f86486
VZ
143 case wxDF_BITMAP:
144 {
145 wxBitmap *bitmap = (wxBitmap *)data;
146
147 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
148 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
149 HBITMAP old = (HBITMAP)
150 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
151 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
152 bitmap->GetWidth(),
153 bitmap->GetHeight());
154 if (!hBitmap)
155 {
156 SelectObject(hdcSrc, old);
157 DeleteDC(hdcMem);
158 DeleteDC(hdcSrc);
159 return FALSE;
160 }
161
162 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
163 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
164 hdcSrc, 0, 0, SRCCOPY);
165
166 // Select new bitmap out of memory DC
167 SelectObject(hdcMem, old1);
168
169 // Set the data
170 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
171
172 // Clean up
173 SelectObject(hdcSrc, old);
174 DeleteDC(hdcSrc);
175 DeleteDC(hdcMem);
176 break;
177 }
178
179 case wxDF_DIB:
180 {
47d67540 181#if wxUSE_IMAGE_LOADING_IN_MSW
26f86486
VZ
182 wxBitmap *bitmap = (wxBitmap *)data;
183 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
184 // NULL palette means to use the system one
185 HANDLE hDIB = BitmapToDIB(hBitmap, (HPALETTE)NULL);
186 handle = SetClipboardData(CF_DIB, hDIB);
2bda0e17 187#endif
26f86486
VZ
188 break;
189 }
190
47d67540 191#if wxUSE_METAFILE
26f86486
VZ
192 case wxDF_METAFILE:
193 {
194 wxMetafile *wxMF = (wxMetafile *)data;
195 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
2bda0e17 196#ifdef __WINDOWS_386__
26f86486 197 METAFILEPICT *mf = (METAFILEPICT *)MK_FP32(GlobalLock(data));
2bda0e17 198#else
26f86486 199 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
2bda0e17
KB
200#endif
201
26f86486
VZ
202 mf->mm = wxMF->GetWindowsMappingMode();
203 mf->xExt = width;
204 mf->yExt = height;
205 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
206 GlobalUnlock(data);
207 wxMF->SetHMETAFILE((WXHANDLE) NULL);
2bda0e17 208
26f86486
VZ
209 handle = SetClipboardData(CF_METAFILEPICT, data);
210 break;
211 }
2bda0e17 212#endif
26f86486
VZ
213 case CF_SYLK:
214 case CF_DIF:
215 case CF_TIFF:
216 case CF_PALETTE:
217 default:
218 {
219 wxLogError(_("Unsupported clipboard format."));
220 return FALSE;
221 }
2bda0e17 222
26f86486
VZ
223 case wxDF_OEMTEXT:
224 dataFormat = wxDF_TEXT;
225 // fall through
2bda0e17 226
26f86486
VZ
227 case wxDF_TEXT:
228 {
229 char *s = (char *)data;
230
231 width = strlen(s) + 1;
232 height = 1;
233 DWORD l = (width * height);
234 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
235 if ( hGlobalMemory )
236 {
2bda0e17 237#ifdef __WINDOWS_386__
26f86486 238 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
2bda0e17 239#else
26f86486 240 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
2bda0e17
KB
241#endif
242
243#ifdef __WIN32__
26f86486 244 memcpy(lpGlobalMemory, s, l);
2bda0e17 245#elif defined(__WATCOMC__) && defined(__WINDOWS_386__)
26f86486 246 memcpy(lpGlobalMemory, s, l);
2bda0e17 247#else
26f86486 248 hmemcpy(lpGlobalMemory, s, l);
2bda0e17
KB
249#endif
250
26f86486
VZ
251 GlobalUnlock(hGlobalMemory);
252 }
2bda0e17 253
26f86486
VZ
254 handle = SetClipboardData(dataFormat, hGlobalMemory);
255 break;
256 }
2bda0e17 257 }
26f86486
VZ
258
259 if ( handle == 0 )
2bda0e17 260 {
26f86486
VZ
261 wxLogSysError(_("Failed to set clipboard data."));
262
263 return FALSE;
2bda0e17 264 }
26f86486
VZ
265
266 return TRUE;
267}
268
269void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
270{
271 void *retval = NULL;
272
273 switch ( dataFormat )
2bda0e17 274 {
26f86486
VZ
275 case wxDF_BITMAP:
276 {
277 BITMAP bm;
278 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
279 if (!hBitmap)
280 break;
281
282 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
283 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
284
285 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
286 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
287
288 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
289
290 if (!hNewBitmap)
291 {
292 SelectObject(hdcSrc, old);
293 DeleteDC(hdcMem);
294 DeleteDC(hdcSrc);
295 break;
296 }
297
298 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
299 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
300 hdcSrc, 0, 0, SRCCOPY);
301
302 // Select new bitmap out of memory DC
303 SelectObject(hdcMem, old1);
304
305 // Clean up
306 SelectObject(hdcSrc, old);
307 DeleteDC(hdcSrc);
308 DeleteDC(hdcMem);
309
310 // Create and return a new wxBitmap
311 wxBitmap *wxBM = new wxBitmap;
312 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
313 wxBM->SetWidth(bm.bmWidth);
314 wxBM->SetHeight(bm.bmHeight);
315 wxBM->SetDepth(bm.bmPlanes);
316 wxBM->SetOk(TRUE);
317 retval = wxBM;
318 break;
319 }
320
321 case wxDF_METAFILE:
322 case CF_SYLK:
323 case CF_DIF:
324 case CF_TIFF:
325 case CF_PALETTE:
326 case wxDF_DIB:
327 default:
328 {
329 wxLogError(_("Unsupported clipboard format."));
330 return FALSE;
331 }
332
333 case wxDF_OEMTEXT:
334 dataFormat = wxDF_TEXT;
335 // fall through
336
337 case wxDF_TEXT:
338 {
339 HANDLE hGlobalMemory = ::GetClipboardData(dataFormat);
340 if (!hGlobalMemory)
341 break;
2bda0e17 342
26f86486
VZ
343 DWORD hsize = ::GlobalSize(hGlobalMemory);
344 if (len)
345 *len = hsize;
2bda0e17 346
26f86486
VZ
347 char *s = new char[hsize];
348 if (!s)
349 break;
2bda0e17
KB
350
351#ifdef __WINDOWS_386__
26f86486 352 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
2bda0e17 353#else
26f86486 354 LPSTR lpGlobalMemory = (LPSTR)::GlobalLock(hGlobalMemory);
2bda0e17
KB
355#endif
356
357#ifdef __WIN32__
26f86486 358 memcpy(s, lpGlobalMemory, hsize);
2bda0e17 359#elif __WATCOMC__ && defined(__WINDOWS_386__)
26f86486 360 memcpy(s, lpGlobalMemory, hsize);
2bda0e17 361#else
26f86486 362 hmemcpy(s, lpGlobalMemory, hsize);
2bda0e17
KB
363#endif
364
26f86486
VZ
365 ::GlobalUnlock(hGlobalMemory);
366
367 retval = s;
368 break;
369 }
370 }
2bda0e17 371
26f86486
VZ
372 if ( !retval )
373 {
374 wxLogSysError(_("Failed to retrieve data from the clipboard."));
2bda0e17 375 }
26f86486
VZ
376
377 return retval;
2bda0e17
KB
378}
379
06e43511 380wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
2bda0e17 381{
26f86486 382 return (wxDataFormat)::EnumClipboardFormats(dataFormat);
2bda0e17
KB
383}
384
26f86486 385int wxRegisterClipboardFormat(char *formatName)
2bda0e17
KB
386{
387 return ::RegisterClipboardFormat(formatName);
388}
389
26f86486
VZ
390bool wxGetClipboardFormatName(wxDataFormat dataFormat,
391 char *formatName,
392 int maxCount)
2bda0e17 393{
26f86486 394 return ::GetClipboardFormatName((int)dataFormat, formatName, maxCount) > 0;
2bda0e17
KB
395}
396
26f86486 397// ---------------------------------------------------------------------------
06e43511 398// wxClipboard
26f86486 399// ---------------------------------------------------------------------------
2bda0e17 400
26f86486 401IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
2bda0e17 402
26f86486 403wxClipboard* wxTheClipboard = (wxClipboard *)NULL;
4ce81a75 404
2bda0e17
KB
405wxClipboard::wxClipboard()
406{
2bda0e17
KB
407}
408
409wxClipboard::~wxClipboard()
410{
26f86486 411 Clear();
2bda0e17
KB
412}
413
06e43511 414void wxClipboard::Clear()
2bda0e17 415{
2bda0e17
KB
416}
417
06e43511 418bool wxClipboard::Open()
2bda0e17 419{
06e43511 420 return wxOpenClipboard();
2bda0e17
KB
421}
422
06e43511 423bool wxClipboard::SetData( wxDataObject *data )
2bda0e17 424{
26f86486
VZ
425 (void)wxEmptyClipboard();
426
427 if ( data )
428 return AddData(data);
429 else
430 return TRUE;
431}
432
433bool wxClipboard::AddData( wxDataObject *data )
434{
06e43511 435 wxCHECK_MSG( data, FALSE, "data is invalid" );
06e43511 436
26f86486
VZ
437#if wxUSE_DRAG_AND_DROP
438 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, "clipboard not open" );
439
440 wxDataFormat format = data->GetFormat();
441
442 switch ( format )
06e43511
JS
443 {
444 case wxDF_TEXT:
445 case wxDF_OEMTEXT:
446 {
447 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
448 wxString str(textDataObject->GetText());
26f86486 449 return wxSetClipboardData(format, str.c_str());
06e43511 450 }
26f86486 451
06e43511
JS
452 case wxDF_BITMAP:
453 case wxDF_DIB:
454 {
455 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
456 wxBitmap bitmap(bitmapDataObject->GetBitmap());
26f86486 457 return wxSetClipboardData(data->GetFormat(), &bitmap);
06e43511 458 }
26f86486 459
06e43511
JS
460#if wxUSE_METAFILE
461 case wxDF_METAFILE:
462 {
26f86486
VZ
463 wxMetafileDataObject* metaFileDataObject =
464 (wxMetafileDataObject*) data;
06e43511 465 wxMetafile metaFile = metaFileDataObject->GetMetafile();
26f86486
VZ
466 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
467 metaFileDataObject->GetWidth(),
468 metaFileDataObject->GetHeight());
06e43511 469 }
26f86486
VZ
470#endif // wxUSE_METAFILE
471
06e43511 472 default:
26f86486
VZ
473 wxLogError(_("Can not put data in format '%s' on clipboard."),
474 wxDataObject::GetFormatName(format));
475
06e43511 476 return FALSE;
06e43511 477 }
26f86486 478
06e43511
JS
479 return FALSE;
480#else
481 return FALSE;
482#endif
2bda0e17
KB
483}
484
06e43511 485void wxClipboard::Close()
2bda0e17 486{
06e43511 487 wxCloseClipboard();
2bda0e17
KB
488}
489
26f86486 490bool wxClipboard::IsSupported( wxDataFormat format )
2bda0e17 491{
06e43511 492 return wxIsClipboardFormatAvailable(format);
2bda0e17
KB
493}
494
06e43511 495bool wxClipboard::GetData( wxDataObject *data )
2bda0e17 496{
26f86486
VZ
497 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, "clipboard not open" );
498
06e43511 499#if wxUSE_DRAG_AND_DROP
26f86486
VZ
500 wxDataFormat format = data->GetFormat();
501 switch ( format )
06e43511
JS
502 {
503 case wxDF_TEXT:
504 case wxDF_OEMTEXT:
505 {
506 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
26f86486
VZ
507 char* s = (char*) wxGetClipboardData(format);
508 if ( s )
06e43511
JS
509 {
510 textDataObject->SetText(s);
511 delete[] s;
512 return TRUE;
513 }
514 else
515 return FALSE;
06e43511 516 }
26f86486 517
06e43511
JS
518 case wxDF_BITMAP:
519 case wxDF_DIB:
520 {
26f86486
VZ
521 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject *)data;
522 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data->GetFormat());
06e43511
JS
523 if (bitmap)
524 {
525 bitmapDataObject->SetBitmap(* bitmap);
526 delete bitmap;
527 return TRUE;
528 }
529 else
530 return FALSE;
06e43511
JS
531 }
532#if wxUSE_METAFILE
533 case wxDF_METAFILE:
534 {
26f86486
VZ
535 wxMetafileDataObject* metaFileDataObject = (wxMetafileDataObject *)data;
536 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
06e43511
JS
537 if (metaFile)
538 {
26f86486 539 metaFileDataObject->SetMetafile(*metaFile);
06e43511
JS
540 delete metaFile;
541 return TRUE;
542 }
543 else
544 return FALSE;
06e43511
JS
545 }
546#endif
547 default:
26f86486
VZ
548 wxLogError(_("Can not get data in format '%s' from clipboard."),
549 wxDataObject::GetFormatName(format));
550
06e43511 551 return FALSE;
06e43511 552 }
06e43511
JS
553#else
554 return FALSE;
555#endif
2bda0e17
KB
556}
557
4ce81a75
JS
558//-----------------------------------------------------------------------------
559// wxClipboardModule
560//-----------------------------------------------------------------------------
561
562IMPLEMENT_DYNAMIC_CLASS(wxClipboardModule,wxModule)
563
564bool wxClipboardModule::OnInit()
565{
566 wxTheClipboard = new wxClipboard();
26f86486 567
4ce81a75
JS
568 return TRUE;
569}
570
571void wxClipboardModule::OnExit()
572{
573 if (wxTheClipboard) delete wxTheClipboard;
574 wxTheClipboard = (wxClipboard*) NULL;
575}
576
26f86486
VZ
577#else
578 #error "Please turn wxUSE_CLIPBOARD on to compile this file."
47d67540 579#endif // wxUSE_CLIPBOARD
4ce81a75 580