Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

testPersist.py 6.2KB

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