May 17, 2009

Syntax checking on e-mail addresses

You can use the following code to validate e-mail addresses in your Foxpro applications.

* Procedure validatemail([emailaddress])

PARAMETERS pEmail

LOCAL cDomains, cPiece, cMessage, cNum, lDomain, lemailname

pEmail = LOWER(ALLTRIM(pEmail))
cMessage = ""
lDomain = .t.
lEmailname = .t.

IF !EMPTY(pEmail)

cdomains = '"aero", "asia", "biz", "cat", "com", "coop", ' +;
'"edu", "gov", "info", "int", "jobs", "mil", "mobi", "museum", ' +;
'"name", "net", "org", "pro", "tel", "travel"'

* some extra checks which are not tackled below
IF ".." $ pemail OR "@." $ pemail OR ".@" $ pemail && missing pieces between dots and pigtail
lEmailname = .f.
ENDIF
IF NOT "@" $ pEmail && no pigtail
lEmailname = .f.
ENDIF
IF OCCURS("@", pemail) > 1 && multiple pigtails
lEmailname = .f.
ENDIF

* check the emailname
cPiece = LEFT(pEmail, AT("@", pEmail)-1)
IF EMPTY(cPiece)
lEmailname = .f.
ELSE
FOR i = 1 TO LEN(cPiece)
cNum = ASC(SUBSTR(cPiece,i,1))
* A to Z, 0 to 9, ! to /
IF between(cNum, 97,122) OR;
between(cNum, 48,57) OR;
between(cNum, 33,47)
ELSE
lEmailname = .f.
ENDIF
ENDFOR
ENDIF

* check the domain name
cPiece = SUBSTR(pEmail, RAT("@", pEmail)+1)
IF EMPTY(cPiece) && empty
lDomain = .f.
ELSE
IF LEN(cPiece) < 4 && domain name to short
lDomain = .f.
ENDIF

cPiece = SUBSTR(pEmail, RAT(".", pEmail)+1)
IF LEN(cPiece) < 2 && part after the last dot to short
lDomain = .f.
ENDIF
IF LEFT(pEmail,1) $ "." && begins with a dot
lDomain = .f.
ENDIF

FOR i = 1 TO LEN(cPiece)
cNum = ASC(SUBSTR(cPiece,i,1))
* A to Z, 0 to 9, ! to /
IF between(cNum, 97,122) OR;
between(cNum, 48,57) OR;
between(cNum, 33,47)
ELSE
lDomain = .f.
ENDIF
ENDFOR

IF LEN(cPiece) > 2 && top level domain
IF NOT '"' + cPiece + '"' $ cdomains && no top level domain
lDomain = .f.
ENDIF
ELSE
* If you have a list with all the country codes, you could check them here...
ENDIF
ENDIF
ENDIF

RETURN (lEmailname = .T. AND lDomain = .T.)

Mar 7, 2009

An application-wide hourglass

When your users are waiting for your application to complete some task, it's nice to show them the hourglass mousepointer as an indication. You can easily set the mousepointer property of the active form, but when the user moves the mouse outside of it, the mousepointer changes to the arrowhead again and that's not how it should be.
The following code changes the mousepointer for all the forms in your application.
Put the code in a .PRG file and (very important!) name it MAUSER, because that was what Richard and I named it originally.
The reason for that is, that at the moment we were thinking about how to name this function, our friend Maurits walked in the room and 'Maus' is what we call him for short. Also 'maus' is the German word for mouse.

Activating and deactivating the hourglass is as simple as putting =MAUSER(.T.) and =MAUSER(.F.) around the piece of code that takes a while to execute.


PARAMETERS lZetAan

LOCAL nFormTeller

FOR nFormTeller = 1 TO _Screen.FormCount
_Screen.Forms(nFormTeller).SetAll("MousePointer",IIF(lZetAan,11,0))
_Screen.Forms(nFormTeller).MousePointer = IIF(lZetAan,11,0)
NEXT
_Screen.SetAll("MousePointer",IIF(lZetAan,11,0))

_Screen.MousePointer = IIF(lZetAan,11,0)
IF TYPE("_Screen.Activeform.Name") = "C"
_Screen.Activeform.SetAll("MousePointer",IIF(lZetAan,11,0))
ENDIF