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:

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.

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.

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);
}

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 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.

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.

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.)


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.

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:
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:
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.

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:

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 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.

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).

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.

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.

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:

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.

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.