Copyright 2009 by Jamal Mazrui
GNU Lesser General Public License (LGPL)
The word "Homer" is a brand name I sometimes use for developer tools I create. Homer.NET is a set of developer tools for the .NET platform. It supports rapid application development with many convenience functions for accessing Internet data, creating GUI forms, and using screen reader APIs. Development may be done with command-line utilities and a text editor -- no integrated development environment (IDE) is required.
I suggest unarchiving hnsetup.zip into a new directory, e.g.,
C:\Homer.NET
There are three assemblies that define types in the Homer namespace. HomerJax.dll defines the Jax class containing static methods for accessing Internet resources. HomerAcc.dll defines the Acc class containing static methods for producing speech through an active screen reader, and other accessibility-related tasks. HomerLbc.dll implements classes for creating Windows forms conveniently via "Layout by Code" rather than a visually-oriented designer.
The Lbc class has static methods for a variety of canned dialogs. The LbcForm class inherits from System.Windows.Forms.Form, and has instance methods and properties for adding controls to a form, which may be either a modal dialog or a modeless window. The LbcForm class and its members are used to build the canned dialogs of the Lbc class, thereby showing the power of this API and illustrating working code.
JaxForm.exe is an interpreter for source code files written in JScript .NET. Such code can access any of the Homer.NET functionality. JaxFormW.exe is a Windows-only version that does not use a console mode environment. That environment is useful when developing and debugging a .js script (e.g., the print function), but often not appropriate at the production stage.
Interactive JScript (InJs) is a REPL (read execute print loop) environment for testing JScript expressions, including functionality of Homer.NET. Load the program by running InJs.exe.
Batch files starting with the word "Compile" build the Homer.NET assemblies from source code using compilers provided with the .NET 2.0 SDK. Batch files beginning with the word "Run" execute a JScript .NET file dynamically. The .js files illustrate functionality of Homer.NET.
Samples of Homer.NET include compiled C# and VBNET fruit basket programs implemented with Layout by Code. A more sophisticated sample is executed with JaxForm via RunLbcDemo.bat. It includes a tip on the status line for each control and a menu system. All of this is done without any need to reference pixel coordinates for location or size. More specific layout information could be added if desired.
RunJaxDemo.bat illustrates HomerJax functionality, including how you can easily get the content type, source HTML, or plain text of a web page; how you can download a file to disk, how you can translate between languages via the Google API; how you can read recent RSS items from AccessibleWorld.org; how you can list MP3 files from AccessibleWorld.org; how you can get messages from the public timeline of Twitter.com, or poast a tweet if you have a Twitter account. The demo shows how data is converted from JavaScript Object Notation (JSON) to what I call COM exchange format, and how XML data may be conveniently accessed as well.
The functionality and documentation of Homer.NET will improve over time in response to comments, questions, and suggestions. Code contributions are also welcome.
The Component Object Model (COM) is a set of Windows standards by which different programming languages and applications can communicate. COM uses a flexible data type called a variant, which can be an individual value, array of values, or complex object with methods, properties, and events. In general, any COM client can use string, numeric, and COM objects as the data types of parameters or return values. Some, however, cannot use arrays. COM exchange format is intended to support collections, as well as primitive data types, for use by any COM client. Rather than an array, a list COM object is used from the .NET Framework (any version). A COM object dictionary is also used from the Windows Script Host.
HomerJax includes a method called JsToVt, which converts data in JSON format to variant types understood by VBScript (and any COM client language). JavaScript arrays are converted to COM objects with the progID "System.Collections.ArrayList." The methods and properties of this object are documented at
http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx
JavaScript objects, which are like dictionaries, are converted to COM objects with the progID "Scripting.Dictionary." This object is documented at
http://msdn.microsoft.com/en-us/library/x4k5wbx4(VS.85).aspx
In Visual Basic and other languages, either of these types of object collections may be iterated with the "For Each" statement. These objects have an "Item" method, which is the default COM method of the object, so syntax can succinctly referr to items without even using the "Item" keyword (just using an integer element of a list or string key of a dictionary enclosed in parentheses). The code of the demo program illustrates this in getting public messages from Twitter.
HomerJax includes various methods for converting between JavaScript Object Notation (JSON), variant data types, and COM exchange format. This provides much flexibility for accessing data on the Internet.
HomerJax is a library of convenience functions for accessing Internet resources. It is written in JScript, the Microsoft version of JavaScript, and is dependent on several COM servers distributed with Windows. The word "Jax" derives from Ajax, which originally meant "Asynchronous JavaScript and XML." Ajax technologies focus on building dynamic user interfaces in web browsers. HomerJax functions use some of these core technologies, but focus on reading, interpreting, and writing data from the Internet.
Since the Internet is a great source of accessible information for people with visual disabilities who cannot readily read the printed word, my hope is that this library makes it easier for developers, including blind ones like myself, to build applications that take advantage of new social networking sites such as Twitter, FaceBook, and many others. I intend for HomerJax to be accessible via various programming environments, including the Windows Script Host, screen reader scripting languages, and other programming languages via a COM server interface.
HomerJax methods are divided into categories indicated by a prefix at the beginning of their names: Dialog, File, Folder, Html, Js, Path, RegExp, Registry, String, Vt, Web, and Xml. By convention, HomerJax variable names use lower case prefixes to indicate the data type: s for string, i for integer, n for floating point number, l for list, d for dictionary, and o for other COM object. Method and variable names use upper camel case (like the .NET Framework), e.g., XmlGetValue rather than XMLGetValue. JavaScript is a case-sensitive language, so methods need to be called with appropriate capitalization.
Here is a summary of HomerJax methods:
DialogConfirm(sTitle, sMessage, sDefault) = Get choice from a standard Yes, No, or Cancel message box
DialogInput(sTitle, sField, sValue) = Get input from a single edit box
DialogShow(oTitle, oMessage) = Show string version of two parameters in the title && prompt of a message box
FileCopy(sSource, sTarget) = Copy source to destination file, replacing if it exists
FileDelete(sFile) = Delete a file if it exists, && test whether it is subsequently absent
either because it was successfully deleted || because it was!present in the first place
FileExists(sFile) = Test whether File exists
FileGetDate(sFile) = Get date of a file
FileGetSize(sFile) = Get size of a file
FileGetType(sFile) = Get file type
FileMove(sSource, sTarget) = Move source to destination file, replacing if it exists
FileToString(sFile) = Get content of text file
FolderCopy(sSource, sTarget) = Copy source to destination Folder, replacing if it exists
FolderCreate(sFolder) = Create folder
FolderDelete(sFolder) = Delete a Folder if it exists, && test whether it is subsequently absent
either because it was successfully deleted || because it was!present in the first place
FolderExists(sFolder) = Test whether folder exists
FolderGetDate(sFolder) = Get date of a Folder
FolderGetSize(sFolder) = Get size of folder, summing the sizes of files && subfolders it contains
FolderMove(sSource, sTarget) = Move source to destination Folder, replacing if it exists
HtmlEncodeString(sText) = Encode a string for HTML or XML
HtmlGetLinks(sUrl) = Get a list of two-item lists containing the URL and text of a link
HtmlGetTableText(sUrl, iTable) = Get the text of an HTML table specified by number, or null for all of them
HtmlGetText(sUrl) = Get the text of an HTML page
HtmlGetUrls(sUrl) = Get a list of URLs linked to a web page
JsDictionaryToEncodedString(d) = Convert dictionary to string with http encoding
var sReturn = ''
for (var sKey in d) = var sValue = d[sKey]
var sComponent = encodeURIComponent(sKey) + '=' + encodeURIComponent(sValue) = if (sReturn.length > 0) sReturn += '&'
sReturn += sComponent
}
return sReturn
} JsDictionaryToEncodedString method
JsEval(sCode, o1, o2, o3, o4) = Evaluate sCode, optionally referencing up to 4 parameters of any type, and return the result
JsInitArray(oValue, iLength) = var aReturn = []
for (var i = 0; i < iLength; i++) aReturn[i] = oValue
return aReturn
} JsInitArray method
JsIsBlank(sText) = Test if string is empty or white space
JsIsMute(o) = test for empty string
JsIsNull(o) = Test for null
JsIsObject(o) = Test for object
JsIsUndefined(o) = Test whether object is undefined
JSNumber(o) = Convert to JScript number
JsObjectToVt(oValue) = Convert JScript object to variant
JsPrint(o) = Print to screen using console mode of Windows Script Host
JsPrintObject(sName, oValue) = Print type of object and its subobjects
JsSplit(sText, sDelimiter) = Split but ensure an empty array for empty text
JsSplitLines(sText) = JsSplit by line feeds after chomping
JsString(o) = Convert to a JScript string
JsToVt(sJs) = Convert string in JavaScript Object Notation to COM exchange format
PathCombine(sFolder, sName) = Combine folder and name to form a valid path
PathCreateTempFolder() = Create temporary folder && return its full path
PathExists(sPath) = Test whether path exists
PathGetBase(sPath) = Get base/root name of a file or folder
PathGetCurrentDirectory() = Get current directory of active process
PathGetExtension(sPath) = Get extention of file || folder
PathGetFolder(sPath) = Get the parent folder of a file or folder
PathGetInternetCacheFolder() = Get Windows folder for temporary Internet files
PathGetLong(sPath) = Get long name of file or folder
PathGetName(sPath) = Get the file or folder name at the end of a path
PathGetShort(sPath) = Get short path (8.3 style) of a file or folder
PathGetSpec(sDir, sWildcards, sFlags) = Get a list of paths, specifying folder, wild card pattern, && sort order
PathGetTempFile() = Get full path of a temporary file
PathGetTempFolder() = Get Windows folder for temporary files
PathGetTempName() = Get Name for temporary file || folder
PathGetValid(sDir, sBase, sExt, bUnique) = var sIllegal = "&=@%*+\\|':'<>/?" + xQuote
var sViewable = "!#$%&'()*+,-./0123456789:'<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz|}~"
var sPrintable = xSpace + sViewable
PathSetCurrentDirectory(sDir) = Set current directory of active process, and return previously current directory
RegExpContains(sText, sMatch, bIgnoreCase) = /*
Get Array containing the starting index and text of the first match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/
RegExpContainsLast(sText, sMatch, bIgnoreCase) = /*
Get list containing the starting index and text of the last match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/
RegExpCount(sText, sMatch, bIgnoreCase) = /*
Count matches of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/
RegExpExtract(sText, sMatch, bIgnoreCase) = /*
Get list containing matches of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/
RegExpReplace(sText, sMatch, sReplace, bIgnoreCase) = /*
Replace text matching a regular expression
where sText is the string to search
sMatch is the regular expression to match
sReplace is the replacement text
bIgnoreCase indicates whether capitalization matters
*/
RegExpTest(sText, sMatch, bIgnoreCase) = /*
Test match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/
RegistryGetString(iRootKey, sSubKey, sValueName) = Get a string from registry
RegistryRead(sKey) = Get a string from the registry
RegistrySetString(iRootKey, sSubKey, sValueName, sValueData) = Set a registry string
RegistryWrite(sKey, sValue) = Write a string to the registry
ShellCreateShortcut(sFile, sTargetPath, sWorkingDirectory, iWindowStyle, sHotkey) = Create a .lnk or .url file
ShellExec(sCommand) = Run a console mode command && return its standard output
ShellExecute(sFile, sParams, sFolder, sVerb, iWindowStyle) = Execute a command with a verb like RunAs
ShellExpandEnvironmentVariables(sText) = Replace environment variables with their values
ShellGetEnvironmentVariable(sVariable) = Get the value of an environment variable
ShellGetShortcutTargetPath(sFile) = Get the target path of a shortcut file
ShellGetSpecialFolder(vFolder) = Get a special Windows folder
ShellInvokeVerb(sPath, sVerb) = Invoke a verb on a file or folder
ShellOpen(sPath) = Open a file or folder with the default program associated with its type
ShellOpenWith(sExe, sParam) = Open a program with a file
ShellRun(sFile, iStyle, bWait) = /*
Launch a program or file, indicating its window style && whether to wait before returning
window styles:
0 Hides the window && activates another window
1 Activates && displays a window. If the window is minimized || maximized, the
system restores it to its original size && position. This flag should be used
when specifying an application for the first time
2 Activates the window && displays it minimized
3 Activates the window && displays it maximized
4 Displays a window in its most recent size && position. The active window
remains active
5 Activates the window && displays it in its current size && position
6 Minimizes the specified window && activates the next top-level window in the Z
order
7 Displays the window as a minimized window. The active window remains active
8 Displays the window in its current state. The active window remains active
9 Activates && displays the window. If it is minimized || maximized, the system
restores it to its original size && position. An application should specify
this flag when restoring a minimized window
10 Sets the show state based on the state of the program that started the
application
*/
ShellRunCommandPrompt(sDir) = Open a command prompt in the directory specified
ShellRunExplorerWindow(sDir) = Open Windows Explorer in the directory specified
ShellWait(sPath) = Run a program and wait for it to return
StringAppendToFile(sText, sFile, sDivider) = Append string to File, omitting divider if the first one
StringChomp(sText) = Chop \n for both ends of a string
StringChopLeft(sText, iCount) = Remove iCount characters from left of sText
StringChopRight(sText, iCount) = Remove iCount characters from Right of sText
StringContains(sText, sMatch, bIgnoreCase) = Test if a string is contained in another
StringConvertToMacLineBreak(sText) = Convert to Macintosh line break, \r
StringConvertToUnixLineBreak(sText) = Convert to Unix line break, \n
StringConvertToWinLineBreak(sText) = Convert to standard Windows line break, \r\n
StringCount(sText, sMatch) = Count occurrences of a string within another string
StringEndsWith(sText, sSuffix, bIgnoreCase) = Test whether first string ends with second one
StringEqual(s1, s2) = Test if two strings are exactly equal
StringEquiv(s1, s2) = Test whether two strings are the same except for capitalization
StringGetASCII(sText) = Get space delimited ASCII codes for characters in string
StringLeft(sText, iCount) = Return leftmost characters of a string
StringLength(sText) = Return length of a string
StringLower(sText) = Convert string to lower case
StringPlural(sItem, iCount) = Return singular || plural form of a string, depending on whether count equals one
StringQuote(sText) = Quote a string
StringReplace(sText, sMatch, sReplace, bIgnoreCase) = Replace text
StringReplaceAll(sText, sMatch, sReplace, bIgnoreCase) = Replace all occurrences of a string within another
StringRight(sText, iCount) = Return rightmost characters of a string
StringSlice(sText, iStart, iEnd) = return sText.slice(iStart, iEnd) = } StringSlice method
StringToFile(sText, sFile) = Saves string to text file, replacing if it exists
StringToList(sText, sDelimiter) = Convert string with specified delimiter to list
StringTrim(sText) = Trim white space from both ends of a string
StringTrimLeft(sText) = Trim white space from left end of a string
StringTrimRight(sText) = Trim white space from right end of a string
StringUnquote(sText) = Unquote a string
StringUpper(sText) = Convert string to upper case
StringWrap(sText, iMaxLine) = var aLines, aWords
var i, j
var sReturn, sLines, sLine, sWords, sWord
UrlCreate(sProtocol, sHost, sPath, sQuery) = Create a URL from components
UrlGetBaseDomain(sUrl) = Get base domain of a URL
UrlGetExtension(sUrl) = Get extension of a URL
UrlGetFile(sUrl) = Get file of a URL
UrlGetFolder(sUrl) = Get folder of a URL
UrlGetFragment(sUrl) = Get fragment of a URL
UrlGetHost(sUrl) = Get subdomain and domain of a URL
UrlGetPath(sUrl) = Get path of a URL
UrlGetPathPlus(sUrl) = Get path and fragment or query of a URL
UrlGetPrePath(sUrl) = Get part of URL before path
UrlGetProtocol(sUrl) = Get protocol of URL
UrlGetQuery(sUrl) = Get query of URL
UrlGetSubdomain(sUrl) = Get subdomain of a URL
UrlNormalize(sUrl, sBase) = Normalize a URL for comparison
VtArrayToJs(a) = Convert variant array to JScript
VtArrayToList(a) = Convert variant array to list
VtCopyDictionary(dItems) = Copy a dictionary
VtCopyList(lItems) = Copy a list
VtCreateDictionary() = Return a variant dictionary
VtCreateFileSystemObject() = Return a file system object
VtCreateHtmlFile() = Create a variant HTMLFile object
VtCreateInternetExplorerApplication() = Return an Internet Explorer object
VtCreateList() = Create a variant list object
VtCreateRecordSet() = var oRs = Interaction.CreateObject('ADODB.RecordSet') = oRs.CursorLocation = adUseClient
return oRs
} VtCreateRecordSet method
VtCreateShellApplication() = Return a Shell.Application object
VtCreateStream() = Return an ADODB.Stream object
VtCreateVBScriptControl() = Return MSScriptControl.ScriptControl object
VtCreateWebRequest() = Create web request object
VtCreateWScriptShell() = Return WScript.Shell object
VtCreateXmlDocument() = Return an XML document
VtDateToJs(dt) = Convert a variant date to JScript
VtDictionaryKeysToJs(d) = Convert variant array of dictionary keys to JScript array
VtDictionaryKeysToList(d) = Convert variant array of dictionary keys to list
VtDictionaryToJs(d) = Convert a variant dictionary to JScript
VtDictionaryToXml(dItems, sFile) = Save dictionary to XML file
VtEvalVbs(sCode, dParams) = Evaluate VBScript code and return the result
VtEvalVbsParam(sCode, vParam) = Evaluate VBScript code and return result, passing single argument
VtGetWMIObject() = Get WMI object
VtInitDictionary(vValue) = Create a variant dictionary and initialize it with a single key/value pair
VtInitXmlDocument(sXml) = Create and initialize an Xml document with a string of XML
VtListFilterByExtension(lPaths, lExtensions) = Get a subset from a list of paths that match an extension
VtListFilterByRegExp(lItems, sMatch, bIgnoreCase) = Return list of matches of a regular expression
VtListFilterByWildcard(lItems, sMatch) = Return list of matches of a wildcard filter expression
VtListGetExtensions(lPaths) = Get a list of extensions from a list of paths, converting to lower case, removing duplicates, and sorting
VtListToJs(l) = Convert variant list to JScript array
VtListToString(lItems, sDelimiter) = Convert a list to a string with a specified delimiter
VtSleep(iMilliseconds) = var sCode = 'Sleep(d("v"))'
return VtEvalVbsParam(sCode, iMilliseconds) = } VtSleep method
VtTrim(sText) = Trim space from both ends of a string
VtTypeName(vVariant) = Get variant subtype
WebFetch(dParams) = Fetch files from web according to specifications in dictionary of parameters
WebListDownload(lUrls, sFolder, bUnique) = Download a list of URLs, specifying folder and whether to ensure unique file names
WebRequest(sType, sUrl, dData, dHeaders, sUser, sPassword) = Send a web request and return the response
WebRequestGet(sUrl, dData, dHeaders, sUser, sPassword) = Send a get request
WebRequestGetToFile(sUrl, dData, dHeaders, sUser, sPassword, sFile) = Send a get request and save response to file
WebRequestGetToString(sUrl, dData, dHeaders, sUser, sPassword) = Send a get request and return response as string
WebRequestHead(sUrl, dData, dHeaders, sUser, sPassword) = Send a head request
WebRequestHeader(sUrl, sHeader) = Get response header
WebRequestPost(sUrl, dData, dHeaders, sUser, sPassword) = Send a post request
WebRequestPostToFile(sUrl, dData, dHeaders, sUser, sPassword, sFile) = Send a post request and save response to file
WebRequestPostToString(sUrl, dData, dHeaders, sUser, sPassword) = Send a post request and return response as string
WebRequestToFile(sType, sUrl, dData, dHeaders, sUser, sPassword, sFile) = Save web resource to file
WebRequestToString(sType, sUrl, dData, dHeaders, sUser, sPassword) = Return web resource as string
WebUrlContentEncoding(sUrl) = Get encoding of a web resource
WebUrlContentLanguage(sUrl) = Get natural language code of a web resource
WebUrlContentLength(sUrl) = Get content length of a web resource
WebUrlContentLocation(sUrl) = Get redirected location of a web resource
WebUrlContentType(sUrl) = Get content type of a web resource
WebUrlDownloadPath(sUrl, sFolder, bUnique) = /Get file from URL, trying various techniques
WebUrlFileName(sUrl) = Get suggested file name of a web resource
WebUrlIsHtml(sUrl) = Test whether content type is text/html
WebUrlLastModified(sUrl) = Get last modification time stamp of a web resource
WebUrlServer(sUrl) = Get server name and version
WebUrlToFile(sUrl, sFile) = Save web resource to file
WebUrlToString(sUrl) = Return web resource as string
WebUrlToXml(sUrl) = Return web resource as XML document
XmlAppendElement(oParent, sName, sValue) = Append element to a node
XmlCreateElement(oNode, sName, sValue) = Create an XML element
XmlCreateFile(sFile) = Create a root XML file
XmlEnsureGetNode(sFile, sPath) = Return a node, creating preceding elements if necessary
XmlEnsureOpenFile(sFile) = Open an XML file, creating it if necessary
XmlGetAttribute(sFile, sPath, sAttribute, sDefault) = Get an attribute of a node
XmlGetNode(sFile, sPath) = Get a node
XmlGetNodeNames(sFile, sPath) = Get node names
XmlGetNodes(sFile, sPath) = Get a node list
XmlGetText(sFile, sPath, sDefault) = Get the text of a node
XmlGetValue(sFile, sPath, sDefault) = Get the value of a node
XmlOpenFile(sFile) = Open an XML file
XmlRemoveAttribute(sFile, sPath, sAttribute) = Remove an attribute
XmlRemoveNode(sFile, sPath) = Remove a node
XmlRemoveNodes(sFile, sPath) = Remove a node collection
XmlSetAttribute(sFile, sPath, sAttribute, sText) = Set an attribute
XmlSetText(sFile, sPath, sText) = Set text of an element
XmlSetValue(sFile, sPath, sValue) = Set a value
XmlToVtDictionary(sFile) = Convert XML file to variant dictionary
HomerAcc enables an application to produce direct speech messages via the API of an active screen reader. If JAWS, System Access, or Window-Eyes is detected in memory, its API is used to speak a string of text with a call to Acc.Say. Any data type may be passed to this method, causing its string representation to be spoken.
Here is a summary of HomerAcc methods:
bool Say(object oText) = Say the string version of an object using JAWS, System Access, or Window-Eyes
bool IsScreenReaderActive() = Test whether a screen reader is active
bool IsJAWSActive() = Test whether JAWS is active
bool IsWinEyesActive() = Test whether Window-Eyes is active
int JFWRunFunction(string sText) = Run a JAWS function from the current application or default scripts
int JFWRunScript(string sText) = Run a JAWS script from the current application or default scripts
bool JAWSSay(string sText) = Say text with JAWS
bool IsSAActive() = Test whether System Access is active
bool SASay(string sText) = Say text with System Access
bool WESay(string sText) = Say text with Window-Eyes
bool SAPISay(string sText) = Say text with the default SAPI voice
object GetProperty(object o, string sProperty) = Get a COM property
object GetProperty(object o, string sProperty, object[] args) = Get a COM property
object CallMethod(object o, string sMethod, string sValue) = Call a COM method
object CallMethod(object o, string sMethod, int iValue) = Call a COM method
object CallMethod(object o, string sMethod, object[] args) = Call a COM method
To create a form with Layout by Code, take the following steps:
* Instantiate an LbcForm object. For technical reasons, although this class may be used directly in a script passed to JaxForm, it must be inherited from when creating assemblies with other .NET languages. Also, a JaxForm script may pass parameters to the constructor, whereas other code must call an Init method as a seperate step. See FruitBasket.cs, FruitBasket.vb, and FruitBasket.js for examples.
The Init method takes three parameters corresponding to the title of the form, the name of the event handler to use, and a dictionary of tips to appear on the status line when each control has focus. In general, parameters of LbcForm methods are optional, and an intelligent default is chosen if null (Nothing in VB) is passed as a value.
* Add controls to the form. These instance methods start with the word "Add," and and optionally specify data for the control. If a control does not have a caption, itself, a convenience method exists that adds a label to the left of the control. For example, a TextBox could be added to a dialog with the syntax
dlg.AddTextBox(sText)
A labeled TextBox could be added with the syntax
dlg.AddInputBox(sLabel, sText)
The following controls are available: Button, CheckBox, CheckedListBox (multiple-selection ListBox with checkable items), DatePicker, ListBox, MaskedTextBox (TextBox with a configurable template to control input), MultiListBox (multiple-selection ListBox), Memo (multi-line TextBox), NumericUpDown, ProgressBar, RadioButton, TextBox, and TimePicker.
* Add controls to the form in placement order from top to bottom and left to right. Lbc arranges a form as a series of horizontal bands of controls. The last and lowest band is a centered set of buttons such as OK and Cancel. Lbc automatically adds a status bar at the bottom of the window. You can add a menu system at the top of the window by using the AddMenu and AddMenuItem methods before adding controls to the form. Menu items can include an accelerator key for activating a command directly. Use the AddBand method to start a new horizontal band of controls. This is analagous to pressing Enter to start a new line of text.
* Call the CompleteDialog method for a modal dialog or the CompleteWindow method for a modeless window. There are two possible parameters: an array of button names and a number indicating which control should initially have focus. The buttons are placed in a new, centered band at the bottom of the form. If no button array is passed, OK and Cancel buttons are assumed. Other finalization tasks are performed before displaying and activating the form. To complete the form without creating a button band, pass an empty button array.
* In general, all events that need to be monitored are passed to the event handler specified at the start of the form creation process. If no event handler is specified, the default is one called "OnEvent." The event handler has three parameters corresponding to the event name, control that sent the event, and object with properties indicating any additional arguments passed back by the event. Typically, events are managed within a switch block that checks for the event name, and then within another switch block that checks for the control name. The following events are automatically monitored: Click, Closing, GotFocus, Load, SelectedIndexChanged (for a ListBox), and Shown. If a BackGroundWorker component is used, the DoWork, ProgressChanged, and RunWorkerCompleted events are also supported. For technical reasons, the event handler must have public scope.
Lbc automatically assigns a name to each control added to the form. The name has two parts seperated by an underscore character (_): the class of the control and the label of the control. To ensure unique names, make sure that two controls of the same type do not also have the same label. For example, the label of a labeled TextBox would be a pair of controls with the names Label_Search and TextBox_Search. Lbc automatically appends a colon (:) to a label if one is not specified. It automatically prepends an ampersand (&) if none is specified, thereby making the initial letter the default access key of the control (so the control can be focused or activated with Alt+Letter). An Lbc form has a property called Names, which is a dictionary that associates control names and control objects. Thus, you can get a reference to a TextBox with syntax likeTextBox txt = dlg.Names["TextBox_Search"];
Here is a summary of HomerLbc methods:
DialogBrowseForFolder(sTitle, sDir) = Get a folder path to browse
DialogChoose(sTitle, aButtons, iFocus) = Choose a button
DialogConfirm(sTitle, sMessage, sDefault) = Confirm the answer to a Yes/No question
DialogDatePicker(sTitle, sLabel, dtValue, dtMinValue, dtMaxValue) = Pick a date value
DialogInfo(sTitle, sLabel, sText) = Show multiple lines of scrollable information
DialogInput(sTitle, sName, sValue) = Input a value
DialogInputAndChoose(sTitle, sName, sValue, aButtons, iFocus) = Input a value and choose a button
DialogMemo(sTitle, sLabel, sText) = Edit a multiline memo
DialogMultiCheck(sTitle, sLabel, aNames, aValues, aSelect, bSort, iIndex) = Check multiple values
DialogMultiInput(sTitle, aNames, aValues, iFocus) = Input multiple values
DialogMultiPick(sTitle, sLabel, aNames, aValues, aSelect, bSort, iIndex) = Pick multiple values
DialogOpenFile(sTitle, sPath) = Get a file path to open
DialogOpenFolder(sTitle, sFolder) = Get a folder path to open
DialogPick(sTitle, sLabel, aNames, aValues, bSort, iIndex) = Pick a value
DialogPickAndChoose(sTitle, sLabel, aNames, aValues, bSort, iIndex, aButtons, iFocus) = Pick a value and choose a button
DialogPickInputAndChoose(sTitle, sLabel, aNames, aValues, bSort, iIndex, sName, sValue, aButtons, iFocus) = Pick a value, input a value, and choose a button
DialogSaveFile(sTitle, sPath) = Get a file path to save
DialogShow(oTitle, oMessage) = Show two values in the title and message of a message box
DialogTimePicker(sTitle, sLabel, dtValue, dtMinValue, dtMaxValue) = Pick a time value
Init() = Initialize values for code, import, and export files
StringToKey(sKey:String):Keys
Convert a string to a Keys object
LbcDialog() = Instantiate an LbcDialog
LbcDialog(sTitle, sHandler, dFocusStatus) = Instantiate an LbcDialog, passing values for its title, event handler, and status messages
Init(sTitle, sHandler, dFocusStatus) = Initialize an LbcDialog
AddBand() = Start a new band of controls
AddButton(sText):Button
Add a button
AddButtonBand(aButtons) = Add a centered band of buttons
AddCheckBox(sText, bState):CheckBox
Add a checkbox
AddCheckedListBox(aItems, aSelect, bSort, iIndex):CheckedListBox
Add a checked listbox
AddInputBox(sLabel, sText):Control[]
AddComboBox(aItems, bSort, iIndex):ComboBox
Add a combobox
AddComboPickBox(sLabel, aItems, bSort, iIndex):ComboBox
Add a labeled combobox
AddDatePicker(dtValue, dtMinValue, dtMaxValue):DateTimePicker
Add a date picker
AddDatePickerBox(sLabel, dtValue, dtMinValue, dtMaxValue):DateTimePicker
Add a labeled date picker
AddInputBox(sLabel, sText):TextBox
Add a labeled TextBox
AddMemoBox(sLabel, sText, bReadOnly):RichTextBox
AddLabel(sText):Label
Add a label
AddListBox(aItems, bSort, iIndex):ListBox
Add a listbox
AddMemo(sText, bReadOnly):TextBox
Add a multiline memo
AddMemoBox(sLabel, sText, bReadOnly):TextBox
Add a labeled memo
AddPickBox(sLabel, aItems, bSort, iIndex):Control[]
AddMenu(sText):ToolStripMenuItem
Add a menu pulldown
AddMenuItem(sText, oKeys):ToolStripMenuItem
Add a menu item and accelerator key
AddMultiCheckBox(sLabel, aItems, aSelect, bSort, iIndex):CheckedListBox
Add a labeled checked listbox
AddMultiListBox(aItems, aSelect, bSort, iIndex):ListBox
Add a multiple selection listbox
AddMultiPickBox(sLabel, aItems, aSelect, bSort, iIndex):ListBox
Add a labeled multiple selection listbox
AddComboPickBox(sLabel, aItems, bSort, iIndex):Control[]
AddPickBox(sLabel, aItems, bSort, iIndex):ListBox
Add a labeled listbox
AddRadioButton(sText, bState):RadioButton
Add a RadioButton
AddStatus(sText) = Append status text
AddStatusBar():StatusStrip
Add a status bar
AddTextBox(sText):TextBox
Add a textbox
AddMemo(sText, bReadOnly):RichTextBox
AddTimePicker(dtValue, dtMinValue, dtMaxValue):DateTimePicker
Add a time picker
AddTimePickerBox(sLabel, dtValue, dtMinValue, dtMaxValue):DateTimePicker
Add a labeled time picker
AddMultiCheckBox(sLabel, aItems, aSelect, bSort, iIndex):Control[]
CollectionToArray(oCollection) = Convert a collection to an array
CompleteDialog(aButtons, iFocus):Button[]
Complete a dialog with a button band and focus position
CreateFlowPanel(direction) = Create a FlowLayoutPanel
CreateHorizontalPanel() = Create a horizontal FlowLayoutPanel
CreateMainMenu():MenuStrip
Create the main menu of the dialog
CreateMenu(sText) = Create a menu pulldown
CreateMenuItem(sText, sKey) = Create a menu item
CreateTablePanel(iColumns, iRows) = Create a TableLayoutPanel
CreateVerticalPanel() = Create a vertical FlowLayoutPanel
CurrentBand() = Return the current band number
CurrentControl() = Return the control last added
CurrentMenu() = Return the menu pulldown last added
CurrentMenuItem() = Return the menu item last added
Export(sFile) = Export data from a file into controls of the current dialog
FindControl(sClass) = Find the first control with a class name
GetClass(ctl) = Get the class of a control
GetFocus() = Get the control with focus
GetStatus() = Get status text
HandleClick(oSender:Object, oArgs:EventArgs) = Handler for Click event
HandleClosing(oSender:Object, oArgs:CancelEventArgs) = Handler for Closing event of a dialog
HandleDialogChoose(sEvent, oSender, oArgs) = Custom event handler for Choose dialog
HandleDialogDatePicker(sEvent, oSender, oArgs) = Custom event handler for date picker dialog
HandleDialogInfo(sEvent, oSender, oArgs) = Custom event handler for Info dialog
HandleDialogInputAndChoose(sEvent, oSender, oArgs) = Custom event handler for InputAndChoose dialog
HandleDialogMemo(sEvent, oSender, oArgs) = Custom event handler for Memo dialog
HandleDialogMultiCheck(sEvent, oSender, oArgs) = Custom event handler for multi check dialog
HandleDialogMultiInput(sEvent, oSender, oArgs) = Custom event handler for MultiInput dialog
HandleDialogMultiPick(sEvent, oSender, oArgs) = Custom event handler for multi pick dialog
HandleDialogOpenFolder(sEvent, oSender, oArgs) = Custom event handler for OpenFolder dialog
HandleDialogPick(sEvent, oSender, oArgs) = Custom event handler for Pick dialog
HandleDialogPickAndChoose(sEvent, oSender, oArgs) = Custom event handler for PickAndChoose dialog
HandleDialogPickInputAndChoose(sEvent, oSender, oArgs) = Custom event handler for PickInputAndChoose dialog
AddButtonBand(aButtons):Button[]
HandleDialogTimePicker(sEvent, oSender, oArgs) = Custom event handler for time picker dialog
HandleGotFocus(oSender:Object, oArgs:EventArgs) = Handler for GotFocus event of a control
HandleKeyDown(oSender:Object, oArgs:KeyEventArgs) = Handler for KeyDown event
HandleLoad(oSender:Object, oArgs:EventArgs) = Handler for Load event
HandleSelectedIndexChanged(oSender:Object, oArgs:EventArgs) = Handler for SelectedIndexChanged event of a ListBox
HandleSelectionChanged(oSender:Object, oArgs:EventArgs) = Handler for SelectionChanged event of a RichTextBox
HandleShown(oSender:Object, oArgs:EventArgs) = Handle for Shown event of a dialog
Import(sFile) = Import data from a file into controls of the current dialog
MakeAccessibleName(sLabel) = Make an accessible control name
MakeCaption(sText) = Make a control caption
MakeFriendlyKeyName(sKey) = Make a key string more friendly
MakeLabel(sText) = Make a control label
MakeName(ctl, sLabel) = Make a control name
SetStatus(sText) = Set status text
String ReadValue(String sFile, String sSection, String sKey, string sDefault) = Read a value
bool WriteQuote(String sFile, String sSection, String sKey, String sValue) = Write a value surrounded by quotes
bool WriteValue(String sFile, String sSection, String sKey, String sValue) = Write a value
bool WriteValue(String sFile, String sSection, String sKey, String sValue, bool bQuote) = Write a value, optionally surrounding it with quotes
bool DeleteKey(String sFile, String sSection, String sKey) = Delete a key
bool DeleteSection(String sFile, String sSection) = Delete a section
bool FlushFile(String sFile) = Flush any pending changes to disk
string[] ReadKeys(string sFile, string sSection) = Get an array of key names
string[] ReadKeys(string sFile, string sSection, bool bIncludeComments) = Get an array of key names, optionally including commented lines (leading semicolon)
string[] ReadSections(string sFile) = Get an array of section names
bool Add(string sZip, string[] aFiles) = Add array of files to archive (or null for * wildcard)
object[] Contents(string sZip) = Get array of dictionaries of archive contents
bool Delete(string sZip, string[] aFiles) = Delete array of files from archive (or null for * wildcard)
bool Extract(string sZip, string[] aFiles, string sDir, bool bSubdirs) = Extract array of files from archive (or null for * wildcard)
string GetProgramOutput(string sExe, string sParams) = Get standard output from running console executable
bool Test(string sZip) = Test integrity of archive
InJs may be used to run or test code in either standard JavaScript or the enhanced Microsoft JScript 8.0, which also serves as the script language for web development with ASP.NET. The home page of the language is at
http://msdn2.microsoft.com/en-us/library/72bd815a(VS.80).aspx
For example, a .js file can define a sophisticated snippet that may be invoked with the Alt+V command of the EdSharp editor, available at
http://www.EmpowermentZone.com/edsetup.exe
JScript code can also be evaluated by IronCOM, a COM server that provides traditional Win32 applications with access to functionality of the .NET Framework, available at
http://www.EmpowermentZone.com/comsetup.exe
The HomerKit library for JAWS
http://EmpowermentZone.com/kitsetup.exe
or
http://EmpowermentZone.com/kitsetup.zip
includes a function called JSEval that wraps a JScript call via IronCOM, thereby enabling JAWS scripts to make .NET calls for functionality not available in the native scripting language.
InJs may also be helpful for programming in .NET languages other than JScript. Built in commands are defined for inquiring about available methods, properties, and events via reflection. You can explore an object model, test expressions, save working code, and then convert it to the syntax of another .NET language.
Another assembly, XmlComments.dll (with source code in XmlComments.cs), is included for querying documentation of .NET types. I found this by Stephen Toub at
http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/04/06/NETMatters/Default.aspx
Reflecting on a COM object requires that a DLL be registered on the computer, described in the article
"Inspect COM Components Using the TypeLib Information Object"
http://msdn.microsoft.com/msdnmag/issues/1200/TypeLib/
Registering this DLL (also included in the archive) may be done at a command prompt as follows:
RegSvr32 TlbInf32.dll
Installing EdSharp does this automatically, and makes InJs conveniently available with the Go to Environment command, Control+Shift+G.
InJs works well with a screen reader, since new output to the console is automatically read. Periodically, the cls command is useful for clearing the screen and eliminating extra verbiage. InJs may also be used as a simple, speech-friendly calculator, since most algebraic, trigonometric, or date calculations may be done with JScript.
Below is the online documentation, available by entering the help command in Interactive JScript:
Type a JScript statement, followed by Enter
(a closing semicolon is not needed).
Use UpArrow to repeat a command.
End a line of input with a space and underline ( _) to continue
a multiline block of code.
The prompt then changes from a > to _ character.
Most classes of the .NET Framework 2.0 may be used in expressions.
Variable types are inferred.
To ease typing, the following namespaces are imported
(there classes may be referenced without a namespace prefix):
Accessibility
Microsoft.VisualBasic
System
System.Collections
System.ComponentModel
System.Data
System.Diagnostics
System.Drawing
System.IO
System.Net
System.Reflection
System.Runtime.InteropServices
System.Text
System.Text.RegularExpressions
System.Web
System.Windows.Forms
System.Xml
In addition, several built-in commands and functions are available.
A command name is lower case, with a space before each argument,
and no quotes around it. A function name is lower camel case
(words after the first are capitalized).
quit = end this program
cls = clear the screen
eval FileName = execute a JScript file
eval clipboard = execute JScript code on the clipboard
cmd = pass any statement to the Windows command interpreter (cmd.exe)
dos = execute a console-mode command and display its output
log FileName = log output to a file
log off = suspend logging
log on = continue logging
net Type = list members of .NET Type
constructors Type = list its constructors only
events Type = list its events only
fields Type = list its fields only
methods Type = list its methods only
properties Type = list its properties only
com Object = list members of COM Object
dir Type/Object = directory of members of either .NET Type or COM Object
doc Type = documentation for constructors of .NET Type
doc Type Member = documentation for Member of .NET Type
comCreate(sProgID) = alias for new ActiveXObject(sProgID)
output(Object) = alias for Console.WriteLine(Object)
If Window-Eyes is running, itsApplication object is
automatically assigned to the we variable for typing convenience.
Homer.NET 0.73 on September 19, 2009
Added documentation to further explain Lbc concepts. Added SAAPI32.dll for support of the System Access screen reader.
The .NET Framework 2.0 Software Development Kit (SDK) is available at
http://msdn.microsoft.com/en-us/netframework/aa731542.aspx
I developed Homer.NET with the EdSharp editor available at
http://EmpowermentZone.com/edsetup.exe
The latest version is available at
http://EmpowermentZone.com/hnsetup.zip
Jamal Mazrui
jamal@EmpowermentZone.com