testPersist.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import pythoncom
  2. import win32com.server.util
  3. import time
  4. import win32com, sys, string, win32api, traceback
  5. import win32com.client.dynamic
  6. import win32com.client
  7. import pythoncom
  8. from win32com.axcontrol import axcontrol
  9. from pywintypes import Unicode
  10. from win32com import storagecon
  11. from win32com.test.util import CheckClean
  12. import pywintypes
  13. import win32ui
  14. import win32api, os
  15. from pywin32_testutil import str2bytes
  16. S_OK = 0
  17. import datetime
  18. import win32timezone
  19. now = win32timezone.now()
  20. class LockBytes:
  21. _public_methods_ = [ 'ReadAt', 'WriteAt', 'Flush', 'SetSize', 'LockRegion', 'UnlockRegion', 'Stat' ]
  22. _com_interfaces_ = [ pythoncom.IID_ILockBytes ]
  23. def __init__(self, data = ""):
  24. self.data = str2bytes(data)
  25. self.ctime = now
  26. self.mtime = now
  27. self.atime = now
  28. def ReadAt(self, offset, cb):
  29. print("ReadAt")
  30. result = self.data[offset:offset + cb]
  31. return result
  32. def WriteAt(self, offset, data):
  33. print("WriteAt " +str(offset))
  34. print("len " + str(len(data)))
  35. print("data:")
  36. #print data
  37. if len(self.data) >= offset:
  38. newdata = self.data[0:offset] + data
  39. print(len(newdata))
  40. if len(self.data) >= offset + len(data):
  41. newdata = newdata + self.data[offset + len(data):]
  42. print(len(newdata))
  43. self.data = newdata
  44. return len(data)
  45. def Flush(self, whatsthis=0):
  46. print("Flush" + str(whatsthis))
  47. fname = os.path.join(win32api.GetTempPath(), "persist.doc")
  48. open(fname, "wb").write(self.data)
  49. return S_OK
  50. def SetSize(self, size):
  51. print("Set Size" + str(size))
  52. if size > len(self.data):
  53. self.data = self.data + str2bytes("\000" * (size - len(self.data)))
  54. else:
  55. self.data = self.data[0:size]
  56. return S_OK
  57. def LockRegion(self, offset, size, locktype):
  58. print("LockRegion")
  59. pass
  60. def UnlockRegion(self, offset, size, locktype):
  61. print("UnlockRegion")
  62. pass
  63. def Stat(self, statflag):
  64. print("returning Stat " + str(statflag))
  65. return (
  66. "PyMemBytes",
  67. storagecon.STGTY_LOCKBYTES,
  68. len(self.data),
  69. self.mtime,
  70. self.ctime,
  71. self.atime,
  72. storagecon.STGM_DIRECT|storagecon.STGM_READWRITE|storagecon.STGM_CREATE ,
  73. storagecon.STGM_SHARE_EXCLUSIVE,
  74. "{00020905-0000-0000-C000-000000000046}",
  75. 0, # statebits ?
  76. 0
  77. )
  78. class OleClientSite:
  79. _public_methods_ = [ 'SaveObject', 'GetMoniker', 'GetContainer', 'ShowObject', 'OnShowWindow', 'RequestNewObjectLayout' ]
  80. _com_interfaces_ = [ axcontrol.IID_IOleClientSite ]
  81. def __init__(self, data = ""):
  82. self.IPersistStorage = None
  83. self.IStorage = None
  84. def SetIPersistStorage(self, IPersistStorage):
  85. self.IPersistStorage = IPersistStorage
  86. def SetIStorage(self, IStorage):
  87. self.IStorage = IStorage
  88. def SaveObject(self):
  89. print("SaveObject")
  90. if self.IPersistStorage != None and self.IStorage != None:
  91. self.IPersistStorage.Save(self.IStorage,1)
  92. self.IStorage.Commit(0)
  93. return S_OK
  94. def GetMoniker(self, dwAssign, dwWhichMoniker):
  95. print("GetMoniker " + str(dwAssign) + " " + str(dwWhichMoniker))
  96. def GetContainer(self):
  97. print("GetContainer")
  98. def ShowObject(self):
  99. print("ShowObject")
  100. def OnShowWindow(self, fShow):
  101. print("ShowObject" + str(fShow))
  102. def RequestNewObjectLayout(self):
  103. print("RequestNewObjectLayout")
  104. def test():
  105. # create a LockBytes object and
  106. #wrap it as a COM object
  107. # import win32com.server.dispatcher
  108. lbcom = win32com.server.util.wrap(LockBytes(), pythoncom.IID_ILockBytes) #, useDispatcher=win32com.server.dispatcher.DispatcherWin32trace)
  109. # create a structured storage on the ILockBytes object
  110. stcom = pythoncom.StgCreateDocfileOnILockBytes(lbcom, storagecon.STGM_DIRECT| storagecon.STGM_CREATE | storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE, 0)
  111. # create our ClientSite
  112. ocs = OleClientSite()
  113. # wrap it as a COM object
  114. ocscom = win32com.server.util.wrap(ocs, axcontrol.IID_IOleClientSite)
  115. # create a Word OLE Document, connect it to our site and our storage
  116. oocom=axcontrol.OleCreate("{00020906-0000-0000-C000-000000000046}",
  117. axcontrol.IID_IOleObject,
  118. 0,
  119. (0,),
  120. ocscom,
  121. stcom,
  122. )
  123. mf=win32ui.GetMainFrame()
  124. hwnd=mf.GetSafeHwnd()
  125. # Set the host and document name
  126. # for unknown reason document name becomes hostname, and document name
  127. # is not set, debugged it, but don't know where the problem is?
  128. oocom.SetHostNames("OTPython", "This is Cool")
  129. # activate the OLE document
  130. oocom.DoVerb( -1, ocscom, 0, hwnd, mf.GetWindowRect())
  131. # set the hostnames again
  132. oocom.SetHostNames("OTPython2", "ThisisCool2")
  133. # get IDispatch of Word
  134. doc=win32com.client.Dispatch(oocom.QueryInterface(pythoncom.IID_IDispatch))
  135. # get IPersistStorage of Word
  136. dpcom=oocom.QueryInterface(pythoncom.IID_IPersistStorage)
  137. # let our ClientSite know the interfaces
  138. ocs.SetIPersistStorage(dpcom)
  139. ocs.SetIStorage(stcom)
  140. # use IDispatch to do the Office Word test
  141. # pasted from TestOffice.py
  142. wrange = doc.Range()
  143. for i in range(10):
  144. wrange.InsertAfter("Hello from Python %d\n" % i)
  145. paras = doc.Paragraphs
  146. for i in range(len(paras)):
  147. paras[i]().Font.ColorIndex = i+1
  148. paras[i]().Font.Size = 12 + (4 * i)
  149. # XXX - note that
  150. # for para in paras:
  151. # para().Font...
  152. # doesnt seem to work - no error, just doesnt work
  153. # Should check if it works for VB!
  154. dpcom.Save(stcom, 0)
  155. dpcom.HandsOffStorage()
  156. # oocom.Close(axcontrol.OLECLOSE_NOSAVE) # or OLECLOSE_SAVEIFDIRTY, but it fails???
  157. #Save the ILockBytes data to "persist2.doc"
  158. lbcom.Flush()
  159. #exiting Winword will automatically update the ILockBytes data
  160. #and flush it to "%TEMP%\persist.doc"
  161. doc.Application.Quit()
  162. if __name__=='__main__':
  163. test()
  164. pythoncom.CoUninitialize()
  165. CheckClean()