>if IsClassRegistered("Word.Application") > declare long ShellExecute in "shell32.dll" ; > long hwnd, string lpszOp, ; > string lpszFile, string lpszParams, ; > string lpszDir, long nShowCmd > ShellExecute(0,'Open','winword.exe',0,0,1) >endif > >function IsClassRegistered >lparameters tcClass >#DEFINE HKEY_CLASSES_ROOT -2147483648 >#DEFINE ERROR_SUCCESS 0 && OK > >DECLARE Integer RegOpenKey IN Win32API ; > Integer nHKey, String @cSubKey, Integer @nResult > >DECLARE Integer RegCloseKey IN Win32API ; > Integer nHKey > >local lnKey >lnKey = 0 >llRetVal = ( RegOpenKey(HKEY_CLASSES_ROOT, tcClass, @lnKey) = ERROR_SUCCESS ) >if llRetVal > RegCloseKey(lnKey) >endif >return llRetVal >ShellExecute has an advantage in that you can even run it if the exe is renamed (but .doc associated). ie:
>StrToFile('','c:\temp\myDoc.doc') >ShellExecute(0,'Open','c:\temp\myDoc.doc',0,0,1) >Cetin
>>DO DECL >> >>lcwordsparm = "" >>*--Get the path to winword.exe from the registry >>lcwordpath=readregistrykey("Winword.Exe") >>IF TYPE('lcwordpath')<>"C" .or. EMPTY(lcwordpath) >> RETURN >>ENDIF >> >>lcwordsapp = lcwordpath+"WINWORD.EXE" >>lcwordsdir = LEFT(lcwordsapp,RAT("\",lcwordsapp)-1) >>lcwordsprg = "WINWORD.EXE" >>lcwordsdef = SYS(2003) >>SET DEFAULT TO LEFT(lcwordsapp,RAT("\",lcwordsapp)-1) >> >>*--Does the app exist? >>IF ADIR(laDummy, lcwordsapp)=1 >> *--Can we run it? >> llivansok = RunAndWait(lcwordsprg, lcwordsparm, lcwordsdir) >> CLEAR >> WAIT WINDOW "Finished Running Word. >>ENDIF >>RETURN >> >>*---------------------------------------------------------------------------------- >>PROCEDURE RunAndWait (lcApp, lcCmdLine, lcdir) >>#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 >> = WaitForSingleObject(hProcess, INFINITE) >> = CloseHandle(hThread) >> = CloseHandle(hProcess) >>ELSE >> RETURN .F. >>ENDIF >> >>*---------------------------------------------------------------------------------- >>PROCEDURE DECL >>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 >>DECLARE INTEGER GetLastError IN kernel32 >>DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject >>DECLARE INTEGER WaitForSingleObject IN kernel32; >> INTEGER hHandle, INTEGER dwMilliseconds >>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 >>RETURN >> >> >>*---------------------------------------------------------------------------------- >>FUNCTION readregistrykey >>LPARAMETERS qprogram >> >>#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 >> >>LOCAL nKey, cSubKey, cValue, cValueRead >>nKey = HKEY_LOCAL_MACHINE >>cSubKey = "Software\Microsoft\Windows\CurrentVersion\App Paths\"+qprogram >>cValue = "Path" >> >>cValueRead = ReadREG_SZ(nKey, cSubKey, cValue) >>IF (EMPTY(cValueRead)) THEN >> RETURN '' >>ELSE >> RETURN cValueRead >>ENDIF >> >>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) >>IF (nErrCode # 0) THEN >> RETURN "" >>ENDIF >> >>lpbValue = LEFT(lpbValue, lpcbValueSize - 1) >>RETURN lpbValue >>