Selecting Menu Items in Desktop Windows Applications

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

While testing menu 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.

One of the actions that you would perform the most over a menu is selecting its individual items. This topic explains various approaches that can be used to select a menu item by simulating mouse and keyboard actions, check and uncheck menu items and hot-track them.

Simulating Clicks on Menu Items

To simulate a mouse click on a menu item, use the Menu.Click method. This method only has the “path” parameter for the item you want to click. The path consists of item names or indexes separated with the pipeline character ( | ). Note that it is possible to use wildcards (* and ?) to specify item names in the path. For more information on the item path syntax, see Addressing Menu Items in Desktop Windows Applications.

JavaScript, JScript

function Test()
{
  var w = Sys.Process("notepad").Window("Notepad", "*");
  w.MainMenu.Click("File|Open...");
  // You can also address menu items by indexes --
  // w.MainMenu.Click("[0]|[1]");
}

Python

def Test():
  w = Sys.Process("notepad").Window("Notepad", "*")
  w.MainMenu.Click("File|Open...")
  # You can also address menu items by indexes --
  # w.MainMenu.Click("[0]|[1]")

VBScript

Sub Test
  Set w = Sys.Process("notepad").Window("Notepad", "*")
  w.MainMenu.Click("File|Open...")
  ' You can also address menu items by indexes --
  ' w.MainMenu.Click("[0]|[1]")
End Sub

DelphiScript

procedure Test;
var w : OleVariant;
begin
  w := Sys.Process('notepad').Window('Notepad', '*');
  w.MainMenu.Click('File|Open...');
  // You can also address menu items by indexes --
  // w.MainMenu.Click('[0]|[1]');
end;

C++Script, C#Script

function Test()
{
  var w = Sys["Process"]("notepad")["Window"]("Notepad", "*");
  w["MainMenu"]["Click"]("File|Open...");
  // You can also address menu items by indexes --
  // w["MainMenu"]["Click"]("[0]|[1]");
}

Selecting Menu Items Using Keyboard Shortcuts

Most menu items have access keys -- these are the keys that allow the user to select a menu item from the keyboard when the menu is opened. Access keys usually appear underlined in the menu item names: File, Edit, Exit, and so on (if you do not see underlined characters in item names, try hitting Alt).

In order to select a menu item using its access key, the menu should be opened first. To open a main menu category, you should press the category’s access key in combination with the Alt key (for example, Alt+F will open the File menu). To open the system menu, use the Alt+Space shortcut; the context menu can be called using the Application key. To select an item in the currently opened menu, press the item’s access key, without any additional keys. For instance, to select the Copy command in the context menu, you should press the Application key (this will invoke the menu), and then press C (this will select the Copy command).

In TestComplete, you can simulate keystrokes using the Keys action. This action should be applied to the application’s window that has the main menu or a control that has a context menu. Alternatively, you can use the Sys.Keys method, which will send the keypresses to the currently active window or control. The access keys are case-insensitive, so Keys("F") and Keys("f") will have the same result. The following example demonstrates how you can select menu items in Notepad using access keys:

JavaScript, JScript

function Test()
{
  // Obtain the Notepad's window
  var w = Sys.Process("notepad").Window("Notepad", "*");

  // Select the "File | Open..." command
  w.Keys("~fo");
}

Python

def Test():
  # Obtain the Notepad's window
  w = Sys.Process("notepad").Window("Notepad", "*")

  # Select the "File | Open..." command
  w.Keys("~fo")

VBScript

Sub Test
  ' Obtain the Notepad's window
  Set w = Sys.Process("notepad").Window("Notepad", "*")

  ' Select the "File | Open..." command
  w.Keys("~fo")
End Sub

DelphiScript

procedure Test;
var w : OleVariant;
begin
  // Obtain the Notepad's window
  w := Sys.Process('notepad').Window('Notepad', '*');

  // Select the "File | Open..." command
  w.Keys('~fo');
end;

C++Script, C#Script

function Test()
{
  // Obtain the Notepad's window
  var w = Sys["Process"]("notepad")["Window"]("Notepad", "*");

  // Select the "File | Open..." command
  w["Keys"]("~fo");
}

Most frequently used menu items usually have special keyboard shortcuts assigned. For instance, Ctrl+C is a common shortcut for the Edit | Copy command; Ctrl+S is a shortcut for Notepad’s File | Save command; and so on. If a menu item has a shortcut, you can quickly select the item from tests by simulating the shortcut. The difference between the shortcuts and access keys is that the access key selects a menu item when the menu is opened, whereas the shortcut selects a menu item without the menu being opened.

Below is a code snippet that inserts the current date and time into Notepad’s window by using the F5 shortcut rather than selecting the Edit | Time/Date command:

JavaScript, JScript

function Test()
{
  var w = Sys.Process("notepad").Window("Notepad", "*");
  w.Keys("[F5]");
  // The line above has the same result as
  // w.MainMenu.Click("Edit|Time/Date");
}

Python

def Test():
  w = Sys.Process("notepad").Window("Notepad", "*")
  w.Keys("[F5]")
  # The line above has the same result as
  # w.MainMenu.Click("Edit|Time/Date")

VBScript

Sub Test
  Set w = Sys.Process("notepad").Window("Notepad", "*")
  w.Keys("[F5]")
  ' The line above has the same result as
  ' w.MainMenu.Click("Edit|Time/Date")
End Sub

DelphiScript

procedure Test;
var w : OleVariant;
begin
  w := Sys.Process('notepad').Window('Notepad', '*');
  w.Keys('[F5]');
  // The line above has the same result as
  // w.MainMenu.Click('Edit|Time/Date');
end;

C++Script, C#Script

function Test()
{
  var w = Sys["Process"]("notepad")["Window"]("Notepad", "*");
  w["Keys"]("[F5]");
  // The line above has the same result as
  // w["MainMenu"]["Click"]("Edit|Time/Date");
}

Checking and Unchecking Menu Items

Some menu items represent options that can be checked or unchecked, this way enabling or disabling a specific application feature. An example is Notepad’s Format | Word Wrap option. To check or uncheck these menu items from tests, you can use the Menu.Check method. This method has two parameters: Item, that specifies the “full path” to the desired item (see Addressing Menu Items in Desktop Windows Applications), and Checked that specifies the desired item state - True (checked) or False (unchecked). To determine if the menu item is checked or unchecked, use the Checked property of the MenuItem object corresponding to this item.

The code snippet below demonstrates how you can toggle Notepad’s Format | Word Wrap menu item:

JavaScript, JScript

function Test()
{
  var w = Sys.Process("notepad").Window("Notepad", "*");
  var Checked = w.MainMenu.Items(2).SubMenu.Items(0).Checked;
  w.MainMenu.Check("Format|Word Wrap", ! Checked);
  // You can also address menu items by indexes --
  // w.MainMenu.Check("[2]|[0]", ! Checked);
}

Python

def Test():
  w = Sys.Process("notepad").Window("Notepad", "*")
  Checked = w.MainMenu.Items[2].SubMenu.Items[0].Checked
  w.MainMenu.Check("Format|Word Wrap", not Checked)
  # You can also address menu items by indexes --
  # w.MainMenu.Check("[2]|[0]", ! Checked)

VBScript

Sub Test
  Set w = Sys.Process("notepad").Window("Notepad", "*")
  Checked = w.MainMenu.Items(2).SubMenu.Items(0).Checked
  Call w.MainMenu.Check("Format|Word Wrap", Not Checked)
  ' You can also address menu items by indexes --
  ' Call w.MainMenu.Check("[2]|[0]", Not Checked)
End Sub

DelphiScript

procedure Test;
var w, Checked : OleVariant;
begin
  w := Sys.Process('notepad').Window('Notepad', '*');
  Checked := w.MainMenu.Items[2].SubMenu.Items[0].Checked;
  w.MainMenu.Check('Format|Word Wrap', not Checked);
  // You can also address menu items by indexes --
  // w.MainMenu.Check('[2]|[0]', not Checked);
end;

C++Script, C#Script

function Test()
{
  var w = Sys["Process"]("notepad")["Window"]("Notepad", "*");
  var Checked = w["MainMenu"]["Items"](2)["SubMenu"]["Items"](0)["Checked"];
  w["MainMenu"].Check("Format|Word Wrap", ! Checked);
  // You can also address menu items by indexes --
  // w["MainMenu"]["Check"]("[2]|[0]", ! Checked);
}

Hot-Tracking Menu Items

In certain cases, you may need to hot-track the menu item (that is, to select it without executing it). For example, you may need to check whether a submenu is invoked when an item is selected. To hot-track a menu item, use the Menu.Select method. It works similar to Menu.Click, but does not simulate a click on the specified item.

The example below “runs through” the items in Notepad’s File menu using the Menu.Select method:

JavaScript, JScript

function Test()
{
  var w, FileMenu, i;

  w = Sys.Process("notepad").Window("Notepad", "*");

  FileMenu = w.MainMenu.Items(0).SubMenu;
  for (i=0; i<FileMenu.Count; i++)
    if (! FileMenu.Items(i).IsSeparator)
    {
      w.MainMenu.Select("File|[" + i + "]");
      aqUtils.Delay (200);
    }
}

Python

def Test():

  w = Sys.Process("notepad").Window("Notepad", "*")

  FileMenu = w.MainMenu.Items[0].SubMenu
  for i in range(0, FileMenu.Count):
    if not FileMenu.Items[i].IsSeparator:
      w.MainMenu.Select("File|[" + str(i) + "]")
      aqUtils.Delay (200)

VBScript

Sub Test
  Dim w, FileMenu, i

  Set w = Sys.Process("notepad").Window("Notepad", "*")

  Set FileMenu = w.MainMenu.Items(0).SubMenu
  For i = 0 To FileMenu.Count-1
    If Not FileMenu.Items(i).IsSeparator Then
      w.MainMenu.Select("File|[" & i & "]")
      aqUtils.Delay (200)
    End If
  Next
End Sub

DelphiScript

procedure Test;
var w, FileMenu, i : OleVariant;
begin
  w := Sys.Process('notepad').Window('Notepad', '*');

  FileMenu := w.MainMenu.Items[0].SubMenu;
  for i := 0 to FileMenu.Count-1 do
    if not FileMenu.Items[i].IsSeparator then
    begin
      w.MainMenu.Select('File|[' + aqConvert.VarToStr(i) + ']');
      aqUtils.Delay(200)
    end
end;

C++Script, C#Script

function Test()
{
  var w, FileMenu, i;

  w = Sys["Process"]("notepad")["Window"]("Notepad", "*");

  FileMenu = w["MainMenu"]["Items"](0)["SubMenu"];
  for (i=0; i<FileMenu["Count"]; i++)
    if (! FileMenu["Items"](i)["IsSeparator"])
    {
      w["MainMenu"]["Select"]("File|[" + i + "]");
      aqUtils["Delay"] (200);
    }
}

See Also

Working With Menus in Desktop Windows Applications
Addressing Menu Items in Desktop Windows Applications
Working With Third-Party Menus in Desktop Windows Applications
Click Action (Menu Controls)
Check Action (Menu Controls)
Select Action (Menu Controls)
Keys Action

Highlight search results