Added OnKeyDown, OnKeyUp.
[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 #ifdef __GNUG__
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
27 #if wxUSE_CLIPBOARD
28
29 #ifndef WX_PRECOMP
30 #include "wx/object.h"
31 #include "wx/event.h"
32 #include "wx/app.h"
33 #include "wx/frame.h"
34 #include "wx/bitmap.h"
35 #include "wx/utils.h"
36 #endif
37
38 #if wxUSE_METAFILE
39 #include "wx/metafile.h"
40 #endif
41
42 #include "wx/clipbrd.h"
43
44 #include <windows.h>
45
46 HICON myIcon;
47
48 #include "wx/msw/private.h"
49 #include "wx/msw/dib.h"
50
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"
55 #endif
56
57 #include <string.h>
58
59 bool wxClipboardIsOpen = FALSE;
60
61 bool 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
71 bool wxCloseClipboard(void)
72 {
73 if (wxClipboardIsOpen)
74 {
75 wxClipboardIsOpen = FALSE;
76 }
77 return (::CloseClipboard() != 0);
78 }
79
80 bool wxEmptyClipboard(void)
81 {
82 return (::EmptyClipboard() != 0);
83 }
84
85 bool wxClipboardOpen(void)
86 {
87 return wxClipboardIsOpen;
88 }
89
90 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
91 {
92 return (::IsClipboardFormatAvailable(dataFormat) != 0);
93 }
94
95 bool wxSetClipboardData(wxDataFormat dataFormat, wxObject *obj, int width, int height)
96 {
97 switch (dataFormat)
98 {
99 case wxDF_BITMAP:
100 {
101 wxBitmap *wxBM = (wxBitmap *)obj;
102
103 HDC hdcMem = CreateCompatibleDC(NULL);
104 HDC hdcSrc = CreateCompatibleDC(NULL);
105 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, (HBITMAP) wxBM->GetHBITMAP());
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 }
115 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
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 }
132 case wxDF_DIB:
133 {
134 #if wxUSE_IMAGE_LOADING_IN_MSW
135 HBITMAP hBitmap=(HBITMAP) ((wxBitmap *)obj)->GetHBITMAP();
136 HANDLE hDIB=BitmapToDIB(hBitmap,NULL); // NULL==uses system palette
137 bool success = (::SetClipboardData(CF_DIB,hDIB) != 0);
138 #else
139 bool success=FALSE;
140 #endif
141 return success;
142 break;
143 }
144 #if wxUSE_METAFILE
145 case wxDF_METAFILE:
146 {
147 wxMetafile *wxMF = (wxMetafile *)obj;
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;
158 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
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 }
174 case wxDF_OEMTEXT:
175 dataFormat = wxDF_TEXT;
176 case wxDF_TEXT:
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
212 wxObject *wxGetClipboardData(wxDataFormat dataFormat, long *len)
213 {
214 switch (dataFormat)
215 {
216 case wxDF_BITMAP:
217 {
218 BITMAP bm;
219 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
220 if (!hBitmap)
221 return NULL;
222
223 HDC hdcMem = CreateCompatibleDC(NULL);
224 HDC hdcSrc = CreateCompatibleDC(NULL);
225
226 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
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
239 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
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 }
261 case wxDF_METAFILE:
262 case CF_SYLK:
263 case CF_DIF:
264 case CF_TIFF:
265 case CF_PALETTE:
266 case wxDF_DIB:
267 {
268 return FALSE;
269 break;
270 }
271 case wxDF_OEMTEXT:
272 dataFormat = wxDF_TEXT;
273 case wxDF_TEXT:
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
311 wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
312 {
313 return (wxDataFormat) ::EnumClipboardFormats(dataFormat);
314 }
315
316 int wxRegisterClipboardFormat(char *formatName)
317 {
318 return ::RegisterClipboardFormat(formatName);
319 }
320
321 bool wxGetClipboardFormatName(wxDataFormat dataFormat, char *formatName, int maxCount)
322 {
323 return (::GetClipboardFormatName((int) dataFormat, formatName, maxCount) > 0);
324 }
325
326 /*
327 * wxClipboard
328 */
329
330 //-----------------------------------------------------------------------------
331 // wxClipboard
332 //-----------------------------------------------------------------------------
333
334 IMPLEMENT_DYNAMIC_CLASS(wxClipboard,wxObject)
335
336 wxClipboard* wxTheClipboard = (wxClipboard*) NULL;
337
338 wxClipboard::wxClipboard()
339 {
340 m_open = FALSE;
341 }
342
343 wxClipboard::~wxClipboard()
344 {
345 Clear();
346 }
347
348 void wxClipboard::Clear()
349 {
350 wxNode* node = m_data.First();
351 while (node)
352 {
353 wxDataObject* data = (wxDataObject*) node->Data();
354 delete data;
355 node = node->Next();
356 }
357 m_data.Clear();
358 }
359
360 bool wxClipboard::Open()
361 {
362 wxCHECK_MSG( !m_open, FALSE, "clipboard already open" );
363
364 m_open = TRUE;
365
366 return wxOpenClipboard();
367 }
368
369 bool wxClipboard::SetData( wxDataObject *data )
370 {
371 #if wxUSE_DRAG_AND_DROP
372 wxCHECK_MSG( data, FALSE, "data is invalid" );
373 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
374
375 switch (data->GetFormat())
376 {
377 case wxDF_TEXT:
378 case wxDF_OEMTEXT:
379 {
380 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
381 wxString str(textDataObject->GetText());
382 return wxSetClipboardData(data->GetFormat(), (wxObject*) (const char*) str);
383 break;
384 }
385 case wxDF_BITMAP:
386 case wxDF_DIB:
387 {
388 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
389 wxBitmap bitmap(bitmapDataObject->GetBitmap());
390 return wxSetClipboardData(data->GetFormat(), & bitmap);
391 break;
392 }
393 #if wxUSE_METAFILE
394 case wxDF_METAFILE:
395 {
396 wxMetafileDataObject* metaFileDataObject = (wxMetafileDataObject*) data;
397 wxMetafile metaFile = metaFileDataObject->GetMetafile();
398 return wxSetClipboardData(wxDF_METAFILE, & metaFile, metaFileDataObject->GetWidth(), metaFileDataObject->GetHeight());
399 break;
400 }
401 #endif
402 default:
403 {
404 return FALSE;
405 }
406 }
407
408 return FALSE;
409 #else
410 return FALSE;
411 #endif
412 }
413
414 void wxClipboard::Close()
415 {
416 wxCHECK_RET( m_open, "clipboard not open" );
417
418 m_open = FALSE;
419 wxCloseClipboard();
420 }
421
422 bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString& WXUNUSED(id) )
423 {
424 return wxIsClipboardFormatAvailable(format);
425 }
426
427 bool wxClipboard::GetData( wxDataObject *data )
428 {
429 wxCHECK_MSG( m_open, FALSE, "clipboard not open" );
430
431 #if wxUSE_DRAG_AND_DROP
432 switch (data->GetFormat())
433 {
434 case wxDF_TEXT:
435 case wxDF_OEMTEXT:
436 {
437 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
438 char* s = (char*) wxGetClipboardData(data->GetFormat());
439 if (s)
440 {
441 textDataObject->SetText(s);
442 delete[] s;
443 return TRUE;
444 }
445 else
446 return FALSE;
447 break;
448 }
449 case wxDF_BITMAP:
450 case wxDF_DIB:
451 {
452 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
453 wxBitmap* bitmap = (wxBitmap*) wxGetClipboardData(data->GetFormat());
454 if (bitmap)
455 {
456 bitmapDataObject->SetBitmap(* bitmap);
457 delete bitmap;
458 return TRUE;
459 }
460 else
461 return FALSE;
462 break;
463 }
464 #if wxUSE_METAFILE
465 case wxDF_METAFILE:
466 {
467 wxMetafileDataObject* metaFileDataObject = (wxMetafileDataObject*) data;
468 wxMetafile* metaFile = (wxMetafile*) wxGetClipboardData(wxDF_METAFILE);
469 if (metaFile)
470 {
471 metaFileDataObject->SetMetafile(* metaFile);
472 delete metaFile;
473 return TRUE;
474 }
475 else
476 return FALSE;
477
478 break;
479 }
480 #endif
481 default:
482 {
483 return FALSE;
484 }
485 }
486 return FALSE;
487 #else
488 return FALSE;
489 #endif
490 }
491
492 //-----------------------------------------------------------------------------
493 // wxClipboardModule
494 //-----------------------------------------------------------------------------
495
496 IMPLEMENT_DYNAMIC_CLASS(wxClipboardModule,wxModule)
497
498 bool wxClipboardModule::OnInit()
499 {
500 wxTheClipboard = new wxClipboard();
501
502 return TRUE;
503 }
504
505 void wxClipboardModule::OnExit()
506 {
507 if (wxTheClipboard) delete wxTheClipboard;
508 wxTheClipboard = (wxClipboard*) NULL;
509 }
510
511 #endif // wxUSE_CLIPBOARD
512