День добрый
Есть необходимость получать окно предварительного просмотра windows в своём окне
Имеется такой код:
from comtypes import (IUnknown, STDMETHOD, HRESULT, GUID, CLSCTX_LOCAL_SERVER)
import comtypes.client as cc
from ctypes import POINTER
from ctypes.wintypes import HWND, MSG, DWORD, LPCWSTR, RECT, tagRECT
import pythoncom
class IPreviewHandler(IUnknown):
_case_insensitive_ = False
# _iid_ = GUID('{8895B1C6-B41F-4C1C-A562-0D564250836F}') # pdf
_iid_ = GUID('{E357FCCD-A995-4576-B01F-234630154E96}') #dwg
_idlflags_ = []
_methods_ = [
## virtual HRESULT STDMETHODCALLTYPE SetWindow(
## /* [in] */ HWND hwnd,
## /* [in] */ CRECTPTR prc) = 0;
STDMETHOD(HRESULT, "SetWindow",
[HWND, POINTER(tagRECT)]),
## virtual HRESULT STDMETHODCALLTYPE SetRect(
## /* [in] */ CRECTPTR prc) = 0;
STDMETHOD(HRESULT, "SetRect",
[POINTER(RECT)]),
## virtual HRESULT STDMETHODCALLTYPE DoPreview( void) = 0;
STDMETHOD(HRESULT, "DoPreview", []),
## virtual HRESULT STDMETHODCALLTYPE Unload( void) = 0;
STDMETHOD(HRESULT, "Unload", []),
## virtual HRESULT STDMETHODCALLTYPE SetFocus( void) = 0;
STDMETHOD(HRESULT, "SetFocus", []),
## virtual HRESULT STDMETHODCALLTYPE QueryFocus(
## /* [out] */ HWNDPTR phwnd) = 0;
STDMETHOD(HRESULT, "QueryFocus",
[POINTER(HWND)]),
## virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(
## /* [in] */ MSGPTR pmsg) = 0;
STDMETHOD(HRESULT, "TranslateAccelerator",
[POINTER(MSG)])
]
#
class Interface(IUnknown):
_case_insensitive_ = False
_iid_ = GUID('{B7D14566-0509-4CCE-A71F-0A554233BD9B}') # IInitializeWithFile
_idlflags_ = []
_methods_ = [
STDMETHOD(HRESULT, "Initialize",
[LPCWSTR, DWORD])
]
def get_preview_file(filepath: str, hwnd: int, rect: tuple):
# clsd = '{3A84F9C2-6164-485C-A7D9-4B27F8AC009E}' # pdf
clsd = '{AC1DB655-4F9A-4c39-8AD2-A65324A4C446}' #dwg
handler = cc.CreateObject(clsd, clsctx=CLSCTX_LOCAL_SERVER, interface=IPreviewHandler)
iwstream = handler.QueryInterface(Interface)
iwstream.Initialize(filepath, 1)
rect = (rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3])
handler.SetWindow(hwnd, tagRECT(*rect))
handler.DoPreview()
handler.SetFocus()
return handler
где
handler = cc.CreateObject(clsd, clsctx=CLSCTX_LOCAL_SERVER, interface=IPreviewHandler) - создаю экземпляр класса для просмотра
IPreviewHandler - зарегистрированный в системе просмоторщик
Interface - интерфейс просмотра, в данном случае через файл
Сложности в том, что для pdf или xls работает всё без проблем. Но если же я хочу просмотреть файлы, например, AutoCAD, то есть dwg, то появляется такая ошибка
handler = cc.CreateObject(clsd, clsctx=CLSCTX_LOCAL_SERVER, interface=IPreviewHandler)
File "C:\python 3.9.10\lib\site-packages\comtypes\client\__init__.py", line 215, in CreateObject
obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface)
File "C:\python 3.9.10\lib\site-packages\comtypes\__init__.py", line 1264, in CoCreateInstance
_ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
File "_ctypes/callproc.c", line 997, in GetResult
OSError: [WinError -2147221164] Класс не зарегистрирован
Мне не совсем ясно, почему класс не регистрирован, если он прописан в реестре и сам windows успешно может просматривать dwg файлы... может он использует для этого другие просмоторщики, но не уверен