Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
ReaderWrapper to control Adobe Reader - Use in VFP?
Message
De
10/12/2004 18:57:36
 
 
À
10/12/2004 11:00:56
Information générale
Forum:
Visual FoxPro
Catégorie:
COM/DCOM et OLE Automation
Versions des environnements
Visual FoxPro:
VFP 8 SP1
OS:
Windows XP
Network:
Windows XP
Database:
Visual FoxPro
Divers
Thread ID:
00968303
Message ID:
00968456
Vues:
8
Tracy,

I'm not sure what you mean. Do you want to use it as a wrapper and call from VFP, or translate to VFP ?

I made a VFP wrapper based on the code you showed. It does working (almost all) with one exception. The DDE Callback function must be implemented. You can not pass a NULL pointer. Just create a very small wrapper for that.

If you want to wrapped the whole code in C++ (FLL), I think you better change it a little so you can simply call function by function (haven't test it yet though, I'm not really into COM programming). Or maybe someone can help you with COM


Update:
Sorry, I guess I was focusing too much into C++, API and COM things. Actually it can be done with VFP command directly. Here is the code:
Local lc_DocFile, lo_AcroReader

Declare Sleep in Kernel32 Long dwMilliSecond
Declare Integer ShellExecute in Shell32 ;
   Long hWnd, String cAction, String cFile, ;
   String cParam, String cDirectory, Integer nShow

lc_DocFile = 'D:\Temp\PDF_Test.pdf'
If (ShellExecute( 0, 'Open', lc_DocFile, Null, Null, 1 ) > 32)

   ** Pause a moment before initializing
   ** If DDE cannot connect give it more time.
   Sleep( 200 )

   lo_AcroReader = CreateObject( 'clsReader', 'AcroView', 'Control' )
   If (type('lo_AcroReader') == 'O')
      With lo_AcroReader
         .cPdfFile = lc_DocFile
         If .OpenDoc()
            Sleep( 1000 )   && Pause a second to watch the page changing
            .GoToPage( 4 )
            .PrintDoc( .T. )
            .CloseDoc()
         else
            MessageBox( 'Open document failed', 16, 'PDF Open' )
         endif
         .ExitAcrobat()
      EndWith

      lo_AcroReader = Null
      Release lo_AcroReader
   else
      MessageBox( 'Error DDE initiating', 16, 'DDE Error' )
   endif
endif

Clear class clsReader
Clear Dlls


*** Acrobat Reader Class Wrapper
*** ----------------------------
Define class clsReader as Custom
   cPdfFile = ''
   nChannel = -1

   Procedure Init( tc_Service, tc_Topic )
      Local ll_Safety

      ll_Safety = DDESetOption( 'Safety' )
      DDESetOption( 'Safety', .F. )
      This.nChannel = DDEInitiate( tc_Service, tc_Topic )
      DDESetOption( 'Safety', ll_Safety )

      Return (This.nChannel != -1)
   EndProc


   Procedure OpenDoc
      Local ll_Success

      With This
         If !empty( .cPdfFile )
            ll_Success = DDEExecute( .nChannel, '[DocOpen("' + .cPdfFile + '")]' )
         endif
      EndWith

      Return ll_Success
   EndProc


   Procedure GoToPage( tn_PageNo )
      Local ll_Success, lc_StrQuery

      With This
         If !empty( .cPdfFile )
            lc_StrQuery = '[DocGoTo("' + alltrim( .cPdfFile ) + '",' + ;
               transform( tn_PageNo-1 ) + ')]'
            ll_Success = DDEExecute( .nChannel, lc_StrQuery )
         endif
      EndWith
      Return ll_Success
   EndProc


   Procedure PrintDoc( tl_Silent )
      Local ll_Success, lc_StrQuery

      With This
         If !empty( .cPdfFile )
            If tl_Silent
               lc_StrQuery = '[FilePrintSilent("' + .cPdfFile + '")]'
            else
               lc_StrQuery = '[FilePrint("' + .cPdfFile + '")]'
            endif

            If DDEExecute( .nChannel, lc_StrQuery )
               Sleep( 50 )
               ll_Success = .T.
            endif
         endif
      EndWith

      Return ll_Success
   EndProc


   Procedure CloseDoc
      Local ll_Success

      With This
         If !empty( .cPdfFile )
            If DDEExecute( .nChannel, '[DocClose("' + .cPdfFile + '")]' )
               Sleep( 10 )
               ll_Success = .T.
            endif
         endif
      EndWith

      Return ll_Success
   EndProc


   Procedure ExitAcrobat
      Local ll_Success

      If DDEExecute( This.nChannel, '[AppExit()]' )
         Sleep( 10 )
         ll_Success = DDETerminate( This.nChannel )
      endif

      Return ll_Success
   EndProc
EndDefine
Regards


>Can this be used in VFP? If so, how?
>
>*------------------------------------------------------------------------
>Introduction
>Acrobat Reader can't be driven using Automation. Only few restrictive DDE messages has been defined by adobe to control reader from outside.
>This class maps some usefull DDE messages that will allow you open, seek, print and close a file in acrobat.
>
>BackgroundBackground
>The DDE message description can be downloaded from the Adobe web site (IACReference.pdf)
>
>Using the code
>Using the class is simple :
>
>//
>#include "ReaderWrapper.h"
>
>    // This will instanciate a new object
>    CReaderWrapper ReaderDemo("d:\\test.pdf");
>
>    // Open your document inside acrobat
>    ReaderDemo.DocOpen();
>
>    //Seek display to page 4
>    ReaderDemo.GoToPage(4);
>
>    //Print the file without displaying any modal dialog box
>    ReaderDemo.FilePrintSilent();
>
>    //Close the document
>    ReaderDemo.DocClose();
>
>    //Exit reader
>    ReaderDemo.ExitAcrobat();
>//
>
>
>
>// ReaderWrapper.cpp: implementation of the CReaderWrapper class.
>//
>//////////////////////////////////////////////////////////////////////
>
>#include "stdafx.h"
>#include "sstpdf2.h"
>#include "ReaderWrapper.h"
>
>
>#ifdef _DEBUG
>#undef THIS_FILE
>static char THIS_FILE[]=__FILE__;
>#define new DEBUG_NEW
>#endif
>
>
>/*************************************************************************
>
>  -------------------------------------
>
>* Software: CReaderWrapper                                                     *
>* Version:  1.1						                                           *
>* Date:     2004-11-09			                                               *
>*                                                                              *
>* You may use, modify and redistribute this software as you wish.              *
>
>**************************************************************************
>
>						OVERVIEW
>
>  This class uses DDE messages to communicate with acrobat reader (or acrobat)
>  Most of usefull DDE messages have been wrapped into that class.
>  Acrobat DDE messages are described in the adobe document called IACReference.pdf
>  (this document can be downloaded inside the ADOBE SDK)
>
>**************************************************************************
>
>*************************************************************************/
>
>//////////////////////////////////////////////////////////////////////
>// Construction/Destruction
>//////////////////////////////////////////////////////////////////////
>
>HDDEDATA CALLBACK DdeCallback(
>    UINT uType,     // Transaction type.
>    UINT uFmt,      // Clipboard data format.
>    HCONV hconv,    // Handle to the conversation.
>    HSZ hsz1,       // Handle to a string.
>    HSZ hsz2,       // Handle to a string.
>    HDDEDATA hdata, // Handle to a global memory object.
>    DWORD dwData1,  // Transaction-specific data
>	DWORD dwData2)  // Transaction-specific data.
>{
>    return 0;
>}
>
>CReaderWrapper::CReaderWrapper(CString stPdfFile)
>{
>	this->stPdfFileName=stPdfFile;
>	this->dwIdInst=0;
>	this->hConv=0;
>
>	/*DDE initialisation process*/
>
>	
>    UINT iReturn;
>
>    iReturn = DdeInitialize(&this->dwIdInst, (PFNCALLBACK)DdeCallback,
>                            APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 );
>
>	ASSERT(iReturn==DMLERR_NO_ERROR);
>
>
>}
>
>CReaderWrapper::~CReaderWrapper()
>{
>
>	/*Disconnect */
>	if(this->hConv)
>		DdeDisconnect(this->hConv);
>
>	if(this->dwIdInst)
>		DdeUninitialize(this->dwIdInst);
>
>
>}
>
>/*Open the pdf file in acrobat reader*/
>void CReaderWrapper::DocOpen()
>{
>
>HINSTANCE hRet;
>	
>	/*Start the DDE server*/
>	hRet = ShellExecute(0, "open", (LPCTSTR)this->stPdfFileName, 0, 0, SW_SHOWNORMAL);
>    ASSERT((int)hRet >= 33);
>
>	/*Connect to server*/
>	HSZ hszApp, hszTopic;
>	char szApp[] = "acroview";
>	char szTopic[] = "control";
>
>
>	hszApp = DdeCreateStringHandle(this->dwIdInst, szApp, 0);
>    hszTopic = DdeCreateStringHandle(this->dwIdInst, szTopic, 0);
>
>	this->hConv = DdeConnect(this->dwIdInst, hszApp, hszTopic, NULL);
>
>	DdeFreeStringHandle(this->dwIdInst, hszApp);
>    DdeFreeStringHandle(this->dwIdInst, hszTopic);
>	
>	if (this->hConv == NULL)
>    {
>        printf("DDE Connection Failed.\n");
>        Sleep(1500);
>		DdeUninitialize(this->dwIdInst);
>
>    }
>
>	/*DDE message DocOpen MUST be send first before using other messages*/
>CString stCmdLine;
>
>	stCmdLine="";
>
>	stCmdLine.Format("[DocOpen(\"%s\")]",this->stPdfFileName);
>	
>	this->_ExecuteQuery(stCmdLine);
>
>
>}
>
>/*Open the pdf file in acrobat reader*/
>void CReaderWrapper::CloseAllDocs()
>{
>
>CString stCmdLine;
>
>	stCmdLine="[CloseAllDocs]";
>	this->_ExecuteQuery(stCmdLine);
>}
>
>/*Close the current document*/
>void CReaderWrapper::DocClose()
>{
>
>CString stCmdLine;
>
>	stCmdLine="";
>	stCmdLine.Format("[DocClose(\"%s\")]",this->stPdfFileName);
>	this->_ExecuteQuery(stCmdLine);
>}
>
>void CReaderWrapper::ExitAcrobat()
>{
>
>CString stCmdLine;
>
>	stCmdLine="[AppExit()]";
>	this->_ExecuteQuery(stCmdLine);
>
>}
>
>
>void CReaderWrapper::GoToPage(int iPage)
>{
>
>CString stCmdLine;
>
>	stCmdLine="";
>
>	stCmdLine.Format("[DocGoTo(\"%s\",%i)]",this->stPdfFileName,iPage-1);
>	this->_ExecuteQuery(stCmdLine);
>
>}
>
>void CReaderWrapper::FilePrint()
>{
>
>CString stCmdLine;
>
>	stCmdLine="";
>
>	stCmdLine.Format("[FilePrint(\"%s\")]",this->stPdfFileName);
>	this->_ExecuteQuery(stCmdLine);
>
>}
>
>void CReaderWrapper::FilePrintSilent()
>{
>
>CString stCmdLine;
>
>	stCmdLine="";
>
>	stCmdLine.Format("[FilePrintSilent(\"%s\")]",this->stPdfFileName);
>	this->_ExecuteQuery(stCmdLine);
>
>}
>
>/*Private methods*/
>void CReaderWrapper::_ExecuteQuery(CString stQuery)
>{
>
>HDDEDATA hData=NULL;
>
>	hData = DdeCreateDataHandle(this->dwIdInst, (LPBYTE)(LPCTSTR)stQuery,
>                               stQuery.GetLength()+1, 0, NULL, CF_TEXT, 0);
>    if (hData==NULL)
>	{
>        printf("Command failed: %s\n", (LPCTSTR)stQuery);
>    }
>    else
>	{
>        DdeClientTransaction((LPBYTE)hData, 0xFFFFFFFF, this->hConv, 0L, 0,
>                             XTYP_EXECUTE, TIMEOUT_ASYNC, NULL);
>    }
>
>}
>
Herman
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform