]> git.saurik.com Git - wxWidgets.git/blame - src/msw/clipbrd.cpp
Fixed wxFileDialog and VC++ DLL compilation
[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
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
2bda0e17
KB
13#pragma implementation "clipbrd.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/setup.h"
25#endif
26
47d67540 27#if wxUSE_CLIPBOARD
2bda0e17
KB
28
29#ifndef WX_PRECOMP
2432b92d
JS
30#include "wx/object.h"
31#include "wx/event.h"
2bda0e17
KB
32#include "wx/app.h"
33#include "wx/frame.h"
34#include "wx/bitmap.h"
35#include "wx/utils.h"
36#endif
37
06e43511 38#if wxUSE_METAFILE
2bda0e17 39#include "wx/metafile.h"
06e43511
JS
40#endif
41
2bda0e17 42#include "wx/clipbrd.h"
06e43511
JS
43
44#include <windows.h>
45
46HICON myIcon;
47
2bda0e17
KB
48#include "wx/msw/private.h"
49#include "wx/msw/dib.h"
50
06e43511
JS
51// wxDataObject is tied to OLE/drag and drop implementation,
52// therefore so is wxClipboard :-(
53#if wxUSE_DRAG_AND_DROP
54#include "wx/dataobj.h"
2bda0e17
KB
55#endif
56
06e43511
JS
57#include <string.h>
58
2bda0e17
KB
59bool wxClipboardIsOpen = FALSE;
60
61bool wxOpenClipboard(void)
62{
63 if (wxTheApp->GetTopWindow() && !wxClipboardIsOpen)
64 {
65 wxClipboardIsOpen = (::OpenClipboard((HWND) wxTheApp->GetTopWindow()->GetHWND()) != 0);
66 return wxClipboardIsOpen;
67 }
68 else return FALSE;
69}
70
71bool wxCloseClipboard(void)
72{
73 if (wxClipboardIsOpen)
74 {
75 wxClipboardIsOpen = FALSE;
76 }
77 return (::CloseClipboard() != 0);
78}
79
80bool wxEmptyClipboard(void)
81{
82 return (::EmptyClipboard() != 0);
83}
84
85bool wxClipboardOpen(void)
86{
87 return wxClipboardIsOpen;
88}
89
06e43511 90bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
2bda0e17
KB
91{
92 return (::IsClipboardFormatAvailable(dataFormat) != 0);
93}
94
06e43511 95bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int width, int height)
2bda0e17
KB
96{
97 switch (dataFormat)
98 {
b3324be2 99 case wxDF_BITMAP:
2bda0e17
KB
100 {
101 wxBitmap *wxBM = (wxBitmap *)obj;
102
57c208c5
JS
103 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
104 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
c4e7c2aa 105 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, (HBITMAP) wxBM->GetHBITMAP());
2bda0e17
KB
106 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
107 wxBM->GetWidth(), wxBM->GetHeight());
108 if (!hBitmap)
109 {
110 SelectObject(hdcSrc, old);
111 DeleteDC(hdcMem);
112 DeleteDC(hdcSrc);
113 return FALSE;
114 }
c4e7c2aa 115 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
2bda0e17
KB
116 BitBlt(hdcMem, 0, 0, wxBM->GetWidth(), wxBM->GetHeight(),
117 hdcSrc, 0, 0, SRCCOPY);
118
119 // Select new bitmap out of memory DC
120 SelectObject(hdcMem, old1);
121
122 // Set the data
123 bool success = (bool)(::SetClipboardData(CF_BITMAP, hBitmap) != 0);
124
125 // Clean up
126 SelectObject(hdcSrc, old);
127 DeleteDC(hdcSrc);
128 DeleteDC(hdcMem);
129 return success;
130 break;
131 }
b3324be2 132 case wxDF_DIB:
2bda0e17 133 {
47d67540 134#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17 135 HBITMAP hBitmap=(HBITMAP) ((wxBitmap *)obj)->GetHBITMAP();
57c208c5 136 HANDLE hDIB=BitmapToDIB(hBitmap,(HPALETTE) NULL); // NULL==uses system palette
2bda0e17
KB
137 bool success = (::SetClipboardData(CF_DIB,hDIB) != 0);
138#else
139 bool success=FALSE;
140#endif
141 return success;
142 break;
143 }
47d67540 144#if wxUSE_METAFILE
b3324be2 145 case wxDF_METAFILE:
2bda0e17 146 {
06e43511 147 wxMetafile *wxMF = (wxMetafile *)obj;
2bda0e17
KB
148 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
149#ifdef __WINDOWS_386__
150 METAFILEPICT *mf = (METAFILEPICT *)MK_FP32(GlobalLock(data));
151#else
152 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
153#endif
154
155 mf->mm = wxMF->GetWindowsMappingMode();
156 mf->xExt = width;
157 mf->yExt = height;
c4e7c2aa 158 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
2bda0e17
KB
159 GlobalUnlock(data);
160 wxMF->SetHMETAFILE((WXHANDLE) NULL);
161
162 return (SetClipboardData(CF_METAFILEPICT, data) != 0);
163 break;
164 }
165#endif
166 case CF_SYLK:
167 case CF_DIF:
168 case CF_TIFF:
169 case CF_PALETTE:
170 {
171 return FALSE;
172 break;
173 }
b3324be2
JS
174 case wxDF_OEMTEXT:
175 dataFormat = wxDF_TEXT;
176 case wxDF_TEXT:
2bda0e17
KB
177 width = strlen((char *)obj) + 1;
178 height = 1;
179 default:
180 {
181 char *s = (char *)obj;
182 DWORD l;
183
184 l = (width * height);
185 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
186 if (!hGlobalMemory)
187 return FALSE;
188
189#ifdef __WINDOWS_386__
190 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
191#else
192 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
193#endif
194
195#ifdef __WIN32__
196 memcpy(lpGlobalMemory, s, l);
197#elif defined(__WATCOMC__) && defined(__WINDOWS_386__)
198 memcpy(lpGlobalMemory, s, l);
199#else
200 hmemcpy(lpGlobalMemory, s, l);
201#endif
202
203 GlobalUnlock(hGlobalMemory);
204 HANDLE success = SetClipboardData(dataFormat, hGlobalMemory);
205 return (success != 0);
206 break;
207 }
208 }
209 return FALSE;
210}
211
06e43511 212wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
2bda0e17
KB
213{
214 switch (dataFormat)
215 {
b3324be2 216 case wxDF_BITMAP:
2bda0e17
KB
217 {
218 BITMAP bm;
c4e7c2aa 219 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
2bda0e17
KB
220 if (!hBitmap)
221 return NULL;
222
57c208c5
JS
223 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
224 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
2bda0e17 225
c4e7c2aa 226 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
2bda0e17
KB
227 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
228
229 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
230
231 if (!hNewBitmap)
232 {
233 SelectObject(hdcSrc, old);
234 DeleteDC(hdcMem);
235 DeleteDC(hdcSrc);
236 return NULL;
237 }
238
c4e7c2aa 239 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
2bda0e17
KB
240 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
241 hdcSrc, 0, 0, SRCCOPY);
242
243 // Select new bitmap out of memory DC
244 SelectObject(hdcMem, old1);
245
246 // Clean up
247 SelectObject(hdcSrc, old);
248 DeleteDC(hdcSrc);
249 DeleteDC(hdcMem);
250
251 // Create and return a new wxBitmap
252 wxBitmap *wxBM = new wxBitmap;
253 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
254 wxBM->SetWidth(bm.bmWidth);
255 wxBM->SetHeight(bm.bmHeight);
256 wxBM->SetDepth(bm.bmPlanes);
257 wxBM->SetOk(TRUE);
258 return (wxObject *)wxBM;
259 break;
260 }
b3324be2 261 case wxDF_METAFILE:
2bda0e17
KB
262 case CF_SYLK:
263 case CF_DIF:
264 case CF_TIFF:
265 case CF_PALETTE:
b3324be2 266 case wxDF_DIB:
2bda0e17
KB
267 {
268 return FALSE;
269 break;
270 }
b3324be2
JS
271 case wxDF_OEMTEXT:
272 dataFormat = wxDF_TEXT;
273 case wxDF_TEXT:
2bda0e17
KB
274 default:
275 {
276 HANDLE hGlobalMemory = GetClipboardData(dataFormat);
277 if (!hGlobalMemory)
278 return NULL;
279
280 int hsize = (int)GlobalSize(hGlobalMemory);
281 if (len)
282 *len = hsize;
283
284 char *s = new char[hsize];
285 if (!s)
286 return NULL;
287
288#ifdef __WINDOWS_386__
289 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
290#else
291 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
292#endif
293
294#ifdef __WIN32__
295 memcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
296#elif __WATCOMC__ && defined(__WINDOWS_386__)
297 memcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
298#else
299 hmemcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
300#endif
301
302 GlobalUnlock(hGlobalMemory);
303
304 return (wxObject *)s;
305 break;
306 }
307 }
308 return NULL;
309}
310
06e43511 311wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
2bda0e17 312{
06e43511 313 return (wxDataFormat) ::EnumClipboardFormats(dataFormat);
2bda0e17
KB
314}
315
316int wxRegisterClipboardFormat(char *formatName)
317{
318 return ::RegisterClipboardFormat(formatName);
319}
320
06e43511 321bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int maxCount)
2bda0e17 322{
06e43511 323 return (::GetClipboardFormatName((int) dataFormat, formatName, maxCount) > 0);
2bda0e17
KB
324}
325
06e43511
JS
326//-----------------------------------------------------------------------------
327// wxClipboard
328//-----------------------------------------------------------------------------
2bda0e17 329
06e43511 330IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
2bda0e17 331
4ce81a75
JS
332wxClipboard* wxTheClipboard = (wxClipboard*) NULL;
333
2bda0e17
KB
334wxClipboard::wxClipboard()
335{
06e43511 336 m_open = FALSE;
2bda0e17
KB
337}
338
339wxClipboard::~wxClipboard()
340{
06e43511 341 Clear();
2bda0e17
KB
342}
343
06e43511 344void wxClipboard::Clear()
2bda0e17 345{
57c208c5 346#if wxUSE_DRAG_AND_DROP
4ce81a75
JS
347 wxNode* node = m_data.First();
348 while (node)
349 {
350 wxDataObject* data = (wxDataObject*) node->Data();
351 delete data;
352 node = node->Next();
353 }
354 m_data.Clear();
57c208c5 355#endif
2bda0e17
KB
356}
357
06e43511 358bool wxClipboard::Open()
2bda0e17 359{
06e43511 360 wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
2bda0e17 361
06e43511 362 m_open = TRUE;
2bda0e17 363
06e43511 364 return wxOpenClipboard();
2bda0e17
KB
365}
366
06e43511 367bool wxClipboard::SetData( wxDataObject *data )
2bda0e17 368{
06e43511
JS
369#if wxUSE_DRAG_AND_DROP
370 wxCHECK_MSG( data, FALSE, "data is invalid" );
371 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
372
373 switch (data->GetFormat())
374 {
375 case wxDF_TEXT:
376 case wxDF_OEMTEXT:
377 {
378 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
379 wxString str(textDataObject->GetText());
380 return wxSetClipboardData(data->GetFormat(), (wxObject*) (const char*) str);
381 break;
382 }
383 case wxDF_BITMAP:
384 case wxDF_DIB:
385 {
386 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
387 wxBitmap bitmap(bitmapDataObject->GetBitmap());
388 return wxSetClipboardData(data->GetFormat(), & bitmap);
389 break;
390 }
391#if wxUSE_METAFILE
392 case wxDF_METAFILE:
393 {
394 wxMetafileDataObject* metaFileDataObject = (wxMetafileDataObject*) data;
395 wxMetafile metaFile = metaFileDataObject->GetMetafile();
396 return wxSetClipboardData(wxDF_METAFILE, & metaFile, metaFileDataObject->GetWidth(), metaFileDataObject->GetHeight());
397 break;
398 }
399#endif
400 default:
401 {
402 return FALSE;
403 }
404 }
405
406 return FALSE;
407#else
408 return FALSE;
409#endif
2bda0e17
KB
410}
411
06e43511 412void wxClipboard::Close()
2bda0e17 413{
06e43511
JS
414 wxCHECK_RET( m_open, "clipboard not open" );
415
416 m_open = FALSE;
417 wxCloseClipboard();
2bda0e17
KB
418}
419
06e43511 420bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString& WXUNUSED(id) )
2bda0e17 421{
06e43511 422 return wxIsClipboardFormatAvailable(format);
2bda0e17
KB
423}
424
06e43511 425bool wxClipboard::GetData( wxDataObject *data )
2bda0e17 426{
06e43511
JS
427 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
428
429#if wxUSE_DRAG_AND_DROP
430 switch (data->GetFormat())
431 {
432 case wxDF_TEXT:
433 case wxDF_OEMTEXT:
434 {
435 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
436 char* s = (char*) wxGetClipboardData(data->GetFormat());
437 if (s)
438 {
439 textDataObject->SetText(s);
440 delete[] s;
441 return TRUE;
442 }
443 else
444 return FALSE;
445 break;
446 }
447 case wxDF_BITMAP:
448 case wxDF_DIB:
449 {
450 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
451 wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetFormat());
452 if (bitmap)
453 {
454 bitmapDataObject->SetBitmap(* bitmap);
455 delete bitmap;
456 return TRUE;
457 }
458 else
459 return FALSE;
460 break;
461 }
462#if wxUSE_METAFILE
463 case wxDF_METAFILE:
464 {
465 wxMetafileDataObject* metaFileDataObject = (wxMetafileDataObject*) data;
466 wxMetafile* metaFile = (wxMetafile*) wxGetClipboardData(wxDF_METAFILE);
467 if (metaFile)
468 {
469 metaFileDataObject->SetMetafile(* metaFile);
470 delete metaFile;
471 return TRUE;
472 }
473 else
474 return FALSE;
475
476 break;
477 }
478#endif
479 default:
480 {
481 return FALSE;
482 }
483 }
484 return FALSE;
485#else
486 return FALSE;
487#endif
2bda0e17
KB
488}
489
4ce81a75
JS
490//-----------------------------------------------------------------------------
491// wxClipboardModule
492//-----------------------------------------------------------------------------
493
494IMPLEMENT_DYNAMIC_CLASS(wxClipboardModule,wxModule)
495
496bool wxClipboardModule::OnInit()
497{
498 wxTheClipboard = new wxClipboard();
499
500 return TRUE;
501}
502
503void wxClipboardModule::OnExit()
504{
505 if (wxTheClipboard) delete wxTheClipboard;
506 wxTheClipboard = (wxClipboard*) NULL;
507}
508
47d67540 509#endif // wxUSE_CLIPBOARD
4ce81a75 510