VFP: Execute latest (NL)

Foxpro nieuwste versie programma starten

Door jasperdg op 14 Feb 2008

In Visual Foxpro compileer je een programma naar een executable (.exe). Als echter het programma reeds in gebruik is (vele netwerk gebruikers), dan kan de nieuwe executable niet worden overschreven. Ik vind dat niet logisch, want alle gebruikers hebben het programma immers al in hun werkgeheugen staan, maar wie ben ik?

Mijn oplossing is om de executable te kopiƫeren en deze kopie uit te laten voeren. Uiteraard moet dit wel automatisch en transparant voor de gebruiker gebeuren. Dit is een verademing als je moet ontwikkelen in een netwerk omgeving.
Mocht een nieuwe release niet goed werken, dan kan je terug naar een werkende release door de desbetreffende versiekopie te kopieƫren naar de standaard executable.

* Gstarter: Starten van software 

 LPARAMETERS tcRelatie,tcTijd,tcPostcode,tcPlaats,tcPad
 IF VARTYPE(tcRelatie)<>[C] 
  tcRelatie = []
 ENDIF 
 lcProgramma = [q:\programmeren\vfp\synplan2007\synplan.exe]
 AGETFILEVERSION(laVersie, lcProgramma)
 lcVersie = laVersie(11)
 lcDoel = ADDBS(JUSTPATH(lcProgramma))+JUSTSTEM(lcProgramma)+lcVersie+[.]+JUSTEXT(lcProgramma)
 IF !FILE(lcDoel)
  COPY FILE (lcProgramma) TO (lcDoel)
 ENDIF 
 DO (lcDoel) WITH tcRelatie, lcVersie

Dit voorbeeld is iets ingewikkelder omdat er parameters moeten worden doorgegeven. Het programma heet “synplan.exe” en een kopie heet bijvoorbeeld “synplan1.0.3.exe”

VFP: Create Datetime

Foxpro convert date and time to DateTime variable

By jasperdg on Mar 13, 2008

On the net some silly, unusable answers have been posted where programmers just concatenate DTOC() and DATE(). This is wrong! The DTOC() function depends on local date settings, thus resulting string of characters can not be predicted.

That’s why I had to create this little function:

FUNCTION DTtoDateTime(ldDate,lcTime)
 RETURN DATETIME(YEAR(ldDate),MONTH(ldDate),DAY(ldDate),;
        VAL(LEFT(lcTime,2)),VAL(RIGHT(lcTime,2)))
ENDFUNC 

This function is independent to local date and time settings.

VFP: Hide mouse cursor

Hide Mouse Cursor in Visual Foxpro

Today I needed to hide the mouse cursor for a presentation program. Objects in VFP have a MousePointer property with which you can select the appearance of the cursor. 0 for default Windows behaviour, 1 to 17 for specific shapes like arrow (1) or hourglass (11) and 99 for Custom design. There is no “Hidden” appearance, No “MouseVisible” property. Shame.

What to do?

  1. Download the blank cursor.
  2. Next you select the forementioned 99 (custom) MousePointer value and
  3. last place the filename (Null.cur) in the MouseIcon field.

VFP: Correct week number

Calculate Week number correctly in Visual Foxpro

Silly Week() function in Foxpro doesn’t work like it should! The year 2009 was very long… So it had a week 53. I think here in Holland we use the method that the larger part of the week should be in the new year to call it week number one. (Silly me looked over the 3rd parameter. See the easy solution below under Update).

So according to the help on the Week() function we select nFirstWeek 2 (The larger half (four days) of the first week is in the current year.).

Foxpro Week(Date(2009,12,31),2) returns week 52! That is absolutely wrong. A search on the Internet brought me a solution that works for me. It was found on Fox Wiki. This is the very impressive code:

FUNCTION GetWeekNo
 LPARAMETERS ldDate
 lnJulian = VAL(SYS(11,ldDate))+1
 lnDay4 = MOD(MOD(MOD((lnJulian+31741 - MOD(lnJulian,7)),146097),36524),1461)
 lnLeap = INT(lnDay4/1460)
 lnDay1 = MOD(lnDay4-lnLeap,365) + lnLeap
 RETURN INT(lnDay1/7)+1
ENDFUNC

Thanks go to theRambler who proposed this on TekTips.

UPDATE

I stand corrected… Nard van Gentevoort emailed me to explain the VFP Week() function wil give me the right week number. But first I have tot tell it what day the week starts on. Silly Americans start the week on Sunday “at the seventh day he relaxed and saw all was good”.. doesn’t ring a bell? So because we do things right and start off our week at Monday, the full function call in the Netherlands should be: Week(date,2,2). Tested WEEK(DATE(2009,12,31),2,2) and it gives 53 like I expect it to. Thanks Nard !

VFP: Webpage to file

Read web content to a file

A Visual Foxpro function to read a web page’s content into a (cached) file.

UrlToFile.prg

LPARAMETERS tcRemote
 * URL reader from Fox Wiki site: http://fox.wikis.com/wc.dll?Wiki~ReadUrl~VFP
 * Accept URL
 * Return cached filename
 * Note: file gets deleted after first contact. So do filetostr() first! After file() it will be gone.
 LOCAL lnResult, lcTargetFile
 lcTargetFile = REPLICATE(CHR(0), 250)
 DECLARE INTEGER URLDownloadToCacheFile IN urlmon;
 INTEGER lpUnkcaller, STRING szURL, STRING @szFileName,;
 INTEGER dwBufLength, INTEGER dwReserved, INTEGER pBSC
 WAIT WINDOW NOWAIT "Downloading remote file..."
 lnResult = URLDownloadToCacheFile(0, tcRemote, @lcTargetFile,LEN(lcTargetFile), 0,0)
 WAIT CLEAR
 RETURN STRTRAN(lcTargetFile, Chr(0), "")

And wrapper UrlToStr.prg:

LPARAMETERS tcRemote
 * Wrapper for UrlToFile to read web content into a string
 LOCAL lcFile,lcResult
 lcFile = UrlToFile(tcRemote)
 lcResult = FILETOSTR( lcFile)
 RETURN lcResult

VFP: Fetch XML feed

Interpreting XML Feed in Visual Foxpro

Looking for ways to interpret XML files I stumbled on this article at the foxite.com forum. This was still way too difficult in my opinion. So I used the methods and created some lean code that does what I want in far less code.

This piece of program retrieves a feed from the Dutch public-services network and lists all items:

lcFeed = [http://feeds.livep2000.nl/]
lcFile = UrlToFile(lcFeed)

oXML = CREATEOBJECT("MSXML2.DOMDocument")
oXML.load(lcFile)
oItems = oXML.getElementsByTagName([item])
FOR EACH oItem IN oItems
 FOR EACH oLine IN oItem.childNodes
  ? oLine.nodeName+[: ]+oLine.text
 ENDFOR 
ENDFOR

VFP: Progress bar

VFP Progress bar using foundation class

Using the foundation class you can have a progress bar in no time. Hardest part is to locate the FFC folder, but most of the times it’s just beneath the vfp install program folder found with SYS(2004).

Half this code is for slowing down the demo:

* Progressbar with VFP Foundation Classes
* Source: https://degraafonline.com
* Free after Carl Warner's article at http://www.vfug.org/Newsletters/ThermometerBar.htm 

 lnPause = 2 && seconds between steps
 lcLibraryLocation = SYS(2004)+[FFC\]
 loTherm = NewObject([_thermometer],lcLibraryLocation+[_therm],[],[Progress Example])
 loTherm.Show
 =INKEY(lnPause,[HM])
 loTherm.Update(10) && just set the progress bar
 =INKEY(lnPause,[HM])
 loTherm.Update(20,[80 percent to go]) && set progress bar and show a subtitle
 =INKEY(lnPause,[HM])
 loTherm.Update(50,[half way])
 =INKEY(lnPause,[HM])
 loTherm.Complete([Ready])
 =INKEY(lnPause,[HM])
 loTherm.Release

VFP: Find IP by name

VfpNameLookup

For my network checks I want to ping some computers to see if they’re still active on my network. But before that, I have to lookup the IP numbers for the network names. Found this TekTips article on NSlookup from VFP6 and built my own function around the example.

* Lookup an IP number connected to a netwerk name
* (C)2011 Jasper de Graaf for J.A. Software
* Source: https://degraafonline.com 
* Inspiration from http://www.tek-tips.com/viewthread.cfm?qid=891380&page=338 

LPARAMETERS tcLookup && name to lookup

* No parameter, wrong type or empty 
IF PCOUNT()=0 OR !VARTYPE(tcLookup)=[C] OR EMPTY(tcLookup)
 ? [nslookup needs character parameter lookup network name or ip number]
 RETURN []
ENDIF 

* create scripting shell object and test
loShell = CreateObject("WScript.Shell")
IF VARTYPE(loShell)<>[O]
 ? [did not succeed in creating Wscript.Shell object]
 RETURN []
ENDIF 

* perform lookup and get results
loScriptExec = loShell.Exec("nslookup -debug "+tcLookup)
lcNsLookup = loScriptExec.StdOut.ReadAll()

IF AT([ANSWERS],lcNsLookup,2)>0 && we got a valid answer!
 lnIPpos = AT([Address:],lcNsLookup,2)+8
 lcNsIp = ALLTRIM(SUBSTR(lcNsLookup,lnIPpos))
ELSE
 lcNsIp = [] && could not resolve network name
ENDIF 

loScriptExec = null
loShell = null 
RETURN lcNsIp

VFP: Ping

Visual Foxpro: Ping an IP number and return weither it has responded. Uses Windows scripting shell.

* Ping function
* (C)2011 Jasper de Graaf for J.A. Software
* Source: https://degraafonline.com
LPARAMETERS tcIpNumber && IP number to ping

* No parameter, wrong type or empty 
IF PCOUNT()=0 OR !VARTYPE(tcIpNumber)=[C] OR EMPTY(tcIpNumber)
 ? [ping needs character parameter ip number (ie: "192.168.1.254")]
 RETURN []
ENDIF 

* create scripting shell object and test
loShell = CreateObject("WScript.Shell")
IF VARTYPE(loShell)<>[O]
 ? [did not succeed in creating Wscript.Shell object]
 RETURN []
ENDIF 

* perform short single ping and get results
loScriptExec = loShell.Exec("ping -n 1 -w 2 "+tcIpNumber)
lcPing = loScriptExec.StdOut.ReadAll()
llPing = ![time-out]$LOWER(lcPing)

loScriptExec = null
loShell = null 
RETURN llPing