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.

util.py 3.3KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """General client side utilities.
  2. This module contains utility functions, used primarily by advanced COM
  3. programmers, or other COM modules.
  4. """
  5. import pythoncom
  6. from win32com.client import Dispatch, _get_good_object_
  7. PyIDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
  8. def WrapEnum(ob, resultCLSID=None):
  9. """Wrap an object in a VARIANT enumerator.
  10. All VT_DISPATCHs returned by the enumerator are converted to wrapper objects
  11. (which may be either a class instance, or a dynamic.Dispatch type object).
  12. """
  13. if type(ob) != pythoncom.TypeIIDs[pythoncom.IID_IEnumVARIANT]:
  14. ob = ob.QueryInterface(pythoncom.IID_IEnumVARIANT)
  15. return EnumVARIANT(ob, resultCLSID)
  16. class Enumerator:
  17. """A class that provides indexed access into an Enumerator
  18. By wrapping a PyIEnum* object in this class, you can perform
  19. natural looping and indexing into the Enumerator.
  20. Looping is very efficient, but it should be noted that although random
  21. access is supported, the underlying object is still an enumerator, so
  22. this will force many reset-and-seek operations to find the requested index.
  23. """
  24. def __init__(self, enum):
  25. self._oleobj_ = enum # a PyIEnumVARIANT
  26. self.index = -1
  27. def __getitem__(self, index):
  28. return self.__GetIndex(index)
  29. def __call__(self, index):
  30. return self.__GetIndex(index)
  31. def __GetIndex(self, index):
  32. if type(index) != type(0):
  33. raise TypeError("Only integer indexes are supported for enumerators")
  34. # NOTE
  35. # In this context, self.index is users purely as a flag to say
  36. # "am I still in sequence". The user may call Next() or Reset() if they
  37. # so choose, in which case self.index will not be correct (although we
  38. # still want to stay in sequence)
  39. if index != self.index + 1:
  40. # Index requested out of sequence.
  41. self._oleobj_.Reset()
  42. if index:
  43. self._oleobj_.Skip(
  44. index
  45. ) # if asked for item 1, must skip 1, Python always zero based.
  46. self.index = index
  47. result = self._oleobj_.Next(1)
  48. if len(result):
  49. return self._make_retval_(result[0])
  50. raise IndexError("list index out of range")
  51. def Next(self, count=1):
  52. ret = self._oleobj_.Next(count)
  53. realRets = []
  54. for r in ret:
  55. realRets.append(self._make_retval_(r))
  56. return tuple(realRets) # Convert back to tuple.
  57. def Reset(self):
  58. return self._oleobj_.Reset()
  59. def Clone(self):
  60. return self.__class__(self._oleobj_.Clone(), self.resultCLSID)
  61. def _make_retval_(self, result):
  62. return result
  63. class EnumVARIANT(Enumerator):
  64. def __init__(self, enum, resultCLSID=None):
  65. self.resultCLSID = resultCLSID
  66. Enumerator.__init__(self, enum)
  67. def _make_retval_(self, result):
  68. return _get_good_object_(result, resultCLSID=self.resultCLSID)
  69. class Iterator:
  70. def __init__(self, enum, resultCLSID=None):
  71. self.resultCLSID = resultCLSID
  72. self._iter_ = iter(enum.QueryInterface(pythoncom.IID_IEnumVARIANT))
  73. def __iter__(self):
  74. return self
  75. def __next__(self):
  76. return _get_good_object_(next(self._iter_), resultCLSID=self.resultCLSID)