*:*************************************************************************** *: Procedure file: ACORDPRT.PRG *:*************************************************************************** * Purpose: Prints Acord PDF Forms * Reqmts: li_acord must be .t. (licensed for acord forms) * li_acordview for preview and printer selection by ctrl-p * Usage: llreturn = acordprt([formnumber]) * llreturn = acordprt("61NC") *:************************************************************************** PARAMETERS xacordform IF TYPE('xacordform')<>"C" .OR. EMPTY(xacordform) RETURN .F. ENDIF IF TYPE('li_acord')<>"L" .OR. !li_acord && no acord license RETURN .F. ENDIF IF TYPE('li_acordview')<>"L" RETURN .F. ENDIF IF TYPE('dopass') ="U" dopass = .F. && do not process password on acord pdf forms ENDIF PRIVATE acordalias, tempfile, pdffile, lcsetsafety, xreturn acordalias = ALIAS() tempfile = hdir+xacordform+'.xfdf' pdffile = hdir+xacordform+'.pdf' lcsetsafety = SET('SAFETY') xreturn = .F. SET SAFETY OFF IF FILE(pdffile) && .pdf file DELETE FILE (pdffile) ENDIF IF FILE(tempfile) && .xfdf file DELETE FILE (tempfile) ENDIF *---Open Tables IF UseFile("ACORDEFN",ddir) IF UseFile("ACORDICT",ddir) DO AcordGen DO AcordExe ENDIF ENDIF *---Close Tables IF USED("ACORDICT") && holds acord/policy profiler data dictionary USE IN ACORDICT ENDIF IF USED("ACORDEFN") && holds field definitions USE IN ACORDEFN ENDIF IF !EMPTY(acordalias) .AND. ALIAS() <> acordalias SELECT (acordalias) ENDIF IF !EMPTY(lcsetsafety) SET SAFETY &lcsetsafety ENDIF *---Cleanup IF FILE(pdffile) && .pdf file DELETE FILE (pdffile) ENDIF IF FILE(tempfile) && .xfdf file DELETE FILE (tempfile) ENDIF RETURN xreturn *---------------------------------------------------------------------- PROCEDURE AcordGen *---Select Fields SELECT Acordefn.formname, Acordefn.formfield, Acordefn.formorder,; Acordict.profiler, 01 AS starttag, 00 AS endtag; FROM ; acordefn ; LEFT OUTER JOIN acordict ; ON Acordefn.formfield = Acordict.formfield; WHERE Acordefn.formname = ( xacordform ); ORDER BY Acordefn.formorder; INTO CURSOR Acordfields READWRITE SELECT Acordfields GOTO TOP PRIVATE m.output m.output = FCREATE(tempfile,0) IF m.output < 0 =MESSAGEBOX("Could not create '+tempfile+' Acord xml file.",0+16+4096,"ERROR") RETURN ENDIF *---Initialize local variables PRIVATE ifields, mfield, mvalue ifields = 1 mfield = '' mvalue = '' DIMENSION fNames[1], fTagNames[1] fNames = '' fTagNames = '' PRIVATE i, iRecCount, iRecNo, iFieldCount, iFieldNo iRecCount = RECCOUNT() *---Remove duplicate tags FOR iRecNo = 1 TO iRecCount GOTO iRecNo *---Expand field name mfield = Acordfields.formfield ifields = OCCURS('.', mfield) + 1 DIMENSION fNames[ifields] fNames = '' FOR i = 1 TO ifields IF OCCURS('.', mfield) > 0 fNames[i] = SUBSTR(mfield, 1, AT('.', mfield)) mfield = SUBSTR(mfield, AT('.', mfield)+1) ELSE fNames[i] = mfield mfield = '' ENDIF NEXT *---Initialize EndTag REPLACE AcordFields.endtag WITH ifields *---Step through the field names. Skip the last one iFieldCount = ifields - 1 FOR iFieldNo = 1 TO iFieldCount IF fNames[iFieldNo] = '*.' LOOP ENDIF GOTO iRecNo SKIP SCAN REST *---Expand field name mfield = Acordfields.formfield ifields = OCCURS('.', mfield) + 1 DIMENSION fTagNames[ifields] fTagNames = '' FOR i = 1 TO ifields IF OCCURS('.', mfield) > 0 fTagNames[i] = SUBSTR(mfield, 1, AT('.', mfield)) mfield = SUBSTR(mfield, AT('.', mfield)+1) ELSE fTagNames[i] = mfield mfield = '' ENDIF NEXT *---Check for Duplicates IF TYPE('fTagNames[iFieldNo]') <> 'U' IF fNames[iFieldNo] == fTagNames[iFieldNo] IF iFieldNo = 1 fTagNames[iFieldNo] = '*.' REPLACE Acordfields.starttag WITH Acordfields.starttag + 1 ELSE IF fTagNames[iFieldNo-1] = '*.' fTagNames[iFieldNo] = '*.' REPLACE Acordfields.starttag WITH Acordfields.starttag + 1 ENDIF ENDIF ELSE EXIT ENDIF ELSE EXIT ENDIF *---Save Record mfield = '' FOR i = 1 TO ifields IF !EMPTY(fTagNames[i]) mfield = mfield + fTagNames[i] ENDIF NEXT REPLACE Acordfields.formfield WITH mfield ENDSCAN NEXT *---Set EndTag GOTO iRecNo SKIP IF !EOF('Acordfields') ifields = OCCURS('*', AcordFields.formfield) SKIP -1 REPLACE AcordFields.endtag WITH AcordFields.endtag - ifields ENDIF NEXT *---Write Header =FWRITE(m.output, '<?xml version="1.0" encoding="UTF-8"?>'+CHR(10)) =FWRITE(m.output, '<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">'+CHR(10)) =FWRITE(m.output, '<f href="'+xacordform+'.pdf"/>'+CHR(10)) =FWRITE(m.output, '<fields>'+CHR(10)) *---Loop through records GOTO TOP SCAN *---Expand field name mfield = Acordfields.formfield ifields = OCCURS('.', mfield) + 1 DIMENSION fNames[ifields] fNames = '' FOR i = 1 TO ifields IF OCCURS('.', mfield) > 0 fNames[i] = SUBSTR(mfield, 1, AT('.', mfield)-1) mfield = SUBSTR(mfield, AT('.', mfield)+1) ELSE fNames[i] = mfield mfield = '' ENDIF NEXT *---Write Tags FOR i = 1 TO ifields IF i >= Acordfields.starttag =FWRITE(m.output, '<field name="'+RTRIM(fNames[i])+'">'+CHR(10)) ENDIF NEXT *---Write Value mvalue = '' *--TCH 04/12/2004 check for no value *--TCH 05/06/2004 check for .null. value IF !ISNULL(AcordFields.profiler) .and. !EMPTY(ALLTRIM(Acordfields.profiler)) mvalue = EVALUATE(Acordfields.profiler) ENDIF *--TCH 05/05/2004 Strip out reserved words in xml to avoid parsing errors *--for example the & in Carrier or Agency name, etc. mvalue = XmlEncode(mvalue) =FWRITE(m.output, '<value>'+RTRIM(mvalue)+'</value>'+CHR(10)) *---Write End Tags of Last record FOR i = 1 TO Acordfields.endtag =FWRITE(m.output, '</field>'+CHR(10)) NEXT ENDSCAN *---Write Footer and close the file =FWRITE(m.output, '</fields>'+CHR(10)) =FWRITE(m.output, '</xfdf>'+CHR(10)) =FCLOSE(m.output) USE IN Acordfields RETURN *---------------------------------------------------------------------- PROCEDURE AcordExe PRIVATE cAppName, lcresult, lcline, llacordok, lcACORDdef PRIVATE lnpos, lcpath, lcshort cAppName = '' lcresult = '' lcline = '' llacordok = .T. lcACORDdef = SYS(5)+SYS(2003) lnpos = 0 lcshort = '' lcpath = '' IF FILE(tempfile) IF UseFile("ACORDFRM",ddir,"FORMNAME") IF INDEXSEEK(UPPER(ALLTRIM(xacordform)),.T.,'ACORDFRM','FORMNAME') =STRTOFILE(ACORDFRM.FORMDATA,pdffile) ELSE =MESSAGEBOX("Cannot locate form:"+UPPER(ALLTRIM(xacordform))+" in forms table.",0+16+4096,"ERROR - Form Missing in Form Table.") ENDIF USE IN ACORDFRM 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) ELSE llacordok = ExeWait( m.cAppName, lcline+xacordform+'.xfdf',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 ELSE =MESSAGEBOX("Unable to create Acord Form.",0+16+4096,"ERROR - PDF or XFDF Missing.") ENDIF ELSE =MESSAGEBOX("Unable to create Acord Form.",0+16+4096,"ERROR - PDF or XFDF Missing.") ENDIF xreturn = .T. RETURN *---PROCEDURE BELOW SHOULD BE PART OF A CLASS *---Create ShowMessage method for using the MESSAGEBOX. *---------------------------------------------------------------------- PROCEDURE DECLexewait && load required dlls for exewait function =ADLLS(dllarray) 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_CLASSES_ROOT nKey = HKEY_LOCAL_MACHINE *nKey = HKEY_CURRENT_USER *cSubKey = "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" *cSubKey = "Applications\AcroRd32.EXE\Shell\Open\command" 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 * nKey The root key to open. It can be any of the constants defined below. * #DEFINE HKEY_CLASSES_ROOT -2147483648 * #DEFINE HKEY_CURRENT_USER -2147483647 * #DEFINE HKEY_LOCAL_MACHINE -2147483646 * #DEFINE HKEY_USERS -2147483645 * cSubKey The SubKey to open. * cValue The value that is going to be read. * Constants that are needed for Registry functions * #DEFINE REG_SZ 1 * WIN 32 API functions that are used 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 *---------------------------------------------------------------------- FUNCTION PassWin PARAMETER tcTitle * Routine which sees if an application is active by looking for its * Window title * expC1 Window title DECLARE INTEGER FindWindow IN Win32API AS FindWindow STRING, STRING lnwindow = FindWindow(0,tcTitle) IF lnwindow > 0 #DEFINE WM_SETFOCUS 0x0007 #DEFINE KEYEVENTF_KEYUP 2 #DEFINE VK_SHIFT 0x10 DECLARE SHORT PostMessage IN user32; INTEGER HWND,; INTEGER Msg,; STRING wParam,; INTEGER LPARAM DECLARE INTEGER SetForegroundWindow IN Win32API; INTEGER HWND DECLARE INTEGER SetActiveWindow IN Win32API; INTEGER HWND DECLARE keybd_event IN Win32API; INTEGER bVk, INTEGER bScan,; INTEGER dwFlags, INTEGER dwExtraInfo HWND = lnwindow ReturnValue = PostMessage(HWND, WM_SETFOCUS, 0, 0) lcsentence = "~PASSWORD"+CHR(13) && change to valid form password = SetActiveWindow(HWND) = SetForegroundWindow(HWND) FOR Lni = 1 TO LEN(lcsentence) lcchar = SUBSTR(lcsentence, Lni, 1) IF lcchar <> "~" llshift = ISUPPER(lcchar) lnchar = ASC(UPPER(lcchar)) IF llshift = keybd_event(VK_SHIFT, 0, 0, 0) ENDIF = keybd_event(lnchar, 0, 0, 0) = keybd_event(lnchar, 0, KEYEVENTF_KEYUP, 0) IF llshift = keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0) ENDIF ELSE lnchar = 192 = keybd_event(VK_SHIFT, 0, 0, 0) = keybd_event(lnchar, 0, 0, 0) = keybd_event(lnchar, 0, KEYEVENTF_KEYUP, 0) = keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0) ENDIF NEXT CLEAR DLLS PostMessage CLEAR DLLS SetForegroundWindow CLEAR DLLS SetActiveWindow CLEAR DLLS keybd_event CLEAR DLLS FindWindow RETURN .T. ELSE CLEAR DLLS FindWindow RETURN .F. ENDIF *---------------------------------------------------------------------- PROCEDURE stopadobe PARAMETERS hThread DECLARE Sleep IN kernel32 INTEGER dwMilliseconds DO WHILE !Passwin('Password') .and. lnclosepass < 10 lnclosepass = lnclosepass + 1 =SLEEP(300) ENDDO =Sleep(5000) *DECLARE INTEGER TerminateThread IN WIN32API INTEGER hThread, INTEGER uExitCode *=TerminateThread(hThread,99) *RETURN LOCAL awin_apps, vfp_handle, ln_current_window,ln_window_count * Dimension array awin_apps to store running apps DIMENSION awin_apps[1,2] * Initialize variable to store handle for current application vfp_handle=0 * Declare API Functions DECLARE INTEGER FindWindow ; IN win32api ; INTEGER nullpointer, ; STRING cwindow_name DECLARE INTEGER GetWindow ; IN win32api ; INTEGER ncurr_window_handle, ; INTEGER ndirection DECLARE INTEGER GetWindowText ; IN win32api ; INTEGER n_win_handle, ; STRING @ cwindow_title, ; INTEGER ntitle_length * End of API function declarations * Get handle for current application vfp_handle=FindWindow(0,_SCREEN.CAPTION) * Store handle of current app to a variable ln_current_window=vfp_handle * Initialize a count variable used to dimension array of running apps ln_window_count=0 DO WHILE ln_current_window>0 * Initialize variable to store application title lc_window_title=SPACE(255) * Call to GetWindowText to fetch window caption ln_length=GetWindowText(ln_current_window, ; @lc_window_title,LEN(lc_window_title)) * Note that the lc_window_title variable is used as a buffer to * receive text from the call to GetWindowText IF ln_length>0 lc_window_title=STRTRAN(TRIM(lc_window_title),CHR(0),"") ELSE lc_window_title="" ENDIF IF ln_current_window>0 .AND. !EMPTY(lc_window_title) * Increment the window count and re-dimension the array of running * applications ln_window_count=ln_window_count+1 DIMENSION awin_apps(ln_window_count,2) awin_apps[ln_Window_Count,1]=lc_window_title awin_apps[ln_Window_Count,2]=ln_current_window ENDIF * Call to GetWindow to fetch handle of running applications. ln_current_window=GetWindow(ln_current_window,2) ENDDO PRIVATE it FOR it = 1 TO ALEN(awin_apps,1) IF "Adobe" $ awin_apps(it,1) IF TYPE('awin_apps(it,2)')="N" =close2(awin_apps(it,2)) ENDIF ENDIF ENDFOR RETURN .T. *---------------------------------------------------------------------- PROCEDURE close2 PARAMETERS HWND #DEFINE WM_CLOSE 16 #DEFINE WM_SETFOCUS 0x0007 DECLARE SHORT PostMessage IN user32; INTEGER HWND,; INTEGER Msg,; STRING wParam,; INTEGER LPARAM DECLARE INTEGER SetForegroundWindow IN Win32API; INTEGER HWND DECLARE INTEGER SetActiveWindow IN Win32API; INTEGER HWND =PostMessage(HWND, WM_SETFOCUS, 0, 0) =PostMessage(HWND, WM_CLOSE, 0, 0) RETURN .T. *----------------------------------------------------------------------- FUNCTION XmlEncode LPARAMETERS teExpression *-- Transfrom 5 Known reserved XML characters only LOCAL lcReturn lcReturn = TRAN(teExpression) IF VARTYPE(teExpression) = 'C' lcReturn = ALLTRIM(lcReturn) lcReturn = STRTRAN(lcReturn, '&', '&') lcReturn = STRTRAN(lcReturn, '<', '<') lcReturn = STRTRAN(lcReturn, '>', '>') lcReturn = STRTRAN(lcReturn, '"', '"') lcReturn = STRTRAN(lcReturn, "'", ''') ENDIF RETURN lcReturn *------------------------------------------------------------------------- FUNCTION XMLDeCode LPARAMETERS cTXT LOCAL i,ch FOR i=1 TO 255 ch=ALLTRIM(STR(i)) cTXT=STRTRAN(cTXT,"&#"+ch+";",CHR(i)) ENDFOR RETURN cTXT>Hi again Tracy,