lcACORDdef = SYS(5)+SYS(2003) li_acordview = .T. hdir = 'c:\acordforms\finishedforms\' pdffile = hdir+'25.pdf' xacordform = '25' IF TYPE('dopass') ="U" dopass = .F. && do not process password on acord pdf forms ENDIF IF FILE(pdffile) DO DECLexewait *--Look for the file in known locations lcresult = Acrofind() IF EMPTY(lcresult) *--Look for AcroRd32.exe first in the registry lcresult = readregistrykey() IF OCCURS('"',lcresult)>0 IF TYPE('lcresult')="C" .AND. !EMPTY(lcresult) m.cAppName=SUBSTR(lcresult,2,AT('"',lcresult,2)-2) ELSE m.cAppName = '' ENDIF ELSE m.cAppName = lcresult+"AcroRd32.Exe" ENDIF ELSE m.cAppName = lcresult ENDIF IF FILE(m.cAppName) && AcroRd32.exe lcline = " /p /h " IF li_acordview && preview in acrobat reader so user can select printer by ctrl-p lcline = "" ENDIF SET DEFAULT TO LEFT(hdir,RAT("\",hdir)-1) lnpos=(RAT("\",m.cAppName)+1) && one position to the right of lcshort='' lcpath='' IF lnpos > 0 lcshort = UPPER(SUBSTR(m.cAppName,lnpos)) && grab from lnpos to end lcpath = UPPER(LEFT(m.cAppName,RAT("\",m.cAppName)-1)) && strip off the extension ENDIF IF !EMPTY(lcshort) .AND. !EMPTY(lcpath) lcpath = "'"+lcpath+"'" SET DEFAULT TO &lcpath *llacordok = ExeWait(lcshort,lcline+hdir+xacordform+'.xfdf',lcpath) llacordok = ExeWait(lcshort,lcline+hdir+xacordform+'.pdf',lcpath) ELSE *llacordok = ExeWait( m.cAppName, lcline+xacordform+'.xfdf',hdir) llacordok = ExeWait( m.cAppName, lcline+xacordform+'.pdf',hdir) ENDIF IF !llacordok =MESSAGEBOX("Unable to print Acord Form.",0+16+4096,"ERROR") ELSE WAIT WINDOW "Finished Printing" NOWAIT ENDIF SET DEFAULT TO &lcACORDdef ELSE =MESSAGEBOX('Unable to locate Acrobat Reader. Please install and try again',0+16+4096,'ERROR - Acrobat Reader Missing.') ENDIF DO RELexewait ENDIF RETURN *------------------- PROCEDURE DECLexewait && load required dlls for exewait function =ADLLS(dllarray) IF TYPE('dllarray')<>'A' DIMENSION dllarray(1) dllarray(1)='' ENDIF IF ASCAN(dllarray,'CREATEPROCESS') = 0 DECLARE INTEGER CreateProcess IN kernel32; INTEGER lpAppName, STRING lpCmdLine, INTEGER lpProcAttr,; INTEGER lpThrAttr, INTEGER bInhHandles, INTEGER dwCrFlags,; INTEGER lpEnvir, INTEGER lpCurDir, ; STRING @lpStInfo, STRING @lpProcInfo ENDIF IF ASCAN(dllarray,'GETLASTERROR') = 0 DECLARE INTEGER GetLastError IN kernel32 ENDIF IF ASCAN(dllarray,"CLOSEHANDLE") = 0 DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject ENDIF IF ASCAN(dllarray,"GETEXITCODEPROCESS") = 0 DECLARE INTEGER GetExitCodeProcess IN WIN32API INTEGER hProcess, INTEGER @lpExitCode ENDIF IF ASCAN(dllarray,"SLEEP") = 0 DECLARE Sleep IN kernel32 INTEGER dwMilliseconds ENDIF RETURN *---------------------------------------------------------------------- PROCEDURE RELexewait && release dlls for exewait function CLEAR DLLS CreateProcess CLEAR DLLS GetLastError CLEAR DLLS CloseHandle CLEAR DLLS GetExitCodeProcess CLEAR DLLS Sleep RETURN *---------------------------------------------------------------------- FUNCTION buf2dword(lcBuffer) RETURN ASC(SUBSTR(lcBuffer, 1,1)) + ; ASC(SUBSTR(lcBuffer, 2,1)) * 256 +; ASC(SUBSTR(lcBuffer, 3,1)) * 65536 +; ASC(SUBSTR(lcBuffer, 4,1)) * 16777216 *---------------------------------------------------------------------- FUNCTION readregistrykey #DEFINE HKEY_CLASSES_ROOT -2147483648 #DEFINE HKEY_CURRENT_USER -2147483647 #DEFINE HKEY_LOCAL_MACHINE -2147483646 #DEFINE HKEY_USERS -2147483645 #DEFINE REG_SZ 1 && String #DEFINE REG_BINARY 3 && Binary data #DEFINE REG_DWORD 4 && 32bits int #DEFINE ERROR_SUCCESS 0 && OK *Start of Code LOCAL nKey, cSubKey, cValue, cValueRead nKey = HKEY_LOCAL_MACHINE cSubKey = "Software\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe" cValue = "Path" cValueRead = ReadREG_SZ(nKey, cSubKey, cValue) IF EMPTY(cValueRead) cValueRead = '' ENDIF RETURN cValueRead *---------------------------------------------------------------------- FUNCTION ReadREG_SZ * This function reads a REG_SZ value from the registry. If successful, * it will return the value read. If not successful, it will return an empty string. PARAMETERS nKey, cSubKey, cValue DECLARE INTEGER RegOpenKey IN Win32API ; INTEGER nHKey, STRING @cSubKey, INTEGER @nResult DECLARE INTEGER RegQueryValueEx IN Win32API ; INTEGER nHKey, STRING lpszValueName, INTEGER dwReserved,; INTEGER @lpdwType, STRING @lpbData, INTEGER @lpcbData DECLARE INTEGER RegCloseKey IN Win32API INTEGER nHKey * Local variables used LOCAL nErrCode && Error Code returned from Registry functions LOCAL nKeyHandle && Handle to Key that is opened in the Registry LOCAL lpdwValueType && Type of Value that we are looking for LOCAL lpbValue && The data stored in the value LOCAL lpcbValueSize && Size of the variable LOCAL lpdwReserved && Reserved Must be 0 * Initialize the variables nKeyHandle = 0 lpdwReserved = 0 lpdwValueType = REG_SZ lpbValue = "" nErrCode = RegOpenKey(nKey, cSubKey, @nKeyHandle) * If the error code isn't 0, then the key doesn't exist or can't be opened. IF (nErrCode # 0) THEN RETURN "" ENDIF lpcbValueSize = 1 * Get the size of the data in the value nErrCode=RegQueryValueEx(nKeyHandle, cValue, lpdwReserved, @lpdwValueType, @lpbValue, @lpcbValueSize) * Make the buffer big enough lpbValue = SPACE(lpcbValueSize) nErrCode=RegQueryValueEx(nKeyHandle, cValue, lpdwReserved, @lpdwValueType, @lpbValue, @lpcbValueSize) =RegCloseKey(nKeyHandle) CLEAR DLLS RegOpenKey CLEAR DLLS RegQueryValueEx CLEAR DLLS RegCloseKey IF (nErrCode # 0) THEN RETURN "" ENDIF lpbValue = LEFT(lpbValue, lpcbValueSize - 1) RETURN lpbValue *---------------------------------------------------------------------- FUNCTION Acrofind PRIVATE WNetGetConnection, lpszLocalname, lpszRemoteName, ; sLen, Lni, DRIVE, Dtype, llfound, Lni PRIVATE ARRAY afilesfound(1,3) DIMENSION afilesfound(1,3) afilesfound(1,1)=" " llfound = .F. Lni = 0 DECLARE INTEGER WNetGetConnection IN win32api ; STRING lpszLocalName,; STRING lpszRemoteName,; INTEGER @ lpchBuffer && Declare the external WNetGetConnection ; API FUNCTION slpRemoteName = SPACE(254) && Initialize variables sLen = LEN(slpRemoteName) && Initialize variables *--Populate the one dimensional array with valid drive letters FOR I = 1 TO 26 && Loop through drive letters A thru Z DRIVE = CHR(I + 64) Dtype = DRIVETYPE(DRIVE) && Determine drive type DO CASE CASE Dtype = 3 && Hard drives Lni=Lni+1 DIMENSION adrivelist(Lni,3) adrivelist(Lni,1)=DRIVE adrivelist(Lni,2)=.F. adrivelist(Lni,3)=.F. CASE Dtype = 4 && Removable or network drives iSuccess = WNetGetConnection(DRIVE + ; ":",@slpRemoteName,@sLen) IF iSuccess = 0 Lni=Lni+1 DIMENSION adrivelist(Lni,3) adrivelist(Lni,1)=DRIVE adrivelist(Lni,2)=.F. adrivelist(Lni,3)=.F. ENDIF ENDCASE ENDFOR llfound = .F. FOR Lni = 1 TO ALEN(adrivelist,1) FOR ib = 10 TO 1 STEP -1 lcacrofile = adrivelist(Lni,1)+":"+"\Program Files\Adobe\Acrobat "+ALLTRIM(STR(ib))+".0\Reader\AcroRd32.Exe" IF FILE(lcacrofile) llfound = .T. EXIT ENDIF ENDFOR IF llfound EXIT ENDIF ENDFOR CLEAR DLLS WNetGetConnection IF llfound RETURN lcacrofile ELSE RETURN '' ENDIF *---------------------------------------------------------------------- *--Uses GetExitcodeProcess instead of waitforsingleobject PROCEDURE ExeWait (lcApp, lcCmdLine, lcdir) PRIVATE lntimes lntimes = 0 IF _VFP.AUTOYIELD = .F. llsetback = .T. ELSE llsetback = .F. ENDIF _VFP.AUTOYIELD = .T. PRIVATE lnclosepass lnclosepass = 0 #DEFINE INFINITE 0xFFFFFFFF LOCAL lcStartupInfo, lcProcInfo, hProcess, ; lnPrio, lnIBelieve1 lnIBelieve1 = 1 && Don't remember what that was lnPrio = 32 && Priority of Process=Normal lcStartupInfo = CHR(68) + REPLI(CHR(0), 67) lcProcInfo = REPLI(CHR(0), 16) IF CreateProcess(0, m.lcApp+" "+m.lcCmdLine+CHR(0), 0,0,; m.lnIBelieve1, m.lnPrio,; 0, 0, @lcStartupInfo, @lcProcInfo) <> 0 * process and thread handles returned in ProcInfo structure hProcess = buf2dword(SUBSTR(lcProcInfo, 1,4)) hThread = buf2dword(SUBSTR(lcProcInfo, 5,4)) * waiting until the termination of the program DOEVENTS IF !li_acordview && printing only DO stopadobe ELSE DO WHILE .T. exitcode = 0 && initialize return value to 0 = GetExitCodeProcess(hProcess, @exitcode) && try to obtain process exit code IF exitcode # 259 && not still busy EXIT && fall out of loop ELSE *--Attempt to close the password window up to 3 times IF dopass .AND. lnclosepass < 3 .AND. PassWin('Password') = Sleep (1000) && wait 1 seconds lnclosepass = lnclosepass + 1 ENDIF ENDIF = Sleep (100) && wait .1 seconds ENDDO ENDIF = CloseHandle(hThread) = CloseHandle(hProcess) ELSE IF llsetback _VFP.AUTOYIELD = .F. ENDIF RETURN .F. ENDIF IF llsetback _VFP.AUTOYIELD = .F. ENDIF RETURN