[python-win32] win32clipboard & bitmaps

Luke Deller ldeller@xplantechnology.com
Wed, 23 May 2001 22:52:23 +1000


This is a multi-part message in MIME format.

------=_NextPart_000_000C_01C0E3DB.08206E60
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi again,
I downloaded the PyWin32 code from cvs and found the problem in
win32clipboard.  It assumes that the handle returned from GetClipboardData
was an HGLOBAL.  This is not true for some clipboard formats such as bitmaps
and metafiles.

I have patched win32clipboardmodule.cpp to handle CF_ENHMETAFILE and
CF_METAFILE correctly, and to generate an "unimplemented" error message for
CF_BITMAP and CF_DIB. (my patch is attached to this email).

Regards,
Luke Deller.

-----Original Message-----
From: python-win32-admin@python.org
[mailto:python-win32-admin@python.org]On Behalf Of Luke Deller
Sent: Wednesday, 23 May 2001 5:43 PM
To: python-win32@python.org
Subject: [python-win32] win32clipboard & bitmaps


Hi,
I'm having trouble with the win32clipboard module in win32all-138.
I do the following after copying a bitmap image into the clipboard:

$ python
Python 2.0 (#8, Oct 16 2000, 17:27:58) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> import win32clipboard
>>> win32clipboard.OpenClipboard(0)
>>> print
win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_BITMAP)
1
>>> str = win32clipboard.GetClipboardData(win32clipboard.CF_BITMAP)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
pywintypes.api_error: (6, 'GetClipboardData:GlobalLock', 'The handle is
invalid.
')

Any ideas why I get this exception?  Is this a bug in win32clipboard?  The
clipboard contents will paste correctly into another application (eg
Microsoft Word using "Paste Special" to paste as a regular bitmap)

Thanks!
Luke.


_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32



------=_NextPart_000_000C_01C0E3DB.08206E60
Content-Type: application/octet-stream;
	name="win32clipboard.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="win32clipboard.patch"

Index: win32/src/win32clipboardmodule.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/cvsroot/PyWin32/win32/src/win32clipboardmodule.cpp,v
retrieving revision 1.8
diff -u -r1.8 win32clipboardmodule.cpp
--- win32clipboardmodule.cpp	2001/05/08 23:46:28	1.8
+++ win32clipboardmodule.cpp	2001/05/23 12:55:15
@@ -290,33 +290,81 @@
=20
   if (!handle) {
     return ReturnAPIError("GetClipboardData");
-  }
+  } =20
=20
-  HGLOBAL cData;
-  cData =3D GlobalLock(handle);
-  if (!cData) {
-    GlobalUnlock(handle);
-    return ReturnAPIError("GetClipboardData:GlobalLock");
-  }
-  DWORD size =3D GlobalSize(cData);
-  if (!size) {
-    GlobalUnlock(handle);
-    return ReturnAPIError("GetClipboardData:GlobalSize");
+  void * cData;
+  DWORD size;
+  switch (format) {
+    case CF_ENHMETAFILE:
+      size =3D GetEnhMetaFileBits((HENHMETAFILE)handle, 0, NULL);
+      if (!size)
+	return ReturnAPIError("GetClipboardData:GetEnhMetafileBits(NULL)");
+      // allocate a temporary buffer for enhanced metafile
+      cData =3D malloc(size);
+      if (cData =3D=3D NULL)
+	return ReturnAPIError("GetClipboardData:malloc");
+      // copy enhanced metafile into the temporary buffer
+      if (0 =3D=3D GetEnhMetaFileBits((HENHMETAFILE)handle, size, =
(LPBYTE)cData)) {
+	free(cData);
+	return ReturnAPIError("GetClipboardData:GetEnhMetafileBits");
+      }
+      break;
+    case CF_METAFILEPICT:
+      size =3D GetMetaFileBitsEx((HMETAFILE)handle, 0, NULL);
+      if (!size)
+	return ReturnAPIError("GetClipboardData:GetMetafileBitsEx(NULL)");
+      // allocate a temporary buffer for metafile
+      cData =3D malloc(size);
+      if (cData =3D=3D NULL)
+	return ReturnAPIError("GetClipboardData:malloc");
+      // copy metafile into the temporary buffer
+      if (0 =3D=3D GetMetaFileBitsEx((HMETAFILE)handle, size, cData)) {
+	free(cData);
+	return ReturnAPIError("GetClipboardData:GetMetafileBitsEx");
+      }
+      break;
+    case CF_BITMAP:
+      return ReturnAPIError("GetClipboardData(CF_BITMAP) =
unimplemented");
+      break;
+    case CF_DIB:
+      return ReturnAPIError("GetClipboardData(CF_DIB) unimplemented");
+      break;
+    default:
+      cData =3D GlobalLock(handle);
+      if (!cData) {
+        GlobalUnlock(handle);
+        return ReturnAPIError("GetClipboardData:GlobalLock");
+      }
+      size  =3D GlobalSize(cData);
+      if (!size) {
+        GlobalUnlock(handle);
+        return ReturnAPIError("GetClipboardData:GlobalSize");
+      }
+      break;
   }
   switch (format) {
     case CF_UNICODETEXT:
       ret =3D PyWinObject_FromWCHAR((wchar_t *)cData, (size / =
sizeof(wchar_t))-1);
+      GlobalUnlock(handle);
       break;
     // For the text formats, strip the null!
     case CF_TEXT:
     case CF_OEMTEXT:
       ret =3D PyString_FromStringAndSize((char *)cData, size-1);
+      GlobalUnlock(handle);
+      break;
+    case CF_ENHMETAFILE:
+    case CF_METAFILEPICT:
+    case CF_BITMAP:
+    case CF_DIB:
+      ret =3D PyString_FromStringAndSize((char *)cData, size);
+      free(cData);
       break;
     default:
       ret =3D PyString_FromStringAndSize((char *)cData, size);
+      GlobalUnlock(handle);
       break;
   }
-  GlobalUnlock(handle);
   return ret;
=20
   // @comm An application can enumerate the available formats in =
advance by

------=_NextPart_000_000C_01C0E3DB.08206E60--