Addressing Toolbar Buttons in Desktop Windows Applications

Applies to TestComplete 15.47, last modified on January 20, 2023

While testing toolbar controls, you can use specific properties and methods of the corresponding program object to perform certain actions and obtain data stored in controls. You can call these methods and properties from your keyword tests, as well as from scripts. This topic describes how to work with the needed properties and methods from your scripts. However, when testing a control from your keyword test, you can use the same methods and properties calling them from keyword test operations. For more information, see Keyword Tests Basic Operations.

To work with toolbar controls in various application types, TestComplete uses special program objects -- Win32ToolBar, StripToolBar and WPFToolBar. These objects provide a similar set of methods and properties, which let you simulate various actions over toolbar buttons and check the state of individual buttons. This topic describes how you can specify toolbar buttons in scripts:

Using Button Captions, Indexes and IDs

You can specify a toolbar button by its caption or position within the toolbar. In most cases, you can specify button by their captions, in the following way:

toolBarObj.ClickItem("New")

For example, the code snippet below clicks the Home button on Internet Explorer’s toolbar.

The following code snippet works with Internet Explorer 11.

JavaScript, JScript

function Test()
{

  // Obtain the IE process and toolbar
  Browsers.Item(btIexplorer).Run("about:blank");
  var browser = Sys.Browser("iexplore");

  var propArray = new Array("WndClass", "WndCaption");
  var valuesArray = new Array("ToolBarWindow32", "Favorites and Tools Bar");

  var toolbar = browser.BrowserWindow(0).FindChild(propArray, valuesArray, 10);
  if (toolbar.Exists)
    // Go to the home page
    toolbar.ClickItem("Ho&me");

}

Python

def Test():

  # Obtain the IE process and toolbar
  Browsers.Item[btIExplorer].Run("about:blank")
  browser = Sys.Browser("iexplore")

  propArray = ["WndClass", "WndCaption"]
  valuesArray = ["ToolBarWindow32", "Favorites and Tools Bar"]

  toolbar = browser.BrowserWindow(0).FindChild(propArray, valuesArray, 10)
  if toolbar.Exists:
    # Go to the home page
    toolbar.ClickItem("Ho&me")

VBScript

Sub Test
Dim browser, toolbar, propArray, valuesArray

  ' Obtain the IE process and toolbar
  Browsers.Item(btIexplorer).Run "about:blank"
  Set browser = Sys.Browser("iexplore")

  propArray = Array("WndClass", "WndCaption")
  valuesArray = Array("ToolBarWindow32", "Favorites and Tools Bar")

  Set toolbar = browser.BrowserWindow(0).FindChild(propArray, valuesArray, 10)
  If toolbar.Exists Then
    ' Go to the home page
    toolbar.ClickItem("Ho&me")
  End If

End Sub

DelphiScript

procedure Test();
var browser, toolbar, propArray, valuesArray;
begin

  // Obtain the IE process and toolbar
  Browsers.Item(btIexplorer).Run('about:blank');
  browser := Sys.Browser('iexplore');

  propArray := ['WndClass', 'WndCaption'];
  valuesArray := ['ToolBarWindow32', 'Favorites and Tools Bar'];

  toolbar := browser.BrowserWindow(0).FindChild(propArray, valuesArray, 10);
  if toolbar.Exists then
    // Go to the home page
    toolbar.ClickItem('Ho&me');

end;

C++Script, C#Script

function Test()
{

  // Obtain the IE process and toolbar
  Browsers["Item"](btIexplorer)["Run"]("about:blank");
  var browser = Sys["Browser"]("iexplore");

  var propArray = new Array("WndClass", "WndCaption");
  var valuesArray = new Array("ToolBarWindow32", "Favorites and Tools Bar");

  var toolbar = browser["BrowserWindow"](0)["FindChild"](propArray, valuesArray, 10);
  if (toolbar["Exists"])
    // Go to the home page
    toolbar["ClickItem"]("Ho&me");

}

If the toolbar does not display the buttons’ text labels, you can find them by using the wButtonText property of the scripting object that corresponds to the tested toolbar (Win32ToolBar, StripToolBar or WPFToolBar).

If toolbar buttons do not have a caption, you can specify it by the index (in other words, by position within the toolbar). Indexes are zero-based: the first button on the toolbar has the index 0, the second - 1, and so on. The total number of buttons on the toolbar is specified by the wButtonCount property. So, the last button has index wButtonCount - 1. For instance, the following instruction will click the fifth button on the toolbar:

toolBarObj.ClickItem(4)

Note: The Win32ToolBar methods and properties have the special ByPosition parameter, which you should set to True when you specify a toolbar button by its index. This parameter lets TestComplete tell the button indexes and IDs apart from each other (see below).

Indexes are continuous throughout the toolbar and do not depend on whether the toolbar occupies one or several rows. You can determine the index of a specific button using the wButtonPos property. Note that separators are also counted as toolbar buttons and thus included in the buttons numeration.

The following script demonstrates how you can specify toolbar buttons by indexes (positions). It iterates through the items in the Quick Launch bar and posts their captions and icons to the test log:

JavaScript, JScript

function ListQuickLaunchItems ()
{
  var p, qlBar, i;

  // Obtain the Quick Launch bar
  p = Sys.Process("Explorer");
  qlBar = p.Window("Shell_TrayWnd").Window("ReBarWindow32").Window("ToolbarWindow32", "Quick Launch");

  // Iterate through Quick Launch items
  for (i = 0; i < qlBar.wButtonCount; i++)
    Log.Picture(qlBar.wImage(i, true), qlBar.wButtonText(i, true));
}

Python

def ListQuickLaunchItems():

  # Obtain the Quick Launch bar
  p = Sys.Process("Explorer")
  qlBar = p.Window("Shell_TrayWnd").Window("ReBarWindow32").Window("ToolbarWindow32", "Quick Launch")

  # Iterate through Quick Launch items
  for i in range(0, qlBar.wButtonCount):
    Log.Picture(qlBar.wImage[i, True], qlBar.wButtonText[i, True])

VBScript

Sub ListQuickLaunchItems
  Dim p, qlBar, i

  ' Obtain the Quick Launch bar
  Set p = Sys.Process("Explorer")
  Set qlBar = p.Window("Shell_TrayWnd").Window("ReBarWindow32").Window("ToolbarWindow32", "Quick Launch")

  ' Iterate through Quick Launch items
  For i = 0 To qlBar.wButtonCount-1
    Call Log.Picture(qlBar.wImage(i, True), qlBar.wButtonText(i, True))
  Next
End Sub

DelphiScript

procedure ListQuickLaunchItems;
var p, qlBar, i : OleVariant;
begin
  // Obtain the Quick Launch bar
  p := Sys.Process('Explorer');
  qlBar := p.Window('Shell_TrayWnd').Window('ReBarWindow32').Window('ToolbarWindow32', 'Quick Launch');

  // Iterate through Quick Launch items
  for i := 0 to qlBar.wButtonCount-1 do
    Log.Picture(qlBar.wImage[i, true], qlBar.wButtonText[i, true]);
end;

C++Script, C#Script

function ListQuickLaunchItems ()
{
  var p, qlBar, i;

  // Obtain the Quick Launch bar
  p = Sys["Process"]("Explorer");
  qlBar = p["Window"]("Shell_TrayWnd")["Window"]("ReBarWindow32")["Window"]("ToolbarWindow32", "Quick Launch");

  // Iterate through Quick Launch items
  for (i = 0; i < qlBar["wButtonCount"]; i++)
    Log["Picture"](qlBar["wImage"](i, true), qlBar["wButtonText"](i, true));
}

If the tested application uses standard Win32 toolbars, you can also specify toolbar buttons by IDs, in addition to captions and indexes. IDs are useful if the button text and/or position changes during the test execution. To determine toolbar button IDs in the tested application, you can use the Win32ToolBar.wButtonID property.

Note that methods and properties of the Win32ToolBar object have the ByPosition parameter, whose purpose is to let TestComplete know whether the Item parameter holds the button position or ID. If you specify the button ID in the Item parameter, you should set the ByPosition parameter to False, otherwise TestComplete will treat the Item value as the button position.

The example below demonstrates the differences when using buttons' indexes and IDs. It works with WordPad, which must be running:

JavaScript, JScript

function Main ()
{
  var p, w, ToolBar;

  // Obtain the WordPad process, its text area and the toolbar
  p = Sys.Process("WORDPAD");
  w = p.Window("WordPadClass").Window("RICHEDIT50W");
  ToolBar = p.Window("WordPadClass").Window("AfxControlBar42u", "Standard").Window("ToolbarWindow32", "Formatting");

  // Click buttons specified by position
  // (Note that the 2nd parameter is True)
  ToolBar.ClickItem(12, true);  // Center
  ToolBar.ClickItem(6, true);  // Bold

  w.Keys("Sample ");

  // Click buttons specified by IDs
  // (Note that the 2nd parameter is False)
  ToolBar.ClickItem(32800, false);  // Italic
  ToolBar.ClickItem(32802, false);  // Underline

  w.Keys("text[Enter]");
}

Python

def Main():

  # Obtain the WordPad process, its text area and the toolbar
  p = Sys.Process("WORDPAD")
  w = p.Window("WordPadClass").Window("RICHEDIT50W")
  ToolBar = p.Window("WordPadClass").Window("AfxControlBar42u", "Standard").Window("ToolbarWindow32", "Formatting")

  # Click buttons specified by position
  # (Note that the 2nd parameter is True)
  ToolBar.ClickItem(12, True)  # Center
  ToolBar.ClickItem(6, True)  # Bold

  w.Keys("Sample ")

  # Click buttons specified by IDs
  # (Note that the 2nd parameter is False)
  ToolBar.ClickItem(32800, False)  # Italic
  ToolBar.ClickItem(32802, False)  # Underline

  w.Keys("text[Enter]")

VBScript

Sub Main
  Dim p, w, ToolBar

  ' Obtain the WordPad process, its text area and the toolbar
  Set p = Sys.Process("WORDPAD")
  Set w = p.Window("WordPadClass").Window("RICHEDIT50W")
  Set ToolBar = p.Window("WordPadClass").Window("AfxControlBar42u", "Standard").Window("ToolbarWindow32", "Formatting")

  ' Click buttons specified by position
  ' (Note that the 2nd parameter is True)
  Call ToolBar.ClickItem(12, True)  ' Center
  Call ToolBar.ClickItem(6, True)  ' Bold

  w.Keys("Sample ")

  ' Click buttons specified by IDs
  ' (Note that the 2nd parameter is False)
  Call ToolBar.ClickItem(32800, False)  ' Italic
  Call ToolBar.ClickItem(32802, False)  ' Underline

  w.Keys("text[Enter]")
End Sub

DelphiScript

procedure Main;
var p, w, ToolBar : OleVariant;
begin
  // Obtain the WordPad process, its text area and the toolbar
  p := Sys.Process('WORDPAD');
  w := p.Window('WordPadClass').Window('RICHEDIT50W');
  ToolBar := p.Window('WordPadClass').Window('AfxControlBar42u', 'Standard').Window('ToolbarWindow32', 'Formatting');

  // Click buttons specified by position
  // (Note that the 2nd parameter is True)
  ToolBar.ClickItem(12, true);  // Center
  ToolBar.ClickItem(6, true);  // Bold

  w.Keys('Sample ');

  // Click buttons specified by IDs
  // (Note that the 2nd parameter is False)
  ToolBar.ClickItem(32800, false);  // Italic
  ToolBar.ClickItem(32802, false);  // Underline

  w.Keys('text[Enter]');
end;

C++Script, C#Script

function Main ()
{
  var p, w, ToolBar;

  // Obtain the WordPad process, its text area and the toolbar
  p = Sys["Process"]("WORDPAD");
  w = p["Window"]("WordPadClass")["Window"]("RICHEDIT50W");
  ToolBar = p["Window"]("WordPadClass")["Window"]("AfxControlBar42u", "Standard")["Window"]("ToolbarWindow32", "Formatting");

  // Click buttons specified by position
  // (Note that the 2nd parameter is True)
  ToolBar["ClickItem"](12, true);  // Center
  ToolBar["ClickItem"](6, true);  // Bold

  w["Keys"]("Sample ");

  // Click buttons specified by IDs
  // (Note that the 2nd parameter is False)
  ToolBar["ClickItem"](32800, false);  // Italic
  ToolBar["ClickItem"](32802, false);  // Underline

  w["Keys"]("text[Enter]");
}

Using Case-Sensitive and Case-Insensitive Button Captions

Depending on the Use case-sensitive parameters project option, TestComplete treats captions of toolbar buttons as case-sensitive or case-insensitive. By default, this option is turned off, so that you can specify the button caption in any case (all upper case, all lower case, mixed case, and so on):

toolBarObj.ClickItem("Bold")

toolBarObj.ClickItem("BOLD")

toolBarObj.ClickItem("bold")

toolBarObj.ClickItem("BoLd")

If the Use case-sensitive parameters is checked, you can only specify button captions using the correct case:

toolBarObj.ClickItem("Bold")  // Correct

toolBarObj.ClickItem("bold")  // Incorrect!!!

Using Wildcards and Regular Expressions in Button Captions

If captions of toolbar buttons change according to the current context, it may be useful to specify buttons only by constant parts of their names. To specify arbitrary parts in item names, TestComplete lets you use wildcard characters (* and ?) or regular expressions. The asterisk (*) corresponds to a string of any length (including an empty string), the question mark corresponds to any single character (including none). To specify more complicated parts of a caption, use regular expressions.

To illustrate the wildcards usage, suppose that the tested application’s toolbar contains the Undo button, whose caption depends on the undo buffer: if there is an action to undo, the button caption contains the Undo word and the action name (for example, Undo Typing or Undo Paste); if there are no actions to undo, the button caption is Can't Undo. In order to ensure stable recognition of the Undo button whatever name it has, you can replace variable parts of its name with the * wildcard:

toolBarObj.ClickItem("*Undo*")

In this example, we place the wildcard on both sides of the Undo word, since it can either precede or follow other text.

Specifying Buttons in Owner-Drawn Toolbars

If the toolbar in the tested application is owner-drawn, it is recommended that you specify toolbar buttons using IDs. For more information, see Working With Owner-Drawn ToolBars in Desktop Windows Applications.

See Also

Working With Toolbars in Desktop Windows Applications

Highlight search results