testClipboard.py
5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# testClipboard.py
import unittest
import pythoncom
import win32con
import winerror
import win32clipboard
from pywin32_testutil import str2bytes
from win32com.server.util import NewEnum, wrap
from win32com.server.exception import COMException
IDataObject_Methods = """GetData GetDataHere QueryGetData
GetCanonicalFormatEtc SetData EnumFormatEtc
DAdvise DUnadvise EnumDAdvise""".split()
# A COM object implementing IDataObject used for basic testing.
num_do_objects = 0
def WrapCOMObject(ob, iid=None):
return wrap(ob, iid=iid, useDispatcher = 0)
class TestDataObject:
_com_interfaces_ = [pythoncom.IID_IDataObject]
_public_methods_ = IDataObject_Methods
def __init__(self, strval):
global num_do_objects
num_do_objects += 1
self.strval = strval
self.supported_fe = []
for cf in (win32con.CF_TEXT, win32con.CF_UNICODETEXT):
fe = cf, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL
self.supported_fe.append(fe)
def __del__(self):
global num_do_objects
num_do_objects -= 1
def _query_interface_(self, iid):
if iid==pythoncom.IID_IEnumFORMATETC:
return NewEnum(self.supported_fe, iid=iid)
def GetData(self, fe):
ret_stg = None
cf, target, aspect, index, tymed = fe
if aspect & pythoncom.DVASPECT_CONTENT and \
tymed==pythoncom.TYMED_HGLOBAL:
if cf == win32con.CF_TEXT:
ret_stg = pythoncom.STGMEDIUM()
# ensure always 'bytes' by encoding string.
ret_stg.set(pythoncom.TYMED_HGLOBAL, str2bytes(self.strval))
elif cf == win32con.CF_UNICODETEXT:
ret_stg = pythoncom.STGMEDIUM()
ret_stg.set(pythoncom.TYMED_HGLOBAL, unicode(self.strval))
if ret_stg is None:
raise COMException(hresult=winerror.E_NOTIMPL)
return ret_stg
def GetDataHere(self, fe):
raise COMException(hresult=winerror.E_NOTIMPL)
def QueryGetData(self, fe):
cf, target, aspect, index, tymed = fe
if aspect & pythoncom.DVASPECT_CONTENT == 0:
raise COMException(hresult=winerror.DV_E_DVASPECT)
if tymed!=pythoncom.TYMED_HGLOBAL:
raise COMException(hresult=winerror.DV_E_TYMED)
return None # should check better
def GetCanonicalFormatEtc(self, fe):
RaiseCOMException(winerror.DATA_S_SAMEFORMATETC)
# return fe
def SetData(self, fe, medium):
raise COMException(hresult=winerror.E_NOTIMPL)
def EnumFormatEtc(self, direction):
if direction != pythoncom.DATADIR_GET:
raise COMException(hresult=winerror.E_NOTIMPL)
return NewEnum(self.supported_fe, iid=pythoncom.IID_IEnumFORMATETC)
def DAdvise(self, fe, flags, sink):
raise COMException(hresult=winerror.E_NOTIMPL)
def DUnadvise(self, connection):
raise COMException(hresult=winerror.E_NOTIMPL)
def EnumDAdvise(self):
raise COMException(hresult=winerror.E_NOTIMPL)
class ClipboardTester(unittest.TestCase):
def setUp(self):
pythoncom.OleInitialize()
def tearDown(self):
try:
pythoncom.OleFlushClipboard()
except pythoncom.com_error:
# We never set anything!
pass
def testIsCurrentClipboard(self):
do = TestDataObject("Hello from Python")
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
pythoncom.OleSetClipboard(do)
self.failUnless(pythoncom.OleIsCurrentClipboard(do))
def testComToWin32(self):
# Set the data via our DataObject
do = TestDataObject("Hello from Python")
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
pythoncom.OleSetClipboard(do)
# Then get it back via the standard win32 clipboard functions.
win32clipboard.OpenClipboard()
got = win32clipboard.GetClipboardData(win32con.CF_TEXT)
# CF_TEXT gives bytes on py3k - use str2bytes() to ensure that's true.
expected = str2bytes("Hello from Python")
self.assertEqual(got, expected)
# Now check unicode
got = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT)
self.assertEqual(got, u"Hello from Python")
win32clipboard.CloseClipboard()
def testWin32ToCom(self):
# Set the data via the std win32 clipboard functions.
val = str2bytes("Hello again!") # ensure always bytes, even in py3k
win32clipboard.OpenClipboard()
win32clipboard.SetClipboardData(win32con.CF_TEXT, val)
win32clipboard.CloseClipboard()
# and get it via an IDataObject provided by COM
do = pythoncom.OleGetClipboard()
cf = win32con.CF_TEXT, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL
stg = do.GetData(cf)
got = stg.data
# The data we get back has the \0, as our STGMEDIUM has no way of
# knowing if it meant to be a string, or a binary buffer, so
# it must return it too.
self.failUnlessEqual(got, str2bytes("Hello again!\0"))
def testDataObjectFlush(self):
do = TestDataObject("Hello from Python")
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
pythoncom.OleSetClipboard(do)
self.assertEqual(num_do_objects, 1)
do = None # clear my ref!
pythoncom.OleFlushClipboard()
self.assertEqual(num_do_objects, 0)
def testDataObjectReset(self):
do = TestDataObject("Hello from Python")
do = WrapCOMObject(do)
pythoncom.OleSetClipboard(do)
do = None # clear my ref!
self.assertEqual(num_do_objects, 1)
pythoncom.OleSetClipboard(None)
self.assertEqual(num_do_objects, 0)
if __name__=='__main__':
from win32com.test import util
util.testmain()