F 3.6. Common Window Functions

3.6. Common Window Functions

The Win32 functions can be applied to everything that is defined as being a window. Though not truely object oriented in the C plus plus sense, you can think of a window as being an abstract class and having all of the window functions mentioned. The function GetText, whose parameters are a handle to the window, the destination string and the maximum length of the string, gives the text contained in a window. The text depends on the type: for buttons it is their label, for text fields the field contents and for windows having title-bars the title text. Another universal window function is GetClassName which finds out the name of the window's class. The parameters are exactly the same as with GetWindowText. In the example program, the HandleCommon function gives generic information on a control (window) and uses both of the functions mentioned:

GetClassName(hWindow, textBuf, MAX_TEXT_LENGTH);
// ...
GetWindowText(hWindow, textBuf, MAX_TEXT_LENGTH);

The class name for a window can be used, to a certain extend, as the basis for control type recognition. According to Dolphin Computer Access, however, some screen readers use this way exclusively: Some of the traditional Windows screen readers rely solely on the "class name" or "class atom of a window in order to identify what type of control it is." (Dolphin Computer Access, 2001, "Accessibility Issues"). Frequently the mere class name isn't enough to reliably identify the control. This applies to state information and sub-classed custom controls e.g. toolbar buttons that are really radio buttons.

Another useful window function is EnumChildWindows which can be used to traverse all of the children of a window (such as dialog contents). In screen reading, you could use this function to build up the off-screen model. In the hooklib dll we use the enumeration function to go through some of the children for the window being activated, mostly for the sake of demonstrating, though.

else if(ncode == HCBT_ACTIVATE && ((HWND) wParam) != hObserver)
{ // Get the children of the window being activated.
	HWND hWindow = (HWND) wParam;
	lstrcat(textOut, "Active window ");
	handleCommon(hWindow);
	lstrcat(textOut, "\r\nChildren:\r\n");
	EnumChildWindows(hWindow, enumerateDirectDescendants, (LPARAM) hWindow);
	notifyObserver();
} // else if
In addition to the window handle, the parameter list for EnumChildWindows includes an address of an enumerator function and the lParam passed to that function, which in the above example is the handle to the parent window. For the callback function (enumerateDirectDescendants) we pass the child's window handle and also the third parameter for EnumChildWindows gets passed in implicitly. Traversing the windows stops if all the windows have been traversed or if the enumerator function returns false (as it does in the example).
BOOL CALLBACK enumerateDirectDescendants(HWND hwnd, LPARAM lParam)
{
	if(GetParent(hwnd) == ((HWND) lParam))
	{ // Only if it's a direct descendant.
		lstrcat(textOut, "-");
		handleControls(hwnd);
		lstrcat(textOut, "\r\n");
	} // if
	return TRUE;
} // enumerateDirectDescendants
In order to save space in the text field, the enumerator only handles the first level or direct children of the window being enumerated. That is only windows whose parent is the window for which EnumChildWindows got called.

Back to the Contents