]> git.saurik.com Git - wxWidgets.git/blame - src/msw/clipbrd.cpp
catches program exceptions in release build (VC++ only)
[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
38#include "wx/metafile.h"
39#include "wx/clipbrd.h"
40#include "wx/msw/private.h"
41#include "wx/msw/dib.h"
42
43#include <string.h>
44
45#if !USE_SHARED_LIBRARY
46IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
47IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
48#endif
49
50bool wxClipboardIsOpen = FALSE;
51
52bool wxOpenClipboard(void)
53{
54 if (wxTheApp->GetTopWindow() && !wxClipboardIsOpen)
55 {
56 wxClipboardIsOpen = (::OpenClipboard((HWND) wxTheApp->GetTopWindow()->GetHWND()) != 0);
57 return wxClipboardIsOpen;
58 }
59 else return FALSE;
60}
61
62bool wxCloseClipboard(void)
63{
64 if (wxClipboardIsOpen)
65 {
66 wxClipboardIsOpen = FALSE;
67 }
68 return (::CloseClipboard() != 0);
69}
70
71bool wxEmptyClipboard(void)
72{
73 return (::EmptyClipboard() != 0);
74}
75
76bool wxClipboardOpen(void)
77{
78 return wxClipboardIsOpen;
79}
80
81bool wxIsClipboardFormatAvailable(int dataFormat)
82{
83 return (::IsClipboardFormatAvailable(dataFormat) != 0);
84}
85
86bool wxSetClipboardData(int dataFormat, wxObject *obj, int width, int height)
87{
88 switch (dataFormat)
89 {
b3324be2 90 case wxDF_BITMAP:
2bda0e17
KB
91 {
92 wxBitmap *wxBM = (wxBitmap *)obj;
93
94 HDC hdcMem = CreateCompatibleDC(NULL);
95 HDC hdcSrc = CreateCompatibleDC(NULL);
c4e7c2aa 96 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, (HBITMAP) wxBM->GetHBITMAP());
2bda0e17
KB
97 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
98 wxBM->GetWidth(), wxBM->GetHeight());
99 if (!hBitmap)
100 {
101 SelectObject(hdcSrc, old);
102 DeleteDC(hdcMem);
103 DeleteDC(hdcSrc);
104 return FALSE;
105 }
c4e7c2aa 106 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
2bda0e17
KB
107 BitBlt(hdcMem, 0, 0, wxBM->GetWidth(), wxBM->GetHeight(),
108 hdcSrc, 0, 0, SRCCOPY);
109
110 // Select new bitmap out of memory DC
111 SelectObject(hdcMem, old1);
112
113 // Set the data
114 bool success = (bool)(::SetClipboardData(CF_BITMAP, hBitmap) != 0);
115
116 // Clean up
117 SelectObject(hdcSrc, old);
118 DeleteDC(hdcSrc);
119 DeleteDC(hdcMem);
120 return success;
121 break;
122 }
b3324be2 123 case wxDF_DIB:
2bda0e17 124 {
47d67540 125#if wxUSE_IMAGE_LOADING_IN_MSW
2bda0e17
KB
126 HBITMAP hBitmap=(HBITMAP) ((wxBitmap *)obj)->GetHBITMAP();
127 HANDLE hDIB=BitmapToDIB(hBitmap,NULL); // NULL==uses system palette
128 bool success = (::SetClipboardData(CF_DIB,hDIB) != 0);
129#else
130 bool success=FALSE;
131#endif
132 return success;
133 break;
134 }
47d67540 135#if wxUSE_METAFILE
b3324be2 136 case wxDF_METAFILE:
2bda0e17
KB
137 {
138 wxMetaFile *wxMF = (wxMetaFile *)obj;
139 HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
140#ifdef __WINDOWS_386__
141 METAFILEPICT *mf = (METAFILEPICT *)MK_FP32(GlobalLock(data));
142#else
143 METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
144#endif
145
146 mf->mm = wxMF->GetWindowsMappingMode();
147 mf->xExt = width;
148 mf->yExt = height;
c4e7c2aa 149 mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
2bda0e17
KB
150 GlobalUnlock(data);
151 wxMF->SetHMETAFILE((WXHANDLE) NULL);
152
153 return (SetClipboardData(CF_METAFILEPICT, data) != 0);
154 break;
155 }
156#endif
157 case CF_SYLK:
158 case CF_DIF:
159 case CF_TIFF:
160 case CF_PALETTE:
161 {
162 return FALSE;
163 break;
164 }
b3324be2
JS
165 case wxDF_OEMTEXT:
166 dataFormat = wxDF_TEXT;
167 case wxDF_TEXT:
2bda0e17
KB
168 width = strlen((char *)obj) + 1;
169 height = 1;
170 default:
171 {
172 char *s = (char *)obj;
173 DWORD l;
174
175 l = (width * height);
176 HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
177 if (!hGlobalMemory)
178 return FALSE;
179
180#ifdef __WINDOWS_386__
181 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
182#else
183 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
184#endif
185
186#ifdef __WIN32__
187 memcpy(lpGlobalMemory, s, l);
188#elif defined(__WATCOMC__) && defined(__WINDOWS_386__)
189 memcpy(lpGlobalMemory, s, l);
190#else
191 hmemcpy(lpGlobalMemory, s, l);
192#endif
193
194 GlobalUnlock(hGlobalMemory);
195 HANDLE success = SetClipboardData(dataFormat, hGlobalMemory);
196 return (success != 0);
197 break;
198 }
199 }
200 return FALSE;
201}
202
203wxObject *wxGetClipboardData(int dataFormat, long *len)
204{
205 switch (dataFormat)
206 {
b3324be2 207 case wxDF_BITMAP:
2bda0e17
KB
208 {
209 BITMAP bm;
c4e7c2aa 210 HBITMAP hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP);
2bda0e17
KB
211 if (!hBitmap)
212 return NULL;
213
214 HDC hdcMem = CreateCompatibleDC(NULL);
215 HDC hdcSrc = CreateCompatibleDC(NULL);
216
c4e7c2aa 217 HBITMAP old = (HBITMAP) ::SelectObject(hdcSrc, hBitmap);
2bda0e17
KB
218 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
219
220 HBITMAP hNewBitmap = CreateBitmapIndirect(&bm);
221
222 if (!hNewBitmap)
223 {
224 SelectObject(hdcSrc, old);
225 DeleteDC(hdcMem);
226 DeleteDC(hdcSrc);
227 return NULL;
228 }
229
c4e7c2aa 230 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hNewBitmap);
2bda0e17
KB
231 BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
232 hdcSrc, 0, 0, SRCCOPY);
233
234 // Select new bitmap out of memory DC
235 SelectObject(hdcMem, old1);
236
237 // Clean up
238 SelectObject(hdcSrc, old);
239 DeleteDC(hdcSrc);
240 DeleteDC(hdcMem);
241
242 // Create and return a new wxBitmap
243 wxBitmap *wxBM = new wxBitmap;
244 wxBM->SetHBITMAP((WXHBITMAP) hNewBitmap);
245 wxBM->SetWidth(bm.bmWidth);
246 wxBM->SetHeight(bm.bmHeight);
247 wxBM->SetDepth(bm.bmPlanes);
248 wxBM->SetOk(TRUE);
249 return (wxObject *)wxBM;
250 break;
251 }
b3324be2 252 case wxDF_METAFILE:
2bda0e17
KB
253 case CF_SYLK:
254 case CF_DIF:
255 case CF_TIFF:
256 case CF_PALETTE:
b3324be2 257 case wxDF_DIB:
2bda0e17
KB
258 {
259 return FALSE;
260 break;
261 }
b3324be2
JS
262 case wxDF_OEMTEXT:
263 dataFormat = wxDF_TEXT;
264 case wxDF_TEXT:
2bda0e17
KB
265 default:
266 {
267 HANDLE hGlobalMemory = GetClipboardData(dataFormat);
268 if (!hGlobalMemory)
269 return NULL;
270
271 int hsize = (int)GlobalSize(hGlobalMemory);
272 if (len)
273 *len = hsize;
274
275 char *s = new char[hsize];
276 if (!s)
277 return NULL;
278
279#ifdef __WINDOWS_386__
280 LPSTR lpGlobalMemory = (LPSTR)MK_FP32(GlobalLock(hGlobalMemory));
281#else
282 LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
283#endif
284
285#ifdef __WIN32__
286 memcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
287#elif __WATCOMC__ && defined(__WINDOWS_386__)
288 memcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
289#else
290 hmemcpy(s, lpGlobalMemory, GlobalSize(hGlobalMemory));
291#endif
292
293 GlobalUnlock(hGlobalMemory);
294
295 return (wxObject *)s;
296 break;
297 }
298 }
299 return NULL;
300}
301
302int wxEnumClipboardFormats(int dataFormat)
303{
304 return ::EnumClipboardFormats(dataFormat);
305}
306
307int wxRegisterClipboardFormat(char *formatName)
308{
309 return ::RegisterClipboardFormat(formatName);
310}
311
312bool wxGetClipboardFormatName(int dataFormat, char *formatName, int maxCount)
313{
314 return (::GetClipboardFormatName(dataFormat, formatName, maxCount) > 0);
315}
316
317/*
318 * Generalized clipboard implementation by Matthew Flatt
319 */
320
321wxClipboard *wxTheClipboard = NULL;
322
323void wxInitClipboard(void)
324{
325 if (!wxTheClipboard)
326 wxTheClipboard = new wxClipboard;
327}
328
329wxClipboard::wxClipboard()
330{
331 clipOwner = NULL;
332 cbString = NULL;
333}
334
335wxClipboard::~wxClipboard()
336{
337 if (clipOwner)
338 clipOwner->BeingReplaced();
339 if (cbString)
340 delete[] cbString;
341}
342
343static int FormatStringToID(char *str)
344{
345 if (!strcmp(str, "TEXT"))
b3324be2
JS
346 return wxDF_TEXT;
347
2bda0e17
KB
348 return wxRegisterClipboardFormat(str);
349}
350
351void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
352{
353 bool got_selection;
354
355 if (clipOwner)
356 clipOwner->BeingReplaced();
357 clipOwner = client;
358 if (cbString) {
359 delete[] cbString;
360 cbString = NULL;
361 }
362
363 if (wxOpenClipboard()) {
364 char **formats, *data;
365 int i;
366 int ftype;
367 long size;
368
369 formats = clipOwner->formats.ListToArray(FALSE);
370 for (i = clipOwner->formats.Number(); i--; ) {
371 ftype = FormatStringToID(formats[i]);
372 data = clipOwner->GetData(formats[i], &size);
373 if (!wxSetClipboardData(ftype, (wxObject *)data, size, 1)) {
374 got_selection = FALSE;
375 break;
376 }
377 }
378
379 if (i < 0)
380 got_selection = wxCloseClipboard();
381 } else
382 got_selection = FALSE;
383
384 got_selection = FALSE; // Assume another process takes over
385
386 if (!got_selection) {
387 clipOwner->BeingReplaced();
388 clipOwner = NULL;
389 }
390}
391
392wxClipboardClient *wxClipboard::GetClipboardClient()
393{
394 return clipOwner;
395}
396
397void wxClipboard::SetClipboardString(char *str, long time)
398{
399 bool got_selection;
400
401 if (clipOwner) {
402 clipOwner->BeingReplaced();
403 clipOwner = NULL;
404 }
405 if (cbString)
406 delete[] cbString;
407
408 cbString = str;
409
410 if (wxOpenClipboard()) {
b3324be2 411 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
2bda0e17
KB
412 got_selection = FALSE;
413 else
414 got_selection = wxCloseClipboard();
415 } else
416 got_selection = FALSE;
417
418 got_selection = FALSE; // Assume another process takes over
419
420 if (!got_selection) {
421 delete[] cbString;
422 cbString = NULL;
423 }
424}
425
426char *wxClipboard::GetClipboardString(long time)
427{
428 char *str;
429 long length;
430
431 str = GetClipboardData("TEXT", &length, time);
432 if (!str) {
433 str = new char[1];
434 *str = 0;
435 }
436
437 return str;
438}
439
440char *wxClipboard::GetClipboardData(char *format, long *length, long time)
441{
442 if (clipOwner) {
443 if (clipOwner->formats.Member(format))
444 return clipOwner->GetData(format, length);
445 else
446 return NULL;
447 } else if (cbString) {
448 if (!strcmp(format, "TEXT"))
449 return copystring(cbString);
450 else
451 return NULL;
452 } else {
453 if (wxOpenClipboard()) {
454 receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
455 length);
456 wxCloseClipboard();
457 } else
458 receivedString = NULL;
459
460 return receivedString;
461 }
462}
463
464
47d67540 465#endif // wxUSE_CLIPBOARD
2bda0e17 466