Search code examples
pythonvb.netcom

Python: Converting COM PyIUnknown to known data type


I am currently trying to make a python app do the same thing as a VB app.

The app retrieves an image from an external device over the COM API. I've used win32com and managed to use the Dispatch mechanism to talk with the COM API.

In the VB app, the image is stored like this

pictureData = objResult.Properties('ResultImage')
myImage = AxHost.GetPictureFromIPicture(pictureData)

In my Python app, however on the picture data member, I get PyIUnknown object type. How do I get the image data out of this 'unknown' object?

Let me add that for other 'basic' data like strings, I can see them fine over the Python app.


Solution

  • I found a method that works, maybe not perfect, but if someone Google's this question, I hope it helps.

    from win32com.client import Dispatch
    import pythoncom
    
    imagedata = data.Properties.Item('ResultImage') #this is samas the VB line in the question , except I have to add 'Item' here 
    
    #win32com does not define IPicture type (http://timgolden.me.uk/pywin32-docs/com_objects.html)
    ipicture = Dispatch(imagedata.QueryInterface(pythoncom.IID_IDispatch))
    
    import win32ui
    import win32gui
    
    #creates a PyCBitMap object
    imagebitmap = win32ui.CreateBitmapFromHandle(ipicture.Handle)
    
    #we need a DC handle to save the bitmap file for some reason...
    dc_handler = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
    #this overwrites any older file without asking
    imagebitmap.SaveBitmapFile(dc_handler,'last_pic.bmp')
    

    Questions I still have in my mind are:

    1. are we only forced to interact with IPicture or any non-defined COM (by win32com) in a dynamic way? Is there an elegant way to extend the definitions of interfaces etc.? I tried using QueryInterface(pythontypes.IID('{7BF80980-BF32-101A-8BBB-00AA00300CAB}'). I got this IID from http://msdn.microsoft.com/en-us/library/windows/desktop/ms680761(v=vs.85).aspx however I got an error within Python that this interface cannot be handled.

    2. Not sure why I cannot use the methods defined for IPicture, but I could access the attributes? I tried simply to use ipicture.get_Handle() or ipicture.SaveAsFile() but these didn't work.