首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >被win32api + COM严重迷惑并给出答案

被win32api + COM严重迷惑并给出答案
EN

Stack Overflow用户
提问于 2013-10-27 01:34:26
回答 1查看 1.3K关注 0票数 2

从这里的另一个问题中,我问到如何从和Zune检索当前播放的歌曲,我从一个c++开发人员那里得到了一个答案,他解释了我将如何为WMP做这件事。

但是,我不是C++开发人员,也不是非常熟悉pywin32库的人。除此之外,所有这些文件(特别是关于WMP的文档)是可怕的。

为此,我需要您的帮助,以理解我将如何在Python中完成以下工作。

来源

我有工作代码在C++打印媒体名称,目前正在播放的WMP。这是一个简单的控制台应用程序(78行代码)。 步骤: 1)实现了一个实现IUnknown、IOleClientSite、IServiceProvider和IWMPRemoteMediaServices的基本COM对象。这很简单(可以说,您的里程可能会有所不同),使用ATL模板CComObjectRootEx。唯一需要(简单)代码的方法是IServiceProvider::QueryService和IWMPRemoteMediaServices::GetServiceType。所有其他方法都可能返回E_NOTIMPL 2)实例化"WMPlayer.OCX“COM对象(在我的例子中,通过CoCreateInstance) 3)通过QueryInterface从对象中检索IOleObject接口指针 4)从1中所见的类中获取对象(我使用CComObject<>::CreateInstance模板) 5)使用来自3)接口的SetClientSite方法,传递指向OleClientSite实现的指针。 6)在SetClientSite调用期间,WMP将回调您: fisrt请求一个IServiceProvider接口指针,第二个调用QueryService方法,请求一个IWMPRemoteMediaServices接口指针。返回IWMPRemoteMediaServices的实现,第三,将通过GetServiceType再次调用您。然后必须返回"Remote“。您现在已连接到正在运行的WMP实例。 7)查询COM对象以获得IWMPMedia接口指针 8) (如果7)没有给空,请阅读IWMPMedia::属性。 9)完成 所有这些都是在VS2010 /Windows7和WMP运行时进行的(如果没有媒体播放器进程运行,就什么也不做)。 我不知道yoy是否能够/想在Python中实现COM接口和对象。如果您对我的C++代码感兴趣,请告诉我。您可以在C++ DLL中使用该代码,然后从python中调用它。

我对win32api有一点了解。

在第一步,我真的不知道该做什么,谷歌IOleClientSite结果在msdn文档中,它是一个接口。不过,我已经被困在那里了。在Python中使用这些东西时,我找不到任何东西(可能只是我可怕的googling技巧)。

第二步:

代码语言:javascript
运行
复制
WMP = win32com.client.Dispatch("WMPlayer.OCX")

好吧,这是可行的。

进入第三步。QueryInterface -

“无论您拥有哪个对象,您都可以调用它的QueryInterface()方法来获得一个新的接口,比如IStream。”

来源

不过,对我来说不是。正如我理解他的解释,我认为这意味着每个com对象都从IUnknown“继承”了三种方法,其中之一是QueryInterface,然而,由于在QueryInterface对象上调用QueryInterface失败了,所以情况似乎并非如此。(Object has no attribute 'QueryInterface')

我可以继续说下去,但我相信你明白了,我不知道该如何处理这个问题。有人能帮我解决这个问题吗?最好有代码示例,但也欢迎资源/文档。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-28 20:01:03

几乎是最后的答案,但不能完成。没有C++模块的帮助,我似乎无法使用pythoncom来实现自定义接口。下面是Mark的回答(Mon,2003年1月13日):IDTExtensibility2接口

抱歉-你是索尔。为了支持任意接口,您需要以扩展模块的形式提供C++支持。有一种新的"Univgw“可以帮助你,但我对此知之甚少

我找不到任何关于"Univgw“的东西.

comtypes模块旨在解决这个问题,我找到了一些链接,说明它确实存在,但是我无法让它与我的新的Python3.3一起工作。它是Python2.x代码。comtypes似乎过时了,而且没有维护。

步骤1 IOleClientSite和IServiceProvider的OK,IWMPRemoteMediaServices的KO

步骤2、3、4和5

如果没有IWMPRemoteMediaServices,步骤6、7和8无法实现:-(

免责声明:完整的Python新手,请不要大喊大叫

代码语言:javascript
运行
复制
import pythoncom
import win32com.client as wc
from win32com.axcontrol import axcontrol
import win32com.server as ws
from win32com.server import util
from win32com.server.exception import COMException
import winerror
import pywintypes

# Windows Media Player Custom Interface IWMPRemoteMediaServices
IWMPRemoteMediaServices = pywintypes.IID("{CBB92747-741F-44FE-AB5B-F1A48F3B2A59}")

class OleClientSite:
    _public_methods_ = [ 'SaveObject', 'GetMoniker', 'GetContainer', 'ShowObject', 'OnShowWindow', 'RequestNewObjectLayout', 'QueryService' ]
    _com_interfaces_ = [ axcontrol.IID_IOleClientSite, pythoncom.IID_IServiceProvider ]

    def SaveObject(self):
        print("SaveObject")
        raise COMException(hresult=winerror.E_NOTIMPL)

    def GetMoniker(self, dwAssign, dwWhichMoniker):
        print("GetMoniker ")
        raise COMException(hresult=winerror.E_NOTIMPL)

    def GetContainer(self):
        print("GetContainer")
        raise COMException(hresult=winerror.E_NOTIMPL)

    def ShowObject(self):
        print("ShowObject")
        raise COMException(hresult=winerror.E_NOTIMPL)

    def OnShowWindow(self, fShow):
        print("ShowObject" + str(fShow))
        raise COMException(hresult=winerror.E_NOTIMPL)

    def RequestNewObjectLayout(self):
        print("RequestNewObjectLayout")
        raise COMException(hresult=winerror.E_NOTIMPL)

    def QueryService(self, guidService, riid):
        print("QueryService",guidService,riid)
        if riid == IWMPRemoteMediaServices:
            print("Known Requested IID, but can't implement!")
            raise COMException(hresult=winerror.E_NOINTERFACE)
        else:
            print("Requested IID is not IWMPRemoteMediaServices" )
            raise COMException(hresult=winerror.E_NOINTERFACE)


if __name__=='__main__':
    wmp = wc.Dispatch("WMPlayer.OCX")
    IOO = wmp._oleobj_.QueryInterface(axcontrol.IID_IOleObject)
    pyOCS = OleClientSite()
    comOCS = ws.util.wrap(pyOCS, axcontrol.IID_IOleClientSite)
    IOO.SetClientSite(comOCS)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19613750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档