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