2017-09-06 4 views
0

J'essaie de charger PDF dans la fenêtre. J'utilise Adobe Acrobat activeX et WinApi pour cela. J'ai pu "insérer" un navigateur Web dans ce code, mais je ne peux pas avec PDF. Bien que l'exécution j'obtiens l'erreur:Impossible de charger PDF dans la fenêtre

"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." 

Semble il y a un problème dans le prototype LoadFile, mais de ITypeLibViewer je reçois:

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

donc tout semble ok. Où est un problème?

UPD1: fileName fait passer maintenant comme ceci:

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

Mais maintenant, il se bloque

Mon code:

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); 
+1

'LoadFile' attend un' BSTR', alors que vous passez un littéral de chaîne de caractères. Voir [Type de données BSTR] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069.aspx) pour plus d'informations. – IInspectable

Répondre

1

outils Typelib affichage ... typelib information, qui est une sorte de définition de haut niveau des types.

Il ne vous donnera pas de disposition d'interface binaire brute (signature de méthode exacte, convention d'appel, qui doit être __stdcall pour les méthodes d'interface COM). Par conséquent, votre définition de IAcroAXDocShim est totalement erronée, d'où des plantages dus à une non-concordance de signature de méthode. Voici une définition partielle correcte de celui-ci:

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. 
}; 
+0

Que Dieu vous bénisse, bonhomme! Tout fonctionne maintenant comme prévu. Merci beaucoup! – user2123079