Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
ReaderWrapper to control Adobe Reader - Use in VFP?
Message
From
13/12/2004 12:41:10
 
 
To
13/12/2004 11:06:53
General information
Forum:
Visual FoxPro
Category:
COM/DCOM and OLE Automation
Environment versions
Visual FoxPro:
VFP 8 SP1
OS:
Windows XP
Network:
Windows XP
Database:
Visual FoxPro
Miscellaneous
Thread ID:
00968303
Message ID:
00968812
Views:
10
>I got code working that launches the pdf in Adobe Reader (createprocess with the /p) and displays the print dialog box but when the user clicks on Print or Cancel Adobe Reader is still open of course. I suspend processing in VFP (getexitcodeprocess) while Adobe Reader is open which will not work in this case the way I want it to. The user is forced to manually close Adobe Reader after printing or clicking on cancel or else the vfp app remains suspended because it is looking for the Adobe Reader process to quit. Ideally I would:
>
>1. Launch the pdf in Adobe Reader nonvisual and automatically launch the print dialog window. ->DONE
>2. Suspend processing in VFP until the Adobe process exists. ->DONE
>3. When the user clicks on Print or Cancel, EXIT ADobe Reader automatically. ->PROBLEM
>4. Return processing to VFP when the Adobe Reader process exits. ->DONE
>
>As you can see, item #3 is the problem unless I let the users be responsible for not only clicking on Print or Cancel in the Adobe Reader print dialog window, but also manually closing the reader afterwards so processing can return to VFP.
>
>Tracy

Sorry, a bit late. I did some more test. For the version 5 (the one I am using), the /h is to hide the splash screen. So it is fully working now. About sizing the windows, I can't give the code because it's in my full library (DLL), and it's company property. I am sorry for this. Just to let you know, I'm using Global-Hook. It's spying any windows on creating, moving, sizing, etc. I can do (almost) whatever I want from there.

However I created a VFP version, but it's kind of ugly <g>
Also for solving item #3 I use the callback function that is provided with DDEExecute. Again, this only works without /p on my machine. Here it goes:
Private pl_Completed
Local lc_DocFile, lo_AcroReader, lc_Title

Declare Long SetWindowPos in User32 ;
   Long hWnd, Long hWndInsertAfter, ;
   Integer X, Integer Y, Integer cX, Integer cY, Long wFlags
Declare Long WaitForInputIdle in User32 ;
   Long hProcess, Long dwMilliseconds

Set procedure to sys(16) additive
If (CreateProcess(...) > 0)
   WaitForInputIdle( hProcess, 5000 )  && Wait for 5 seconds or idle time
   lo_AcroReader = CreateObject( 'clsAcroReader', '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 )

            lc_Title = JustFName( lc_DocFile )
            lc_Title = lc_Title + replicate(chr(0), 128-len(lc_Title))
            .hWndAdobe = FindWTitle( @lc_Title, 0, 0 )

            pl_Completed = .F.
            If .PrintDoc()
               Wait 'Printing dialog...' window nowait noclear
               Do while !pl_Completed
                  Sleep( 3 )
               enddo
            endif
            Wait 'Printing in progress...' window nowait
            .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

   Clear class clsAcroReader
endif

Set procedure to
Clear Dlls
Close all
Clear all


Procedure OnPrintDialog
LParameters tn_Channel, tc_Action, tc_Item, tc_Data, tn_Format, tn_TransactionNo

   If (tc_Action == 'XACTCOMPLETE')
      pl_Completed = .T.
   endif
EndProc


*** Acrobat Reader Class Wrapper
*** ----------------------------
Define class clsAcroReader as Custom
   cPdfFile = ''
   nChannel = -1
   cService = ''
   cTopic = ''
   .hWndAdobe = 0

   Procedure Init( tc_Service, tc_Topic )
      Local ll_Safety

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

         Return (.nChannel != -1)
      EndWith
   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_Command

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


   Procedure PrintDoc( tl_Silent )
      Local ll_Success, lc_Command

      With This
         If !empty( .cPdfFile )
            If tl_Silent
               lc_Command = '[FilePrintSilent("' + .cPdfFile + '")]'
            else
               lc_Command = '[FilePrint("' + .cPdfFile + '")]'
            endif
            ll_Success = (DDEExecute( .nChannel, lc_Command, 'OnPrintDialog' ) != -1)
            SetWindowPos( .hWndAdobe, -2, -500,-500,0,0, 0x10 )
         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

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

            If ll_Success
               ll_Success = DDETerminate( .nChannel )
            endif
         endif
      EndWith

      Return ll_Success
   EndProc
EndDefine
Hope you can find the workaround for ver 6.xx
Regards
Herman
Previous
Reply
Map
View

Click here to load this message in the networking platform