################################################################################
# TSL-LIBRARY: EMOS_STD_menue_lib
################################################################################
# Copyright (C) 2000 EMOS Computer Consulting GmbH
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# For further information please contact:
#
# Dean Rajovic
# EMOS Computer Consulting GmbH
# Oskar-Messter-Straße 25
# 85737 Ismaning
# Germany
# tel.: +49 89 608 765-0
# mailto:drajovic@emos.de
# http://www.emos.de
################################################################################
# $Revision: 1.1.1.1 $
# $Author: drajovic $
# $Date: 2004/03/24 20:14:03 $
# $Archive: /MERCURY/TSL_PROJECTS/EMOS_GPL/STD/emos_std_menue_lib/script $
# $NoKeywords: $
################################################################################
#**#
#* This library contains alternative implementations for standard functions
#* that operate on menues (menu_x() functions).
#* Another sort of functions in this library are functions that implement some
#* additional functionality that would probably fit into Mercury's logic
#* for menu_x() functions.
#*/
static const COMPLETE_PATH = 1;
static const LAST_ENTRY = 2;
static menu_selection_mode = LAST_ENTRY;
#**
#* Call this function to cause menu_select_item to select the complete menu path.
#* <p>Note:<br>
#* Behaves the same as WinRunner, the only problem is that it does not always work.
#*/
public function EMOS_menu_set_complete_path_selection()
{
menu_selection_mode = COMPLETE_PATH;
}
#**
#* Call this function to cause menu_select_item to select only the last item
#* instead of the complete menu path.
#* <p>Example:<br>
#* instead of calling menu_select_item( "aaa;bbb;ccc" )<br>
#* this mode causes menu_select_item( "ccc" ) to be called
#* <p>Note:<br>
#* This is the default mode.<br>
#* It uses an undocumented feature of WR that appears to work more often than
#* the documented one.
#*/
public function EMOS_menu_set_last_entry_selection()
{
menu_selection_mode = LAST_ENTRY;
}
#**
#* Returns TRUE if COMPLETE_PATH selection is activated.
#* @return TRUE if COMPLETE_PATH selection FALSE otherwise
#*/
public function EMOS_menu_is_complete_path_selection()
{
return (menu_selection_mode == COMPLETE_PATH) ? TRUE : FALSE;
}
#**
#* Returns TRUE if LAST_ENTRY selection is activated.
#* @return TRUE if LAST_ENTRY selection FALSE otherwise
#*/
public function EMOS_menu_is_last_entry_selection()
{
return (menu_selection_mode == LAST_ENTRY) ? TRUE : FALSE;
}
#**
#* This function is specially designed for a particular DOS application. This
#* application has its own representation of a menu bar. WinRunner is capable
#* of recognising text within the menu bar.
#* This function clicks on a particular string (item) within the menu bar.
#*<p> NOTE!
#* Please note that position and size of the menu bar is hard-coded.
#* @param win (in) name of the window that contains the menu bar
#* @param item (in) the string to be selected
#* @return
#* E_OK: Success
#* !E_OK: Error
#*/
public function DOS_menu_select_item( in win, in item )
{
auto rc, arr[], i;
rc=win_find_text( win, item, arr, 5, 23, 1024, 45, TRUE );
if ( rc != E_OK )
return rc;
return win_mouse_click( win, arr[1], arr[2]-23 );
}
#**
#* This function clicks on a menu item without requiring items to be learned.
#* @param item the item to be selected
#* @param win [optional] window where actions are to be performed
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_select_item1 ( in item, in win )
{
auto dummy;
return EMOS_menu_item ( "sel", item, dummy, dummy, dummy, dummy, win );
}
#**
#* This function returns the info of a menu item without requiring items to be learned.
#* @param item the item to be selected
#* @param attr attribute to be examined
#* @param info (out) info retrieved
#* @param win [optional] window where actions are to be performed
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_get_info1 ( in item, in attr, out info, in win )
{
auto dummy;
return EMOS_menu_item ( "get", item, attr, dummy, info, dummy, win );
}
#**
#* This function waits for the info of a menu item without requiring items to be learned.
#* @param item the item to be selected
#* @param attr attribute to be examined
#* @param info info to be waited for
#* @param time [optional] time to be waited for
#* @param win [optional] window where actions are to be performed
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_wait_info1 ( in item, in attr, in info, in time, in win )
{
auto dummy;
return EMOS_menu_item ( "wait", item, attr, info, dummy, time, win );
}
#**
#* This function compares the expected with the actual info of a menu item without requiring items to be learned.
#* @param item the item to be selected
#* @param attr attribute to be examined
#* @param info info to be checked
#* @param win [optional] window where actions are to be performed
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_check_info1 ( in item, in attr, in info, in win )
{
auto dummy;
return EMOS_menu_item ( "chk", item, attr, info, dummy, dummy, win );
}
#**
#* This function implements the actual logic for processing menu items that are not in the GUI-map.
#* @param action action to be performed
#* @param item the item to be selected
#* @param attr [optional] attribute to be examined
#* @param inInfo [optional] info to be used
#* @param outInfo (out) [optional] info to be returned
#* @param time [optional] time to be waited for
#* @param win [optional] window where actions are to be performed
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
static function EMOS_menu_item ( in action, in item, in attr, in inInfo, out outInfo, in time, in window )
{
static const SEP = ";";
static const MENWIN = "EMOS_menu_win";
static const MENFILE = getenv( "TMP" ) & "\\" & "EMOSmenu";
auto win = (window == "") ? GUI_get_window() : window;
auto arr[], count, i;
auto descr, desc, info;
auto item_i, item_n;
auto rc;
count = split( item, arr, SEP );
if ( count < 1 )
return E_ILLEGAL_PARAMETER;
# create & load a temporary GUI-file
rc =GUI_close( MENFILE );
rc+=GUI_buf_new( MENFILE );
rc+=GUI_load( MENFILE );
rc+=GUI_map_get_desc ( win, "", descr, info );
rc+=GUI_add( MENFILE, MENWIN, "", descr );
if ( rc != E_OK )
return rc;
# create the temporary item(s) using names 1;2;...
for ( i=1; i<count+1; i++ )
{
item_i = ( i == 1 ? i : item_i & SEP & i );
item_n = ( i == 1 ? arr[i] : item_n & SEP & arr[i] );
if ( match( arr[i], "#[0-9][0-9]*" ) == 1 )
{
desc = sprintf( "{ class: menu_item, parent: %s, position: %d }"
, (i==1 ? "none" : i-1)
, substr(arr[i], 2)-1 ); # position has offset 0
}
else
{
desc = sprintf( "{ class: menu_item, parent: %s, label: \"%s\" }"
, (i==1 ? "none" : i-1)
, arr[i] );
}
rc+=GUI_add( MENFILE, MENWIN, i, desc );
}
if ( rc != E_OK )
{
GUI_close( MENFILE );
return rc;
}
# perform the selection
rc+=set_window( MENWIN );
# watch this trick
# menu_select_item() is unreliable in its documented form which says
# that subitems must be comma-separated (e.g. menu_select_item( "File;New..." );
# It appears that menu_select_item( "New..." ) not only works but it is also more reliable.
# Here we decide what entry is going to be used
if ( EMOS_menu_is_last_entry_selection() )
item_i = i-1;
FRM_log_obj_info( item_i );
switch ( action )
{
case "sel":
rc+=menu_select_item( item_i );
break;
case "get":
rc+=menu_get_info( item_i, attr, outInfo );
break;
case "wait":
rc+=menu_wait_info( item_i, attr, inInfo, time );
break;
case "chk":
rc+=menu_get_info( item_i, attr, info );
if ( info == inInfo )
{
tl_step( "EMOS_menu_check_info", PASS, sprintf("attr:%s, info:%s", attr, inInfo) );
}
else
{
tl_step( "EMOS_menu_check_info", FAIL, sprintf("attr:%s, exp:%s, act:%s", attr, inInfo, info) );
rc+=E_MISMATCH;
}
break;
default:
rc+=E_ILLEGAL_PARAMETER;
break;
}
# remove the temporary GUI-file
rc+=GUI_close( MENFILE );
#switch back to the original window (if possble)
if ( win_exists( win ) == E_OK )
rc+=set_window( win );
return rc;
}
#**
#* This function clicks on a menu item without requiring items to be learned by
#* untilysing the WinRunner's text recognition cpabilities.
#* <p>NOTE<p>
#* This is an alternative to EMOS_menu_item() when this one does not seem to be
#* stable enough (e.g. position of menu entries changes too often).
#* This worked in very well for some applications that we were punished to test.
#*
#* @param item the item to be selected
#* @param arg_win_desc (in) (optional) physical menu window description [default: { class: object, MSW_id: 0, location: %d }]
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_item_via_text ( in item, in arg_win_desc )
{
static const SEP = ";";
static const DEF_WIN_DESC = "{ class: object, MSW_id: 0, location: %d }";
auto win_desc;
auto arr[], count, i;
auto rc;
if ( arg_win_desc == "" )
win_desc = DEF_WIN_DESC;
else
win_desc = arg_win_desc;
count = split( item, arr, SEP );
if ( count < 1 )
return E_ILLEGAL_PARAMETER;
for ( i=1; i<count+1; i++ )
{
rc+=win_exists( sprintf( win_desc, i-1 ) );
#printf( "win=%s, exists=%s", sprintf( win_desc, i-1 ), rc );
if ( index( arr[i], " " ) )
rc+=win_move_locator_text ( sprintf( win_desc, i-1 ), arr[i], TRUE );
else
rc+=win_move_locator_text ( sprintf( win_desc, i-1 ), arr[i] );
#printf( "%d: item=%s rc=%s", i, arr[i], rc );
if ( rc == E_OK )
click("Left", 2);
}
return rc;
}
#**
#* This function clicks on a menu item without requiring items to be learned.
#* NOTE: It was a nice try that at some point in time worked or at least seemed to.
#* @param item the item to be selected
#* @return
#* E_OK: cuccess
#* !E_OK: failure
#*/
public function EMOS_menu_select_item2 ( in item )
{
auto rc, descr;
rc = menu_get_desc( item, "class label parent", "class_index", "index", descr );
if ( rc != E_OK ) return rc;
return menu_select_item( descr );
}
#**
#* This function implements an alternative for native menu_select_item().
#* Try using it if the native function does not seem to work. For some
#* mysterious reason tis function indeed manages to select more items than the
#* native one. Note the different interface (parameter list).
#* If you need more info, I must disapoint you. You must either dig into the
#* code yourself or try to get in touch with the author. I gave up.
#* @param gui1 (in) gui-File
#* @param win1 (in) window
#* @param men1 (in) menu_item
#* @param win2 (inout) window:
#*<pre> win2 = "" , dann nur Path von menu_item gibt zurück.
#* win2 = "*", dann sucht Name von Window in alle GUI-Filen
#* (wenn Sie wissen nicht, welche Window taucht auf).
#* win2 # "*",dann sucht nicht (wenn Sie wissen, welche Window taucht auf).
#*</pre>
#* @return
#* E_OK: Erfolg
#* !E_OK: 1 - Object != menu-item or menu="sys_" or "parent"="none"
#* 3 - menu-item existiert nicht aufm Bildschirm
#* 4 - keine Beschreibung von aufgerufenem Fenster in GUI-Map
#* 5 - Menu is disabled
#*/
public function EMOS_menu_select_item(in gui1, in win1, in men1, inout win2 )
{
auto rc,gui2,men2;
rc = menu_select_item1(gui1, win1, men1, 3, gui2, win2, men2);
return (rc);
}
#**
#* The empty (does nothing) exception handler needed for menu_select_item1().
#* @param rc (in)
#* @param func (in)
#*/
public function excep1(in rc, in func)
{
# pause("Exception: rc=" & rc & ", func=<\"" & func & "\">");
}
#===============================================================================
# FUNCTION: menu_select_item1
#===============================================================================
# AUTHOR: Slavine
# DESCRIPTION/PURPOSE:
# ruft auf belibiege menu_item
# PARAMETERS:
# in gui1 - gui-File,
# in win1 - window,
# in men1 - menu_item,
# in ttt1 - warten (sec) auf neue window für menu_item(default 3 sec)
# out gui2 - returns name von aufgerufener GUI-File für menu_item
# inout win2: - window:
# win2 = "" , dann nur Path von menu_item gibt zurück.
# win2 = "*", dann sucht Name von Window in alle GUI-Filen
# wenn Sie wissen nicht, welche Window taucht auf.
# win2 # "*",dann sucht nicht (wenn Sie wissen, welche Window taucht auf).
#
# out str_menu - returns string von menu_item (z.B. "File;Open...")
#
# RETURN VALUE:
# E_OK: Erfolg
# !E_OK: 1 - Object != menu-item or menu="sys_" or "parent"="none"
# 3 - menu-item existiert nicht aufm Bildschirm
# 4 - keine Beschreibung von aufgerufenem Fenster in GUI-Map
# 5 - Menu is disabled
#
#===============================================================================
# z.B:
# win2 = "*";
# gui1 = GUI_HOME & "\\Schuecal2000.gui";
#
# rc = open_menu(gui1,"Schuecal2000","Glaspreise",1,gui2, win2 ,str_menu);
# set_window(win2);
#===============================================================================
public function menu_select_item1( in gui, in win1, in men1, in ttt1, out gui2,
inout win2, out menu_str)
{
auto rc,rc1,desc1,t000,num_win,num_gui;
auto hWnd,hWnd1,hWnd2;
auto i,i0,i1,i2,i3,i4,i5,i6,i7,i8;
auto k0,k1,k2,k3,k4,k5,k6,k7,k8;
auto arr1[],windows[],gui1[];
auto rc11,rc12;
#==== warten auf neue Window oder info ==========
if (ttt1 == 0) ttt1 = 3;
#================================================
rc = GUI_buf_get_desc(gui,win1,men1,desc1);
if ( index(desc1,"menu_item") == 0
|| substr(men1,1,4) == "sys_"
|| substr(desc1,index(desc1,"parent:") + 8,6) == "\"none\"")
return(1);
else
{
rc = GUI_list_buffers(gui1, num_gui);
i2 = 1; i3 = 0;
while ( i2 <= length(desc1))
{
k0 = substr(desc1,i2);
i6 = index(k0,"label:");
if (i6 == 0) break;
else
{
k1 = substr(k0,i6);
i4 = index(k1,"\"") + 1;
k2 = substr(k1, i4);
i5 = (index(k2,"\"") < index(k2,"\\") ) ? index(k2,"\"") - 1 : index(k2,"\\") - 1;
arr1[++i3] = substr(k2,1,i5);
i2 = i2 + i6 + i4 + i5 + 1;
}
}
menu_str = arr1[i3];
for( i7 = i3-1; i7 >=1; i7--)
menu_str = menu_str & ";" & arr1[i7];
EMOS_set_window(win1,10);
load("win32api",1,1);
hWnd = GetForegroundWindow();
define_tsl_exception ("menu_get","excep1", E_ANY_ERROR,"menu_get_info");
t000 = getvar("timeout"); setvar("timeout",ttt1);
#------------------------------------------------------
exception_on ("menu_get");
rc = menu_get_info(men1,"enabled",rc1);
exception_off ("menu_get");
#------------------------------------------------------
setvar("timeout",t000);
if (rc != 0) return(3);
if (rc1 == 0) return(5);
if (win2 == "") return(0);
define_tsl_exception ("set_win", "excep1", E_ANY_ERROR,"set_window");
define_tsl_exception ("menu_sel","excep1", E_ANY_ERROR,"menu_select_item");
#------------------------------------------------------
exception_on ("menu_sel");
rc = menu_select_item (men1);
exception_off("menu_sel");
#------------------------------------------------------
if (rc != 0) return(3);
if (win2 != "*")
{
rc = EMOS_set_window(win2,ttt1);
return(0);
}
for( i7 = 1; i7 <= ttt1; i7++)
{
wait(1);
if (hWnd != GetForegroundWindow()) break;
}
if (i7 > ttt1) return(0); # kein aufgerufene Fenster or selbst sich
hWnd1 = GetForegroundWindow();
t000 = getvar("timeout"); setvar("timeout",0);
rc = exception_on ("set_win");
for( i = 1; i <= num_gui; i++ )
{
rc = GUI_list_buf_windows(gui1[i],windows,num_win);
for( i7 = 1; i7 <= num_win; i7++)
{
#-------------------------------
rc1 = set_window(windows[i7],0);
#-------------------------------
if (rc1 == 0)
{
rc = win_get_info(windows[i7],"handle",hWnd2);
if (hWnd1 == hWnd2)
{
gui2 = gui1[i];
win2 = GUI_get_window();
break;
}
}
}
if (hWnd1 == hWnd2) break;
}
rc = exception_off("set_win");
setvar("timeout",t000);
if (i7 <= num_win) return(0);
else return(4);
}
}
###########################################################################
# TSL-LIBRARY: EMOS_STD_menue_lib
###########################################################################