Section 508 for Software Development Coding Examples

Visual C++

Provision A

§1194.21(a) “When software is designed to run on a system that has a keyboard, product functions shall be executable from a keyboard where the function itself or the result of performing a function can be discerned textually.”

Use Mnemonics (Alt+ and/or Ctrl+ Keys) Where Appropriate to Enable Keystroke Accessibility to Menu Options and Other Components
In any Windows client-based Graphical User Interface (GUI), menus should automatically provide an “Alt+” key alternative to the mouse action, thus allowing keyboard keystrokes to be used. In addition, a developer may elect to use “Ctrl+” keys where certain menu actions need to be accessible without the menu actually appearing. A good example of this is the standard copy (Ctrl+C) and paste (Ctrl+V), which do not require the Edit window menu to appear.

Let's take a look at some code that demonstrates how a standard Windows Visual C++ program could add Alt+ and Ctrl+ keys to a menu.

This is sample code for creating a menu and adding accelerators.

// initializes the window menu at startup
void CreateKeystrokeMenu()
{
	/* The basic menuitems are:

		New      Ctrl+N
		Open	 Ctrl+O
		Close	 Ctrl+C
		Save	 Ctrl+S
		SaveAs   Ctrl+A
		Print    Ctrl+P
		Exit     Ctrl+E
	*/

	MENUITEMINFO fileMenuItemInfo;
	char fileMenu[1][80];
	char menuItem[10][80];

	// Alt keys are automatic using the “&” while control keys are added via a resource
	strcpy(&fileMenu[0][0], "&File");  \\ main menu File
	strcpy(&menuItem[0][0], "&New\tCtrl+N");  \\ first menu subitem New
	strcpy(&menuItem[1][0], "&Open\tCtrl+O");
	strcpy(&menuItem[2][0], "&Close\tCtrl+C");
	strcpy(&menuItem[3][0], "|");
	strcpy(&menuItem[4][0], "&Save\tCtrl+S");
	strcpy(&menuItem[5][0], "Save&As\tCtrl+A");
	strcpy(&menuItem[6][0], "|");
	strcpy(&menuItem[7][0], "&Print\tCtrl+P");
	strcpy(&menuItem[8][0], "|");
	strcpy(&menuItem[9][0], "E&xit\tCtrl+X");

// create the subitem menu to add to the main menu File
	mKeystrokeMenu = CreateMenu();

// Add all menu subitems
	for (int i = 0; i < 10; i++)
	{
// fill in the menu item information structure
		fileMenuItemInfo.fMask = MIIM_STATE|MIIM_TYPE|MIIM_ID;

Within Windows the Alt+ keys are automatic as long as the menu text includes the “&” symbol for the required letter. The Ctrl+ keys are known as accelerators and must be added via a Visual C++ resource (via the editor) or dynamically created. This routine is called during window initialization and the menu created is added to the CreateWindow function as a parameter. This code illustrates this approach:

		// test for separator
	fileMenuItemInfo.fType = (strcmp(&menuItem[i][0], "|") ==
0)?MFT_SEPARATOR:MFT_STRING;
		fileMenuItemInfo.fState = (strcmp(&menuItem[i][0], "|") ==
0)?MFS_DISABLED:MFS_ENABLED;
		fileMenuItemInfo.wID = menuIds[i];
		fileMenuItemInfo.dwTypeData = (strcmp(&menuItem[i][0], "|") ==
0)?NULL:&menuItem[i][0];
		fileMenuItemInfo.cch = (strcmp(&menuItem[i][0], "|") ==
0)?0:strlen(&menuItem[i][0]);
		fileMenuItemInfo.cbSize = sizeof(fileMenuItemInfo);
		// insert the menu item into the submenu
		InsertMenuItem(mKeystrokeMenu, i, FALSE, &fileMenuItemInfo);
}
	// create the main File menu
	mFileMenu = CreateMenu();
	fileMenuItemInfo.fMask = MIIM_STATE|MIIM_TYPE|MIIM_ID|MIIM_SUBMENU;
	fileMenuItemInfo.fType = MFT_STRING;
	fileMenuItemInfo.fState = MFS_ENABLED;
	fileMenuItemInfo.wID = 60000;
	fileMenuItemInfo.hSubMenu = mKeystrokeMenu;
	fileMenuItemInfo.dwTypeData = &fileMenu[0][0];
	fileMenuItemInfo.cch = strlen(&fileMenu[0][0]);
	fileMenuItemInfo.cbSize = sizeof(fileMenuItemInfo);
	InsertMenuItem(mFileMenu, 0, FALSE, &fileMenuItemInfo);

// add accelerator table(no resource required) for control key functions - example adds 3(CTRL+N, CTRL+O, //CTRL+C)
	ACCEL strAccel[3];
	 ZeroMemory(&strAccel, sizeof strAccel);

	strAccel[0].fVirt = FCONTROL;
	strAccel[0].key = 14;  //CTRL+N
	strAccel[0].cmd = 60001;
	strAccel[1].fVirt = FCONTROL;
	strAccel[1].key = 15;  // CTRL+O
	strAccel[1].cmd = 60002;
	strAccel[2].fVirt = FCONTROL;
	strAccel[2].key = 3; // CTRL+C
	strAccel[2].cmd = 60003;

	// Accelerator tables may also be added using a resource file via the Load
//Accelerator function.
	hAccel = CreateAcceleratorTable(strAccel, 3);

Accelerator Tables
Accelerator tables are managed via the Windows loop using the TranslateAccelerator function. For example, this code, found in the main Windows message loop, will handle all keyboard accelerators added via an accelerator table:

 if (!TranslateAccelerator(msg.hwnd, hAccel, &msg))
{
	TranslateMessage(&msg);  // allow input
	DispatchMessage(&msg);  // Actual CTRL key handled by windows main procedure loop
}

All other components, such as buttons, labels, edit fields, check boxes, radio buttons, etc. must be accessible via the keyboard. In general, all buttons should have Alt+ keys mnemonics added and most other controls should be available in logical tabbing order via the Tab keys. In other words, a component must use a mnemonic or it must be accessible via the Tab key.

Accelerator Keys
Another way to add accelerator keys is to use the Visual C++ editor via the accelerator dialog as shown in this example:

This graphic is a screen capture of the Accel Properties dialogue box, used to add accelerator keys in Visual C++.  On the left side of the dialogue box, there is an ID and Key field that are selectable to allow the developer to add a text label and letter that will invoke the command.  The right side has three modifier checkbox choices, which are control, alt and shift.  You can select which modifier will be used in conjunction with the information in the key field to invoke the accelerator. Under the modifier choices, there are radio buttons that allow the user to select either ASCII type or virtkey type.

The actual C++ program may then load the accelerator table created via the Windows API LoadAccelerator function. The Visual C++ editor provides all the tools necessary to add Alt+ or Ctrl+ keys to most components. In addition, a developer can add a textual label to any component that text cannot be written to, for example an edit field. The edit field label can use the text to indicate an Alt+ key letter to access the field. In the sample “Accel Properties” dialog box shown above this technique is used for the ID, Key, Modifiers, and Type fields.

Provision B

§1194.21(b) “Applications shall not disrupt or disable activated features of other products that are identified as accessibility features, where those features are developed and documented according to industry standards. Applications also shall not disrupt or disable activated features of any operating system that are identified as accessibility features where the application programming interface for those accessibility features has been documented by the manufacturer of the operating system and is available to the product developer.”

Typically, operating system level accessibility features have a global interface such as “Control Panel” where the user can change them. Some of these features are sticky keys, filter keys, toggle keys, and show messages for sound.

For example, all accessibility features that are available within the Windows environment can be accessed and changed in Visual C++ through Windows API’s. The SystemParametersInfo function is used to get and/or set a specific accessibility feature for Windows.

A sample of some Windows API’s accessibility features are:

A full feature list specific to each operating system can be accessed from the latest Microsoft documentation on the subject. Generally, a current list of the Windows API’s will be sufficient.

For more advanced accessibility features and interfaces, reference Microsoft’s Active Accessibility information, which can provide other alternatives to developers.

From the Microsoft website:

“Microsoft Active Accessibility 2.0 is a COM-based technology that improves the way accessibility aids work with applications running on Microsoft Windows operating systems. It provides dynamic-link libraries that are incorporated into the operating system as well as a COM interface and application programming elements that provide reliable methods for exposing information about user interface elements.”

This is generally unnecessary for most applications that will simply be retrofitted or need to conform to Section 508. For example, a company developing accessibility software such as a screen reader program would use the Active Accessibility API’s.

Note: All operating systems that have a client interface will have available some form of accessibility features.

The purpose of the Windows API’s related to accessibility is to provide a simplified interface for developers to access and change the current accessibility features. The issue for developers is to provide a way to change custom settings in their own programs without changing the user's accessibility features. This can be accomplished with a menu option that resets all or individual accessibility options to their defaults. The user can choose which options best suit their needs and either select to keep them (through system features such as the control panel) or change them in a custom program.

Let's take a look at some sample code. This code captures the menu selection, then displays the GETACCESSTIMEOUT feature to the user in a MessageBox.

			switch(wParam)
			{
			case 70001: break}
	ACCESSTIMEOUT hAccess;
	hAccess.cbSize = sizeof(ACCESSTIMEOUT);
	SystemParametersInfo(SPI_GETACCESSTIMEOUT,
	sizeof(ACCESSTIMEOUT),&hAccess, 0);
	char buf[10], scat[30];
			itoa(hAccess.iTimeOutMSec, buf, 10);
			memset(&scat,'\0',30);
			strcat(&scat[0], buf);
			strcat(&scat[0], " milliseconds");
			MessageBox(0,scat, "Timeout period of accessibility features", MB_OK);

The resulting MessageBox, shown here, informs the user of the amount of time before the accessibility features time out.

The graphic shown is a screen capture of a Message Box.  The title of the message box is "Timeout period of accessibility features". The text within the box informs the user of the amount of time (300000 Miliseconds) before the designated features time out.  There is an "OK" button for the user to select.

Use the SystemParametersInfo function to get or set all other Windows accessibility features.

In summary, if your program can change an operating system accessibility feature, you must provide an interface for the user to reset that feature. For example, using the color scheme set by the user cannot be changed and/or turned off without allowing the user the ability to reset to their defaults (color schemes for Windows can be accessed via the GetSysColor API and set with the SetSysColors API).

For example, use this code to get the Windows window background color used in the session:

DWORD RGBWindowBackground;
RGBWindowBackground = GetSysColor(COLOR_WINDOW);

RGBWindowBackground now contains the RGB color of the window background color for the current session.

To conform to Provision B, operating system accessibility features cannot be disabled without providing the user with one or more alternatives.

Provision C

§1194.21(c) “A well-defined on-screen indication of the current focus shall be provided that moves among interactive interface elements as the input focus changes. The focus shall be programmatically exposed so that assistive technology can track focus and focus changes.”

System Caret Information
In order for a user to track focus changes on-screen and in fields, the fields must be visually well-defined. In many client Graphical User Interface (GUI) programs, the edit field focus can be difficult to discern. For example, an edit field that has either a very thin non-blinking caret or no caret would be difficult to determine if the field had focus. Therefore, ensure that the system caret used in your programs is easily seen in screen fields.

The blink rate and even a new caret can be created using Windows API’s. The user may want to set the caret blink rate using the Control Panel, which means that a program must provide a way to change the system caret blink rate back to the default value.

To get the current caret blink rate use GetCaretBlinkTime. To set the current caret blink rate use SetCaretBlinkTime. Let's take a look at some sample code that accomplishes this:

// establish the milliseconds variable
UINT caretMilliseconds;
// store the blink time
caretMilliseconds = GetCaretBlinkTime();
// slow down the blink rate
caretMilliseconds = caretMilliseconds – 10000
// reset the caret blink time
ClassName ::SetCaretBlinkTime( caretMilliseconds );

A word of caution, the blink rate affects all system applications, therefore any application started after setting the new blink time will use the new time.

A new caret can be created using the CreateCaret function if the user desires a better-defined caret or a block caret.

Focus By Color
In addition to the system caret features, each field on a screen could use the color attribute to establish focus where necessary. In many cases, components like buttons generally have a well-defined focus attribute typically, indicated by highlighted border when the button is active. Another way to establish a field’s focus is to highlight or bold the text within the text label of the field so that the user can readily distinguish the current field. For example, the dialog window shown here indicates which field has focus by bolding the text label.

This screen capture is of a login window with username and password fields, an OK and cancel button.  This screen capture demonstrates how a form field label (in this case the "Username" button) changes to bold-faced font when the object is in focus.

Using the field text label may be important since some fields/control may not have good visual indicators of their focus.

Let's take a look at some sample code that highlights (or bolds) the user name when the field sets or has focus.

// Does the username have focus?
if (GetFocus() == hUSERNAME)
{
// highlight the control by bold
SendMessage(hUSERNAMEC,WM_SETFONT, (WPARAM)boldFont, TRUE);
}

For developers who are creating applications that are accessed via a VT100 or VT100-like terminal connection, ensure that the cursor follows highlighted menu options when navigation keys are used. Often only highlighted text is used to indicate the change of focus, while leaving the cursor in the corner, which does not conform to this provision.

In some instances, a field such as a button could highlight the text name of the button in bold in order to indicate focus.

Let's take a look at some sample code that highlights (or bolds) the OK button before or as it gets focus:

// OK button have FOCUS?
if (GetFocus() == hOK)
{
// highlight the control by bold - Set the control font to a bold one
SendMessage(hOK,WM_SETFONT, (WPARAM)boldFont, TRUE);
}

This screen capture is of a login window with username and password fields, an ok and cancel button.  This screen capture demonstrates how a button (in this case the "OK" button) changes to bold-faced font when the object is in focus.

Other alternatives include using the window border to indicate the control, which has the focus.

Assistive Technologies
In general, Windows readily provides assistive devices with the ability to track focus changes. This information is provided through system hooks and/or through the Active Accessibility SDK, which any assistive technology program can use, or access automatically. Since Visual C++ programs with a visual counterpart automatically set focus through the operating system on components using a tab order, mouse clicks, and/or accelerator keys, there is no explicit function required. If the program specifically uses the SetFocus function, then the focus is set through Windows API’s, which will automatically be available to assistive technologies using the provision interfaces.

However, any window or component coordinates can be accessed using the GetWindowRect function, which can provide the rectangle of any window to an external API.

For example, retrieve the rectangle coordinates of the username edit control window called hUSERNAME by using this code:

// Establish the rectangle variable
RECT hrect;
// Retrieve the rectangle coordinates of a window
GetWindowRect(hUSERNAME, &hrect);

Provision D

§1194.21(d) “Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.”

Each screen component must be described in text (usually as a text label). Where appropriate, the state of that component may also have to be described in text. In addition, assistive technology must be able to access each component's characteristics.

Text Labels
The standard and easiest way to address the need is to ensure that every screen element is described textually. All menus, menu items, buttons, edit fields, check boxes, radio buttons, list boxes, etc. should have a text label describing them.

For example, this screen capture of this login window includes a number of elements that are appropriately labeled, a checkbox is included, and the state of the checkbox item is also shown.

This graphic is a screen capture of a Windows login form.  There is a Username and password label and empty input field, a new user checkbox which has a message that tells the user that the checkbox is unchecked and another message that tells the user where the focus currently is, which is on the username field.  There is also an ok and cancel button.

This graphic shows how, in a Visual C++ Integrated Development Environment (IDE), the checkbox for new user has a text label added to the right. In this manner, whenever the checkbox state changes, the text label can also change to indicate the same.

This screen capture shows Visual C++'s Integrated Development Environment (IDE). The developer is creating a login screen that has a Username and password label and empty input field, a new user checkbox which has a message that tells the user that the checkbox is unchecked and another message that tells the user where the focus currently is, which is on the username field.  There is also an ok and cancel button.

Use this code to have the state of a checkbox label change after the user selects the checkbox:

// indicate the state of the checkbox item after the item is checked
SetDlgItemText(hLoginWindow, IDC_CHECKBOX_TEXT, "Checked");

Each type of component must be treated in the same fashion, labeled textually, and the state indicated where appropriate.

Images
Wherever an image is indicated on the screen, the image must have a text definition associated with it unless the image is cosmetic.

Take a look at the menu shown in this screen capture.

This graphic is a screen capture of a Windows menu. The file menu is expanded and displays several options and their respective shortcut keys: new with control + n, open with control + o, close with control +c, save with control +s, save as with control + a, print with control + p and exit with control + x.  Each option has an underlined letter that corresponds to the access key associated with the control command.  The open and print options have a bitmap images associated with them.  The open has an image of a folder and the print has an image of a printer.

Both the Open menu item and the Print menu item have bitmap images associated with them. The user can view the bitmap image and the associated text describing the image.

Adding Text
Text may be added in a number of ways. While creating dynamic menus using Windows API’s, you can use this code to add text:

MENUITEMINFO fileMenuItemInfo;
char fileMenu[1][80];
char menuItem[10][80];
strcpy(&fileMenu[0][0], "    &File");
strcpy(&menuItem[0][0], "    &New\tCtrl+N");
strcpy(&menuItem[1][0], "    &Open\tCtrl+O");
strcpy(&menuItem[2][0], "    &Close\tCtrl+C");
strcpy(&menuItem[3][0], "|");
strcpy(&menuItem[4][0], "    &Save\tCtrl+S");
strcpy(&menuItem[5][0], "    Save&As\tCtrl+A");
strcpy(&menuItem[6][0], "|");
strcpy(&menuItem[7][0], "    &Print\tCtrl+P");
strcpy(&menuItem[8][0], "|");
strcpy(&menuItem[9][0], "    E&xit\tCtrl+X");

Another possibility uses the Visual C++ editor to create the menu resource, adding the appropriate text as necessary.

Provision E

§1194.21(e) “When bitmap images are used to identify controls, status indicators, or other programmatic elements, the meaning assigned to those images shall be consistent throughout an application's performance.”

It is your job as a developer to ensure that any image utilized in an application has a consistent meaning. For example, a print feature and accompanying bitmap can be used a number of times throughout many applications. Therefore, the print bitmap must always be used in the same manner, to indicate the printing capability.

Let's take a look at an example of consistent usage of a bitmap image across an application. Each of these two screen captures depicts a drop down menu containing a print option. (Note that the bitmap image for the print option is the same in both menus.)

This graphic is a screen capture of a Windows menu. The file menu is expanded and displays several options and their respective shortcut keys: New with control + n, Open with control + o, Close with control +c, Save with control +s, Save As with control + a, and Print with control + p.  Each option has an underlined letter that corresponds to the access key associated with the control command.  The Open and Print options have bitmap images associated with them.  The Open command has an image of a folder and the Print command has an image of a printer.

This graphic is a screen capture of a Windows menu. The accessibility menu is expanded and displays several options.  Each option has an underlined letter to represent its corresponding access key: The purpose of the screen capture is to show that the “Print All Options” option has a printer icon to the left of the words.

Provision F

§1194.21(f) “Textual information shall be provided through operating system functions for displaying text. The minimum information that shall be made available is text content, text input caret location, and text attributes.”

A variety of methods are available to the developer to add text to editable and static controls within Visual C++. Utilizing standard operating system text display functions, text information will be available to assistive technologies. In addition, most Windows controls that are standard within the Visual C++ IDE are already automatically accessible to assistive technologies, since Windows exposes their attributes automatically. Any assistive technology (such as screen readers) utilizing the Microsoft Active Accessibility tools will have access to standard control attributes.

Text Content
These two functions provide the necessary operating system interface for text updates.

// Using standard Windows messages display the new edit text
// Initialize the text to display
char editText[256] = “Textual information shall be provided through operating system_
 functions for displaying text. The minimum information that shall be made _
 available is text content, text input caret location, and text attributes.”
// Display the edit text
SendMessage(hTextWindow, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)&editText[0]);


// Using a dialog function display the new edit text
// Initialize the text to display
char editText[256] = “Textual information shall be provided through operating system_
 functions for displaying text. The minimum information that shall be made _
 available is text content, text input caret location, and text attributes.”
// Display the edit text
SetDlgItemText(hTextWindow, IDC_EDITTEXT, &editText[0]);

The result of this coding is this Textual Information window.

This graphic is a screen capture of the Textual Information window that displays the text entered in the Visual C++ code examples.  The text is entered into a text area field in the middle of the information window and there is an ok and cancel button at the bottom of the window.

Caret Locations
There are a number of caret functions that can alter the system caret. If necessary, some of the main functions to use would be SetCaretPos or SetFocus.

Use the SetCaretPos function to set the caret location to a specific window coordinate. Let's take a look at the sample code for this:

// to set the system caret to specific window coordinates
// Establish the rectangle structure
RECT hrect;
// get the windows(edit text field) rectangle
GetWindowRect(hTextWindow, &hrect);
// set the system caret to the specific x and y coordinates
SetCaretPos(hrect.left, hrect.top);

Use the SetFocus function to set the system focus to a specific control within a window. (Which in turn will change the system caret to that control or field.) Code for the SetFocus function is:

// set the focus and system caret to the edit text field
SetFocus(hTextWindow);

To retrieve the caret location and provide this to another function or module, use the GetCaretPos function shown here:

// get the system caret position – the POINT structure  contains the system caret x and y //coordinates.
POINT lPoint;
// place the current caret position in the point structure as x and y coordinates
GetCaretPos(&lPoint);

Text Attributes
An application can use these six functions to set the text-formatting attributes for a device context:

  1. SetBkColor.
  2. SetBkMode.
  3. SetTextAlign.
  4. SetTextCharacterExtra.
  5. SetTextColor.
  6. SetTextJustification.

These functions affect the text alignment, the intercharacter spacing, the text justification, and text and background colors. In addition, six additional functions exist that can be used to retrieve the current text formatting attributes for any device context. These remaining six functions are:

  1. GetBkColor.
  2. GetBkMode.
  3. GetTextAlign.
  4. GetTextCharacterExtra.
  5. GetTextColor.
  6. GetTextExtentPoint32.

Let's take a look at one example that involves the use of color. To set the text color of the text edit field to blue, use the SetTextColor (for drawing functions), as shown in this code:

// The SetTextColor function sets the text color for the specified device context to the specified color.
// Note this example works when using the TEXTOUT function to draw text in a control.
// establish a device context
HDC hDC;
// get the device context of the text edit field
hDC = GetDC(hTextWindow);
// set the text color of the text edit field to blue
SetTextColor(hDC,  RGB(0,0,255));
// free the device context
ReleaseDC(hPASSWORD, hDC);

Another function that can retrieve text attributes for a specific controls font is the GetTextMetrics function. Using a device context all text attributes can be retrieved for any given window (control/field). This resulting TEXTMETRIC structure contains many attributes of the given text used.

//The GetTextMetrics function fills the specified buffer with the metrics for the currently //selected font.
// establish a device context
HDC hDC;
// get the device context of the text edit field
hDC = GetDC(hTextWindow);
// establish a TEXTMETRIC structure
TEXTMETRIC strTEXTMETRIC;
// clear the structure
ZeroMemory(&strTEXTMETRIC, sizeof TEXTMETRIC);
// get the text metrics of the device context font
GetTextMetrics(hDC, &strTEXTMETRIC);
// free the device context
ReleaseDC(hPASSWORD, hDC);

Provision G

§1194.21(g) “Applications shall not override user selected contrast and color selections and other individual display attributes.”

Visual C++ provides you with the ability to maintain the integrity of these user-defined attributes:

Let’s take a moment to briefly discuss how to handle each attribute.

Color Selection
Use the SetSysColors function to allow a user to change a system color. (This function is the opposite of the GetSysColor function, which sets RGB values for many different Windows system colors.) The same values are used to reset the system color. Note: Be sure to save the original system setting if you want it reinstated at a later date.

Let's take a look at an example of how the SetSysColors function is used. Let's say that a developer needs to get the user-selected background color used in a session. In order to do this, they use this code:

DWORD RGBWindowBackground; RGBWindowBackground = GetSysColor(COLOR_WINDOW);

After institution of this code, the RGBWindowBackground contains the RGB color of the user's window background color for the current session.

If the Windows background color needs to be changed (let's say to blue), the developer would use this code to reset the background color:

// specify to set the system window background color
int lpElements[2] = {COLOR_WINDOW, 0};
// set the system window background color to blue
COLORREF  lpColors[2];
// create a COLORREF structure from an RGB blue value
lpColors[0] = RGB(0,0,255);
// Initiate the system colors function to set the system window background color
SetSysColors(1,                 // number of elements
  &lpElements[0],        // array of elements
  &lpColors[0]  // array of RGB values
);

Contrast
The high contrast accessibility feature sets the appearance scheme of the user interface in order to provide maximum visibility for a visually disabled user.

To change (or reset) the high contrast scheme, use the SystemParametersInfo function for high contrast values as shown in this code:

// Establish the high contrast structure
HIGHCONTRAST strHighContrast;
// Clear the structure
ZeroMemory(&strHighContrast, sizeof(HIGHCONTRAST));
// request that the confirm hotkey dialog appears after high contrast is set by hotkey
strHighContrast.dwFlags = HCF_CONFIRMHOTKEY;
// set the size of the structure
strHighContrast.cbSize = sizeof(HIGHCONTRAST);
// specify the name of the high contrast scheme
strHighContrast.lpszDefaultScheme = "basic scheme";
// set the system high contrast value
SystemParametersInfo(SPI_SETHIGHCONTRAST,
sizeof(HIGHCONTRAST), &strHighContrast,  0);

Keyboard Repeat Rate
The keyboard repeat rate, acceptance delay, and bounce rate can be set by the SystemInfoParameters function using the type of SPI_SETFILTERKEYS. Utilize this code to perform the task:

// establish the filterkeys structure
FILTERKEYS strFilterKeys;
// clear the structure
ZeroMemory(&strFilterKeys, sizeof(FILTERKEYS));
// initiate the size
strFilterKeys.cbSize = sizeof(FILTERKEYS);
// indicate filterkey will sound-off when hotkeys activate/de-activate them
// user can hold down right shift key for 8 seconds to activate/de-activate the filterkeys)
strFilterKeys.dwFlags = FKF_HOTKEYSOUND |FKF_HOTKEYACTIVE;
// set the time a key must be held down before accepted(one-quarter second)
strFilterKeys.iWaitMSec = 250;
// Set the time a key is held down before repeating to 1 second
strFilterKeys.iDelayMSec = 1000;
// set the repeat key rate to every one-half second
strFilterKeys.iRepeatMSec = 500;
// ensure the bounce rate is zero
strFilterKeys.iBounceMSec = 0;
// set the new keyboard repeat rate
SystemParametersInfo(SPI_SETFILTERKEYS,	sizeof(FILTERKEYS),&strFilterKeys, 0);

Keyboard Sensitivity Setting
While the FILTERKEYS values can actually change the nature of keystrokes defined for the user (thus “sensitivity”), there are a few other functions that may affect how Windows behaves by changing the way that the keyboard operates. These functions are:

// establish the stickykeys structure
STICKYKEYS strStickeyKeys;
// clear the structure
ZeroMemory(&strStickeyKeys, sizeof(STICKYKEYS));
// set the structure size
strStickeyKeys.cbSize = sizeof(STICKYKEYS);
// user can turn the stickykey feature on/off by pressing the shift key 5 times
strStickeyKeys.dwFlags=SKF_HOTKEYACTIVE|SKF_HOTKEYSOUND;
// Initiate the stickykey changes
SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(strStickeyKeys), &strStickeyKeys,  0);
// establish the togglekeys structure
TOGGLEKEYS strToggleKeys;
// clear the structure
ZeroMemory(&strToggleKeys, sizeof(TOGGLEKEYS));
// set the structure size
strToggleKeys.cbSize = sizeof(TOGGLEKEYS);
// user can turn the togglekey feature on/off by holding down the num-lock key for 8 seconds
strToggleKeys.dwFlags=TKF_HOTKEYACTIVE;
// Initiate the togglekey changes
SystemParametersInfo(SPI_SETTOGGLEKE

Provision H

§1194.21(h) “When animation is displayed, the information shall be displayable in at least one non-animated presentation mode at the option of the user.”

Within Windows, several options exist for altering an animated product. These options include the use of:

Let's take a moment to briefly discuss each option.

SystemParametersInfo Function
The SystemParametersInfo function is used for all animations. It retrieves or sets the value of one of the system-wide parameters. This code is used to retrieve or set a system-wide parameter value:

BOOL SystemParametersInfo(UINT uiAction, // system parameter to retrieve or set
UINT uiParam,   // depends on action to be taken
PVOID pvParam,  // depends on action to be taken
UINT fWinIni // user profile update option);

Note that any action taken using SystemParametersInfo affects the entire system – not just the current application.

Affecting Animation Settings Using the SystemParametersInfo Function
Animation settings for an application can be affected by using the SystemParametersInfo function's:

Get or Set Animation State for User Actions
The get or set animation action either returns the current animation state for user actions (SPI_GETANIMATION) or sets the current animation state for user actions (SPI_SETANIMATION). Animation is enabled or disabled by setting variables within the ANIMATIONINFO structure. The same structure is used to get the current animation state.

ANIMATIONINFO Structure

The ANIMATIONINFO structure utilizes:

This code will get the current animation state and store the value within an ANIMATIONINFO structure:

// declare the structure
ANIMATIONINFO strGetAnimation;
// clear the structure
ZeroMemory(&strGetAnimation, sizeof(ANIMATIONINFO));
// set size of structure
strGetAnimation.cbSize = sizeof(ANIMATIONINFO);
// get the system animation setting for user actions
SystemParametersInfo(SPI_GETANIMATION,
sizeof(ANIMATIONINFO), &strGetAnimation,  0);

The current animation state return value is stored in the variable strGetAnimation.iMinAnimate. A zero value indicates no animation and a non-zero value indicates animation is enabled for user actions.

This code will set the current animation state to "enabled":

// declare the structure
ANIMATIONINFO strSetAnimation;
// clear the structure
ZeroMemory(&strSetAnimation, sizeof(ANIMATIONINFO));
// set size of structure
strSetAnimation.cbSize = sizeof(ANIMATIONINFO);
// ensure enabling the animation state
strSetAnimation.iMinAnimate = 1;
// set the system animation setting for user actions
SystemParametersInfo(SPI_SETANIMATION,
sizeof(ANIMATIONINFO), &strSetAnimation,  0);

Menu Animation
To enable or disable menu animation for the system, use the SPI_SETMENUANIMATION action of the SystemParametersInfo function.

To enable menu animation set the pvParam to TRUE. To disable the animation set the pvParam to FALSE.

This code enables animation of the system menu:

BOOL bSetMenuAnimation = TRUE;
SystemParametersInfo(SPI_SETMENUANIMATION,0, &bSetMenuAnimation,  0);

This code disables system menu animation.

BOOL bSetMenuAnimation = FALSE;
SystemParametersInfo(SPI_SETMENUANIMATION,0, &bSetMenuAnimation,  0);

ToolTips Animation

To enable (or disable) ToolTips animation for the system, use the SPI_SETTOOLTIPANIMATION action of the SystemParametersInfo function.

Setting the pvParam to TRUE will enable the animation. Setting the pvParam to FALSE disables the feature.

Use this code to enable system ToolTips animation:

BOOL bSetTooltipAnimation = TRUE;
SystemParametersInfo(SPI_SETTOOLTIPANIMATION,0, &bSetTooltipAnimation,  0);

Note: when enabling ToolTips animation the SPI_SETTOOLTIPFADE action can be used to specify fade or slide animation.

Use this code to disable system ToolTips animation:

BOOL bSetTooltipAnimation = FALSE;
SystemParametersInfo(SPI_SETMENUANIMATION,0, &bSetMenuAnimation,  0);

Provision I

§1194.21(i) “Color coding shall not be used as the only means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.”

In Visual C++, message boxes and state indicators can be adjusted to accommodate the needs of individuals with visual disabilities.

Let's take a look at how both elements need to be treated in order to conform to this provision.

Message Boxes

Most message boxes do not contain text that adequately informs users with a visual disability of the necessary actions that need to be taken. Notice that this message box contains no textual directive that would convey the action required by the user.

This graphic of an alert message box.  The message at the top of the box informs the user that invalid data exists.  The message in the middle of the box states that the data entered is not numeric along with an ok button for the user to select.  It does not convey the action that needs to be taken by the user.

Message boxes can be easily modified through the use of a short code. This code can be used when it is necessary to incorporate a directive that informs the user to stop (and address a known issue) before proceeding:

// include the word “STOP” within the message
MessageBox(0, "The data entered is not numeric.", "STOP!  Invalid Data", MB_ICONSTOP);

Once the code is instituted, the message box looks like this:

This graphic is a message box.  The message at the top of the box informs the user that they need to stop their action due to invalid data.  It states that the data entered is not numeric along with an ok button for the user to select.  This approach informs the user that they need to stop what they are doing and correct data previously entered.

Item State Indicators
A common practice seen in computer applications is to use color to indicate a certain state of an item (e.g., on/off, already viewed, etc.).

Unless given the ability to customize color preferences for display attributes, people who are color blind would not be able to view items such as priority flags.

A simple remedy is to insert a control that will indicate the state of an object to the user. Let's take a look at a sample solution. This message box-style item provides a list of links that are present on a particular page.

The contents of the message box graphic shown have been altered to allow users with visual disabilities to be able to track the state of an item.  In this example, the text items displayed are a list of links that appear on the page.  Each link title shown has a check box positioned to the left of the text. A check will appear in each box once its associated link has been visited.  A cancel button is provided within the box so that the user may cancel out of the function if desired.

The box is displayed and the user is instructed to select the link(s) they wish to visit. As the user visits each designated link, the program automatically checks it off the list.

The code associated with this solution is:

// get the handle to the first link on the color window
hdlgItm = GetDlgItem(hLinksWindow, IDC_CHECKBOX_FIRSTLINK);
// send the checked state message to the first checkbox on the links window.
SendMessage(hdlgItm, BM_SETCHECK,  (WPARAM) BST_CHECKED, 0);

Provision J

§1194.21(j) “When a product permits a user to adjust color and contrast settings, a variety of color selections capable of producing a range of contrast levels shall be provided.”

Visual C++ developers can use a variety of techniques to change colors within Windows. These techniques fall into one of two basic categories:

System-Wide Techniques
Use the GetSysColor and SetSysColors functions to institute system-wide color changes.

Use the GetSysColor function for determining the current color settings. (Note: before changing the settings, be sure to store them for future use.)

Let's take a look at a few examples.

Look at this screen capture of a login window.

This is a screen capture of a user login window with a username and password field.  The bottom of the screen has 2 buttons, an “OK” and “Cancel” button, where the button face and text colors need to be changed due to the fact that the degree of contrast between the two colors is low.

The developer has determined that button face and text colors need to be changed due to the fact that the degree of contrast between the two colors is low. The developer begins their work by using this code to retrieve the current button face and text colors:

// establish the variables
        DWORD RGBButtonFace, RGBButtonText;
// store the current system button face color
        RGBButtonFace = GetSysColor(COLOR_BTNFACE);
// store the current system button text color
        RGBButtonText = GetSysColor(COLOR_BTNTEXT);

The developer then uses this code to reset the button text to blue:

// set the button text to blue
        int lpElements[2] = {COLOR_BTNTEXT, 0};
// establish the COLORREF structure
        COLORREF  lpColors[2];
// set the first COLORREF structure array element to blue
 lpColors[0] = RGB(0,0,255);
// set the system button text color to blue
        SetSysColors(1,  // number of elements
        &lpElements[0], // array of elements
         &lpColors[0]  // array of RGB values
);
  &lpColors[0]  // array of RGB values
);

The outcome of this last code is that the color of the button text has changed to blue (as seen in this screen capture).

This is a screen capture of a user login window with a username and password field.  The bottom of the screen has 2 buttons, an "OK" and "Cancel" button, where the button face and text colors were changed to blue due to the fact that the degree of contrast between the two colors was low.

The developer then changed the button face color (so that the contrast would be greater between button face and text colors). A variety of system-wide color changes can be made using the SetSysColors function. (This function affects the overall color contrast of a system to make it more readable for the user.)

Another system-wide setting that the developer utilizes is the high contrast setting. This feature sets the appearance scheme associated with the user interface. It allows for maximum visibility for a user with a visual disability. This code has the application utilize the high contrast setting:

// Establish the high contrast structure
HIGHCONTRAST strHighContrast;
// Clear the structure
ZeroMemory(&strHighContrast, sizeof(HIGHCONTRAST));
// request that the confirm hotkey dialog appears after high contrast is set by hotkey
strHighContrast.dwFlags = HCF_CONFIRMHOTKEY;
// set the size of the structure
strHighContrast.cbSize = sizeof(HIGHCONTRAST);
// specify the name of the high contrast scheme
strHighContrast.lpszDefaultScheme = "low visual scheme";
// set the system high contrast value
SystemParametersInfo(SPI_SETHIGHCONTRAST,
sizeof(HIGHCONTRAST), &strHighContrast,  0);

Application-Specific Techniques
As mentioned earlier, application-specific techniques also exist that enable you to change colors within a Windows operating system.

Setting application-specific color involves using Visual C++ drawing functions. These functions, in turn, involve a device context. For example, the SetBkColor changes the background color of the current device context used in the TextOut function. Another function, SetTextColor, is then used to change the text color through the use of a device context.

Let's take a look at some examples. A developer would use this code to change the color of text when drawing within the current device context:

// establish the device context
hDC hDC;
// get the device context of the name edit field
hDC = GetDC(hNameText);
// set the text color of the name edit field to blue
SetTextColor(hDC,  RGB(0,0,255));

It is important to note that if third party controls are used within your application, those controls will already have API functions available to set/reset colors without using device contexts.

Provision K

§1194.21(k) “Software shall not use flashing or blinking text, objects, or other elements having a flash or blink frequency greater than 2 Hz and lower than 55 Hz.”

Visual C++ developers can utilize several programming techniques to prevent (or remediate) flash rate-associated problems. These options involve using the:

SetCaretBlinkTime Function

Use the SetCaretBlinkTime function to change or set the caret/cursor blink time. This function only takes one parameter, the number of milliseconds that elapse before the cursor's pixels are inverted (blink or flash). Therefore, using a blink time of 100 milliseconds would be fast, whereas 1000 milliseconds (1 second) would be slower (10X) by comparison.

Let's take a look at some sample code. This code sets the cursor blink rate to 500 milliseconds (which equals one-half of a second):

SetCaretBlinkTime(500);

The SetCaretBlinkTime function sets the caret blink time to the specified number of milliseconds. The blink time is the elapsed time, in milliseconds, required to invert the caret's pixels.

BOOL SetCaretBlinkTime(
  	UINT uMSeconds   // blink time, in milliseconds
	);

Note that the SetCaretBlinkTime function sets the caret/cursor blink time for the entire system – not just the current application.

GetCaretBlinkTime Function
To determine the current caret/cursor blink rate use the GetCaretBlinkTime function. This function will return the current blink time in milliseconds.

This is an example of the code used to retrieve the current cursor blink rate:

UINT uiCurrentBlinkRate;
uiCurrentBlinkRate = GetCaretBlinkTime();

The GetCaretBlinkTime function returns the time required to invert the caret's pixels (blink the caret). The code necessary to retrieve this information is:

UINT GetCaretBlinkTime(VOID);

Windows Access Protocol Interface
Control Panel accessibility options provide a way for the user to set the blink rate without using Windows Application Programming Interfaces (APIs). It is important to note that using the APIs to get/set the blink rate is the same thing as the Control Panel (and the change is system-wide). You can set/reset the blink rate at anytime by first getting the original system blink rate, changing it, and then restoring the original at a later time.

FlashWindowEx Function
The flash window function is used to flash a window a designated number of times. The actual flash rate can be set to millisecond granularity. In order to enable the flash rate setting, the developer must use the FlashWindowEx function.

This function allows the developer to flash a specified window based on parameters from the FLASHWINFO structure. These parameters include the number of times to flash, the frequency rate of flashing and which part of the window to flash. Code for the FLASHWINDOWEX function is:

BOOL FlashWindowEx(
  PFLASHWINFO pfwi // pointer to the flash status information structure
);

FLASHWINFO Structure Parameters
The FLASHWINFO structure parameters within FlashWindowEx consist of:

UINT cbSize:

Specifies the size, in bytes, of the structure.

HWND hwnd:

Handle to the window to be flashed. The window can be either opened or minimized.

DWORD dwFlags:

Specifies the flash status. This parameter can contain one or more flags.

UINT uCount:

Specifies the number of times to flash the window.

DWORD dwTimeout:

Specifies the rate, in milliseconds, at which the window will be flashed. If DwTimeout is zero, the function uses the default cursor blink rate.

Note that the DWORD dwFlags parameter can contain one or more of the following flags:

Flag

Meaning

FLASHW_STOP

Stop flashing. The system restores the window to its original state.

FLASHW_CAPTION

Flash the window caption.

FLASHW_TRAY

Flash the taskbar button.

FLASHW_ALL

Flash both the window caption and taskbar button. This is equivalent to setting the FLASHW_CAPTION FLASHW_TRAY flags.

FLASHW_TIMER

Flash continuously, until the FLASHW_STOP flag is set.

FLASHW_TIMERNOFG

Flash continuously until the window comes to the foreground.

Let's take a look at some sample code. The outcome of this code is flashing of the window caption ten times at the current system blink rate:

// declare the FLASHWINFO structure
FLASHWINFO strFlashWinfo;
// clear the structure
ZeroMemory(&strFlashWinfo, sizeof(FLASHWINFO));
// set the number of times to flash to 10
strFlashWinfo.uCount = 10;
// only flash the windows caption
strFlashWinfo.dwFlags =  FLASHW_CAPTION;
// specify the window to flash
strFlashWinfo.hwnd = hAlertWindow;
// set the flash rate to the same rate as the system cursor
strFlashWinfo.dwTimeout = 0;
// set the size of the structure
strFlashWinfo.cbSize = sizeof(strFlashWinfo);
// flash the window
FlashWindowEx(&strFlashWinfo);

SPI_SETFOREGROUNDFLASHCOUNT Action (SystemParametersInfo Function)
Another technique available to Visual C++ developers is the SPI_SETFOREGROUNDFLASHCOUNT action of the SystemParametersInfo function. This action sets the count for the number of times the taskbar button will flash if a foreground window switch request is rejected using the SetForegroundWindow function.

This code sets the number of times the taskbar button flashes to three:

// declare the count of flashes
UINT uiNumberFlashes = 3;
// set the foreground flash count
SystemParametersInfo(SPI_SETFOREGROUNDFLASHCOUNT, 0, &uiNumberFlashes, 0);

Provision L

§1194.21(l) “When electronic forms are used, the form shall allow people using assistive technology to access the information, field elements, and functionality required for completion and submission of the form, including all directions and cues.”

Visual C++ developers can utilize keyboard short cuts, left-of-field label identifiers, and internal field names to prevent (or remediate) usability issues associated with electronic forms.

Let's take a look at an instance where these techniques are utilized. This screen capture of an electronic form has been designed to gather specific data from the application's user.

This screen capture is of an electronic form.  Fields present for user completion are identified as "First Name," "Last Name," "Address Line 1," "Address Line 2," "City," and "State."  "OK" and "Cancel" buttons are also present. Each field has a particular letter or number underlined to indicate the shortcut key associated with it.

In order to make this type of form usable for people with disabilities, the developer would utilize the keyboard shortcuts, left-of-field label identifiers, and appropriate internal field names just mentioned.

Keyboard Shortcuts
Keyboard shortcuts are a feature that should always appear in an electronic form. They assist all users in quickly accessing a field – in or out of order. Sole reliance on the Tab key for screen navigation not only limits the user to moving to each item in sequential order, but it also can be extremely cumbersome for users (especially on a large screen). Utilize the Ctrl shortcut key to provide users with quick and easy access to all fields on the form.

Let's take a look at an example. This screen capture of a window shows a data-gathering form used to retrieve name and address information.

This screen capture of an electronic form contains fields that are to be completed by the user.  Fields are labeled "First Name," "Last Name," "Street Address," "City," and "State."  "OK" and "Cancel" buttons are also present. Each field has a particular letter or number underlined to indicate the shortcut key associated with it.

Note that one select letter has been underscored in each text label. The use of the Ctrl key, and entering the underscored letter, allows the user to jump directly to the identified field.

Altering code so that it performs this function involves inserting an ampersand (“&”) in front of one letter of the desired text label name. This screen capture of Visual C++'s Text Properties box illustrates this action for you:

This screen capture is a Visual C++ Text Properties box.  There are three tabs on the top of the box: general, styles and extended styles.  The "General" tab has been selected.  The left side has an ID field that is selectable and the right side has a text input field labeled caption with an ampersand inserted prior to the first word appearing in the field, which in this example is state.  The bottom of the box has six checkboxes for additional options, visible, group, help id, disabled and tab stop.  Visible and group are checked and all fields have a specific letter underlined to denote which access key is associated with it.  In order to provide the user with the ability to use the Ctrl key in this way, the code associated with the action needs to map the Ctrl+S combination. One way to accomplish this is to create an accelerator table.  The accelerator table allows a program to use a variety of keystrokes within any program window.   Any number of tables can be used (the exact number depends on the situation).  In this example code, one table will be created (somewhere in the code before the window appears) that allows the Ctrl+S key combination to be used.

In order to provide the user with the ability to use the Ctrl key in this way, the code associated with the action needs to map the Ctrl+S combination. One way to accomplish this is to create an accelerator table. The accelerator table allows a program to use a variety of keystrokes within any program window. Any number of tables can be used (the exact number depends on the situation). In this example code, one table will be created (somewhere in the code before the window appears) that allows the Ctrl+S key combination to be used.

// declare an accelerator table structure
ACCEL strAccel[2];
// clear the structure
ZeroMemory(&strAccel, sizeof strAccel);
// assign the keystroke CTRL-S to the first element of the structure
strAccel[0].fVirt = FCONTROL;
strAccel[0].key = 19;  //S
// 100 will be used as the identifier
strAccel[0].cmd = 100;
// create the accelerator table
hAccel = CreateAcceleratorTable(strAccel, 1);

In order to capture a user's accelerator keystroke combination, the program must use the TranslateAccelerator function to make the determination. This code would be placed inside the parent window's message loop:

if (!TranslateAccelerator(msg.hwnd, hAccel, &msg))
{
	TranslateMessage(&msg);        // allow input
	DispatchMessage(&msg);
}

Once the message is dispatched to the window's main procedure loop, this test is performed for the appropriate messages and keystrokes:

LRESULT CALLBACK WndMainProc(
    HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
 switch (wMsg)
{
// capture menu item keystrokes here
case WM_COMMAND:
// Our accelerator key?
if (LOWORD(wParam) == 100 && HIWORD(wParam) == 1)
{
switch(LOWORD(wParam))
{
// CTRL+S pressed
case 100:
	MessageBox(0, "You have pressed CTRL+S", "Go directly to the State field.", MB_OK);
	break;
….

The window's main procedure loop will now test for a Ctrl key press match. In this instance, Ctrl+S is pressed. The outcome of this is that the code will direct the screen cursor or caret to the state field on the window dialog screen (making it the current active field).

Field Label Identifiers
When working with labels, an effort should be made to align the label to the left side of each field. Positioning the label in this area allows assistive technology products, such as screen readers, to be able to better identify the field.

It is important to note that the actual field label to the left of the edit field itself is the most important to complete due to the fact that this is the label that assistive devices read first.

Internal Field Names
Utilizing internal field names also provides accessibility to users with disabilities. An internal field name is set by using the "General" tab in Visual C++'s Edit Properties window. Let's take a look at how this can be done.

This screen capture is a Visual C++ Edit Properties box.  There are three tabs on the top of the box: general, styles and extended styles.  The "General" tab has been selected.  The left side has an ID field that is selectable.  The bottom of the box has six checkboxes for additional options, visible, group, help id, disabled and tab stop.  Visible and tab stop are checked and all fields have a specific letter underlined to denote which access key is associated with it.

As you can see, the first name edit field is given an internal relevant name called "IDC_EDIT_FIRSTNAME." The same technique can be applied to all other fields on the screen.