无法在窗口中加载 PDF

Can't load PDF in window

本文关键字:加载 PDF 窗口      更新时间:2023-10-16

我正在尝试将 pdf 加载到窗口中。我正在使用 Adobe Acrobat ActiveX Winapi 为此。我可以在此代码中"插入" Web浏览器,但是我不能使用 pdf 。执行时,我会出现错误:

"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."

似乎在LoadFile原型中存在问题,但是来自 itypelibviewer 我得到:

[id(0x00000002), helpstring("method LoadFile")]
VARIANT_BOOL LoadFile([in] BSTR fileName);

所以一切似乎还可以。问题在哪里?

upd1:通过这样做的传递文件名:

BSTR fileName = SysAllocString(L"C:\Users\Fetterless\Desktop\test.pdf");

但是现在它崩溃

我的代码:

const IID DIID_DPdf = { 0x3B813CE7, 0x7C10, 0x4F84, { 0xAD, 0x06, 0x9D, 0xF7, 0x6D, 0x97, 0xA9, 0xAA } };
const CLSID CLSID_Pdf = { 0xCA8A9780, 0x280D, 0x11CF, { 0xA2, 0x4D, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 } };
// Register our Window class
WNDCLASS wndclass;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = &WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = reinterpret_cast <HBRUSH> (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = windowClassName;
::RegisterClass(&wndclass);
HWND mainWindow = ::CreateWindow(
    windowClassName,
    windowTitle,
    0,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    windowWidth,
    windowHeight,
    NULL,
    NULL,
    0,
    0);
::ShowWindow(mainWindow, 1);
::UpdateWindow(mainWindow);
typedef HRESULT(WINAPI *PFonc)(IUnknown*, HWND, IUnknown**);
HINSTANCE hDLL2 = ::LoadLibrary(TEXT("atl.dll"));
if (!hDLL2)
    return 1;
PFonc AtlAxAttachControl = (PFonc) ::GetProcAddress(hDLL2, "AtlAxAttachControl");
RECT rect;
::GetClientRect(mainWindow, &rect);
container = ::CreateWindowEx(
    WS_EX_CLIENTEDGE,
    L"EDIT",
    L"", WS_CHILD | WS_VISIBLE,
    0,
    0,
    rect.right,
    rect.bottom,
    mainWindow,
    0,
    0,
    0);
HRESULT hr = ::CoInitialize(0);

MIDL_INTERFACE("3B813CE7-7C10-4F84-AD06-9DF76D97A9AA")
IAcroAXDocShim : public IDispatch
{
public:
    virtual VARIANT_BOOL LoadFile(BSTR fileName) = 0;
};
IAcroAXDocShim *pIpdf;
hr = ::CoCreateInstance(CLSID_Pdf, 0, CLSCTX_INPROC_SERVER, DIID_DPdf, (void**)&pIpdf);
hr = AtlAxAttachControl(pIpdf, container, 0);
if (FAILED(hr)) {
    MessageBox(0, L"FAILED(AtlAxAttachControl(pitd, container, NULL))", L"Error", MB_ICONERROR | MB_OK);
}

VARIANT_BOOL res = pIpdf->LoadFile(L"C:\Users\Fetterless\Desktop\test.pdf");

::MSG message;
while (::GetMessageA(&message, 0, 0, 0))
{
    switch (message.message) {
    case WM_QUIT:
        break;
    default:
        ::TranslateMessage(&message);
        ::DispatchMessage(&message);
        break;
    }
}
CoUninitialize();
FreeLibrary(hDLL2);

typelib工具显示... Typelib信息,这是一种类型的高级定义。

它不会为您提供原始的二进制接口布局(确切的方法签名,调用约定,这必须是com接口方法的__ stdcall)。

因此,您对iacroaxdocshim的定义是完全错误的,因此由于方法签名不匹配而导致崩溃。这是对此的正确部分定义:

MIDL_INTERFACE("3B813CE7-7C10-4F84-AD06-9DF76D97A9AA")
IAcroAXDocShim : public IDispatch
{
public:
    // LoadFile is the 3rd method. You were "blindly" calling this one instead.
    // Note if you don't need these 2, you could just define them as
    // virtual void DontCallMe() = 0;
    virtual HRESULT __stdcall get_src(BSTR* pVal) = 0;
    virtual HRESULT __stdcall put_src(BSTR pVal) = 0;
    virtual HRESULT __stdcall LoadFile(BSTR fileName, VARIANT_BOOL* ret) = 0;
    // the rest is undefined, but if you don't need it, you don't have to define it.
};