|
5 | 5 | # Note that if the unknown dispatch object then returns a known
|
6 | 6 | # dispatch object, the known class will be used. This contrasts
|
7 | 7 | # with dynamic.Dispatch behaviour, where dynamic objects are always used.
|
| 8 | +from __future__ import annotations |
8 | 9 |
|
9 | 10 | import sys
|
10 | 11 | from itertools import chain
|
@@ -263,7 +264,39 @@ def __setattr__(self, attr, val):
|
263 | 264 | setattr(self._obj_, attr, val)
|
264 | 265 |
|
265 | 266 |
|
266 |
| -def DispatchWithEvents(clsid, user_event_class): |
| 267 | +def __get_disp_and_event_classes(dispatch): |
| 268 | + # Create/Get the object. |
| 269 | + disp = Dispatch(dispatch) |
| 270 | + |
| 271 | + if disp.__class__.__dict__.get("CLSID"): |
| 272 | + return disp.__class__ |
| 273 | + |
| 274 | + # Eeek - no makepy support - try and build it. |
| 275 | + error_msg = "This COM object can not automate the makepy process - please run makepy manually for this object" |
| 276 | + try: |
| 277 | + ti = disp._oleobj_.GetTypeInfo() |
| 278 | + disp_clsid = ti.GetTypeAttr()[0] |
| 279 | + tlb, index = ti.GetContainingTypeLib() |
| 280 | + tla = tlb.GetLibAttr() |
| 281 | + gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) |
| 282 | + # Get the class from the module. |
| 283 | + disp_class = gencache.GetClassForProgID(str(disp_clsid)) |
| 284 | + except pythoncom.com_error as error: |
| 285 | + raise TypeError(error_msg) from error |
| 286 | + |
| 287 | + if disp_class is None: |
| 288 | + raise TypeError(error_msg) |
| 289 | + # Get the clsid |
| 290 | + clsid = disp_class.CLSID |
| 291 | + # Create a new class that derives from 2 classes: |
| 292 | + # the event sink class and the user class. |
| 293 | + events_class = getevents(clsid) |
| 294 | + if events_class is None: |
| 295 | + raise ValueError("This COM object does not support events.") |
| 296 | + return disp, disp_class, events_class |
| 297 | + |
| 298 | + |
| 299 | +def DispatchWithEvents(clsid, user_event_class) -> EventsProxy: |
267 | 300 | """Create a COM object that can fire events to a user defined class.
|
268 | 301 | clsid -- The ProgID or CLSID of the object to create.
|
269 | 302 | user_event_class -- A Python class object that responds to the events.
|
@@ -302,39 +335,14 @@ class object that derives from three classes:
|
302 | 335 | Visible changed: 1
|
303 | 336 | >>>
|
304 | 337 | """
|
305 |
| - # Create/Get the object. |
306 |
| - disp = Dispatch(clsid) |
307 |
| - if not disp.__class__.__dict__.get( |
308 |
| - "CLSID" |
309 |
| - ): # Eeek - no makepy support - try and build it. |
310 |
| - try: |
311 |
| - ti = disp._oleobj_.GetTypeInfo() |
312 |
| - disp_clsid = ti.GetTypeAttr()[0] |
313 |
| - tlb, index = ti.GetContainingTypeLib() |
314 |
| - tla = tlb.GetLibAttr() |
315 |
| - gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) |
316 |
| - # Get the class from the module. |
317 |
| - disp_class = gencache.GetClassForProgID(str(disp_clsid)) |
318 |
| - except pythoncom.com_error: |
319 |
| - raise TypeError( |
320 |
| - "This COM object can not automate the makepy process - please run makepy manually for this object" |
321 |
| - ) |
322 |
| - else: |
323 |
| - disp_class = disp.__class__ |
324 |
| - # If the clsid was an object, get the clsid |
325 |
| - clsid = disp_class.CLSID |
326 |
| - # Create a new class that derives from 3 classes - the dispatch class, the event sink class and the user class. |
327 |
| - events_class = getevents(clsid) |
328 |
| - if events_class is None: |
329 |
| - raise ValueError("This COM object does not support events.") |
| 338 | + disp, disp_class, events_class = __get_disp_and_event_classes(clsid) |
330 | 339 | result_class = type(
|
331 | 340 | "COMEventClass",
|
332 | 341 | (disp_class, events_class, user_event_class),
|
333 | 342 | {"__setattr__": _event_setattr_},
|
334 | 343 | )
|
335 |
| - instance = result_class( |
336 |
| - disp._oleobj_ |
337 |
| - ) # This only calls the first base class __init__. |
| 344 | + # This only calls the first base class __init__. |
| 345 | + instance = result_class(disp._oleobj_) |
338 | 346 | events_class.__init__(instance, instance)
|
339 | 347 | if hasattr(user_event_class, "__init__"):
|
340 | 348 | user_event_class.__init__(instance)
|
@@ -365,33 +373,14 @@ def WithEvents(disp, user_event_class):
|
365 | 373 | This is mainly useful where using DispatchWithEvents causes
|
366 | 374 | circular reference problems that the simple proxy doesn't deal with
|
367 | 375 | """
|
368 |
| - disp = Dispatch(disp) |
369 |
| - if not disp.__class__.__dict__.get( |
370 |
| - "CLSID" |
371 |
| - ): # Eeek - no makepy support - try and build it. |
372 |
| - try: |
373 |
| - ti = disp._oleobj_.GetTypeInfo() |
374 |
| - disp_clsid = ti.GetTypeAttr()[0] |
375 |
| - tlb, index = ti.GetContainingTypeLib() |
376 |
| - tla = tlb.GetLibAttr() |
377 |
| - gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) |
378 |
| - # Get the class from the module. |
379 |
| - disp_class = gencache.GetClassForProgID(str(disp_clsid)) |
380 |
| - except pythoncom.com_error: |
381 |
| - raise TypeError( |
382 |
| - "This COM object can not automate the makepy process - please run makepy manually for this object" |
383 |
| - ) |
384 |
| - else: |
385 |
| - disp_class = disp.__class__ |
386 |
| - # Get the clsid |
387 |
| - clsid = disp_class.CLSID |
388 |
| - # Create a new class that derives from 2 classes - the event sink |
389 |
| - # class and the user class. |
390 |
| - events_class = getevents(clsid) |
391 |
| - if events_class is None: |
392 |
| - raise ValueError("This COM object does not support events.") |
393 |
| - result_class = type("COMEventClass", (events_class, user_event_class), {}) |
394 |
| - instance = result_class(disp) # This only calls the first base class __init__. |
| 376 | + disp, disp_class, events_class = __get_disp_and_event_classes(disp) |
| 377 | + result_class = type( |
| 378 | + "COMEventClass", |
| 379 | + (events_class, user_event_class), |
| 380 | + {}, |
| 381 | + ) |
| 382 | + # This only calls the first base class __init__. |
| 383 | + instance = result_class(disp) |
395 | 384 | if hasattr(user_event_class, "__init__"):
|
396 | 385 | user_event_class.__init__(instance)
|
397 | 386 | return instance
|
|
0 commit comments