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