Linköpings universitet Institutionen för datavetenskap Final Thesis Communication Interface between Rational Robot and Qt objects by Nasir Uddin Ahmed LiTH-IDA-EX--03/078--SE 2003-12-17 Supervisor: Magnus Werner Examiner: Henrik Eriksson Abstract Automated black box, GUI-level regression test tools are popular in the industry. Currently, IBM Rational Robot being one of the best testing tools supports wide verity of integrated development environments (IDEs) and languages. Unfortunately it does not support Qt, the multiplatform C++ GUI toolkit. The excellent documentation, clean interface, and a sensible approach to the object oriented paradigm makes Qt one of the most popular GUI toolkits in the world. The project describes why Rational Robot cannot recognize the Qt objects and their properties. The findings show that Qt objects lack Windows message handlers and all objects register their class names with the same parent object name instead of their own class name. The project describes two different solutions for the problem. The first solution is very strait, Qt kernel has been modified and message handlers have been added. In the second solution, Qt object windows have been sub classed and inter process communication has been used. These two solutions have been evaluated. Keywords Automated testing tools, C++, inter process communication, Qt, Rational Robot, test automation, Windows messages, window sub classing. i Acknowledgements My sincere and hearty gratitude needs to be expressed to a number of people who made this thesis possible. I am deeply grateful to my supervisor Magnus Werner for his support and patience, and for his kindness and his great enthusiasm for the project, which have made it a tremendous pleasure and inspiration to work with him. Per Burman was also of great assistance in the preparatory phase of this thesis. Thanks also go to all these people and many others I met at Saab Training Systems AB, who helped in small but important ways. I would also like to thank my examiner, Henrik Eriksson, for all the suggestions, feedback and guidance I have received throughout the project. Out with the work setting, I would also like to offer my fondest regards to my parents, sister and friends for their support and encouragement. iii Contents INTRODUCTION ........................................................................................................................................ 1 1.1 BACKGROUND ..................................................................................................................................... 1 1.2 GOAL ................................................................................................................................................... 1 1.3 LIMITATIONS ....................................................................................................................................... 2 THEORETICAL BACKGROUND ............................................................................................................ 3 2.1 INTRODUCTION.................................................................................................................................... 3 2.2 WINDOWS PROGRAMMING ................................................................................................................. 3 2.3 WINDOWS MESSAGES ......................................................................................................................... 3 2.4 MESSAGE TYPES ................................................................................................................................. 5 2.4.1 System-Defined Messages ........................................................................................................... 5 2.4.2 Application-Defined Messages ................................................................................................... 6 2.5 MESSAGE ROUTING ............................................................................................................................ 6 2.5.1 Queued Messages ........................................................................................................................ 6 2.5.2 Nonqueued Messages .................................................................................................................. 7 2.6 MESSAGE HANDLING .......................................................................................................................... 8 2.6.1 Message Loop .............................................................................................................................. 8 2.7 MESSAGE FILTERING .......................................................................................................................... 9 2.8 POSTING AND SENDING MESSAGES .................................................................................................... 9 2.8.1 Posting Messages ........................................................................................................................ 9 2.8.2 Sending Messages ....................................................................................................................... 9 2.9 WINDOW CLASSES .............................................................................................................................10 2.9.1 Types of Window Classes ...........................................................................................................10 2.9.2 How the System Locates a Window Class .................................................................................12 2.9.3 Registering a Window Class ......................................................................................................12 2.9.4 Elements of a Window Class ......................................................................................................13 2.10 ABOUT WINDOW PROCEDURES .......................................................................................................15 2.10.1 Structure of a Window Procedure ...........................................................................................15 2.10.2 Default Window Procedure ......................................................................................................15 2.11 SUBCLASSING WINDOW ...................................................................................................................15 2.11.1 Types of Subclassing ................................................................................................................16 2.12 QT FOR WINDOWS ............................................................................................................................16 2.12 RATIONAL ROBOT ............................................................................................................................17 ANALYSIS ...................................................................................................................................................19 3.1 INTRODUCTION...................................................................................................................................19 3.2 HOW RATIONAL ROBOT INTERACTS WITH OBJECT .........................................................................19 3.3 WHY RATIONAL ROBOT CANNOT RECOGNIZE QT OBJECTS? ..........................................................20 3.4 WHY RATIONAL ROBOT CANNOT READ ATTRIBUTES OF AN OBJECT?.............................................21 TECHNICAL SOLUTIONS .......................................................................................................................23 4.1 INTRODUCTION...................................................................................................................................23 4.2 EXISTING WORK FLOW.......................................................................................................................23 4.2.1 Object Creation Operation .........................................................................................................23 4.2.2 Message Handling Operation ....................................................................................................24 v 4.3 PROPOSED OPERATION FLOW ............................................................................................................25 4.3.1 Object Creation Operation .........................................................................................................25 4.3.2 Message Handling Operation ....................................................................................................26 4.4 ALTERNATIVE SOLUTION ..................................................................................................................26 IMPLEMENTATION .................................................................................................................................29 5.1 INTRODUCTION...................................................................................................................................29 5.2 SOFTWARE TOOLS .............................................................................................................................29 5.2.1 Visual Studio 6 ...........................................................................................................................29 5.2.2 Qt Designer.................................................................................................................................29 5.2.3 Microsoft SPY++ ........................................................................................................................30 5.3 CODING AND TESTING........................................................................................................................30 5.3.1 Modifying the Qt kernel .............................................................................................................30 5.3.2 Alternative solution ....................................................................................................................31 CONCLUSION ............................................................................................................................................33 6.1 IMPLEMENTATION RESULTS ..............................................................................................................33 6.2 IMPLEMENTATION DIFFICULTIES......................................................................................................34 6.3 SUMMARY ...........................................................................................................................................34 6.4 FUTURE WORK ...................................................................................................................................35 BIBLIOGRAPHY .......................................................................................................................................37 APPENDIX A TERMINOLOGY .............................................................................................................39 APPENDIX B LIST OF WINDOWS MESSAGES .................................................................................41 vi Chapter 1 Introduction 1.1 Background Testing is an important activity in the software development process, aiming at uncovering and correcting errors in the software. Since this activity is time-consuming and resource-intensive, parts of the testing process are automated. Automated software testing helps improve testers’ productivity. It increases test coverage levels, speeds up test turnaround time and cuts costs of testing. To automate the test IBM Rational Robot is widely used. With Rational Robot any one can create, modify, and execute automated functional, distributed functional, regression and smoke tests for software applications that are built using a wide variety of integrated development environments (IDEs) and languages. Unfortunately it does not support Qt, the multi-platform C++ GUI toolkit. Qt is a multiplatform, C++ application framework that lets developers write one application that will run natively on Windows, Linux/Unix, Mac OS X, and embedded Linux with a simple recompile. It is elegant, intuitive, completely object oriented. Saab Training Systems AB is using Qt to build ExPERT, the software for planning & preparation, data initializations, exercise execution and analysis & evaluation of military training. So, they felt for a communication interface between Qt and Rational Robot to test ExPERT automatically. 1.2 Goal The goal of this project was to design and implement an interface between Qt and Rational Robot. With this interface Rational Robot should perform the following actions: Record scripts of Qt applications Run previously recorded scripts Read the various properties of the Qt objects Insert verification points of any type. 1 1.3 Limitations SAAB Training Systems is very much interested to test ExPERT with Rational Robot. The original implementation only handles the Qt objects that are used in the ExPERT. Due to the limited resources, it does not include the design and implementation of the full communication interface between Qt toolkit objects and Rational Robot. 2 Chapter 2 Theoretical Background 2.1 Introduction The purpose of this chapter is to give the reader an opportunity to acquire the knowledge needed to fully understand the thesis work. The windows programming fundamentals, window classes and messages will be discussed here. 2.2 Windows Programming Unlike MS-DOS-based applications, Windows-based applications are event-driven. They do not make explicit function calls (such as C run-time library calls) to obtain input. Instead, they wait for the system to pass input to them. The system passes all input for an application to the various windows in the application. Each window has a function, called a window procedure that the system calls whenever it has input for the window. The window procedure processes the input and returns control to the system. 2.3 Windows Messages The system passes input to a window procedure in the form of messages. Messages are generated by both the system and applications. The system generates a message at each input event for example, when the user types, moves the mouse, or clicks a control such as a scroll bar. The system also generates messages in response to changes in the system brought about by an application, such as when an application changes the pool of system font resources or resizes one of its windows. An application can generate messages to direct its own windows to perform tasks or to communicate with windows in other applications [3]. The system sends a message to a window procedure with a set of four parameters: a window handle, a message identifier, and two values called message parameters. The window handle identifies the window for which the message is intended. The system uses it to determine which window procedure should receive the message. 3 WM_PAINT WM_KEYDOW N WM_COMMAN D WM_LBUTTON DOWN WM_SIZE Message Queue (Retrieved Message) Application WinMain() Message Loop Window Procedure (Dispatched Message) Message Handler Message Handler Message Handler Message Handler Message Handler Message Handler (Unprocessed Messages) DefWindowProc Figure 2.1 Message handling of a win32 application A message identifier is a named constant that identifies the purpose of a message. When a window procedure receives a message, it uses a message identifier to determine how to process the message. For example, the message identifier WM_PAINT tells the window procedure that the window's client area has changed and must be repainted. Message parameters specify data or the location of data used by a window procedure when processing a message. The meaning and value of the message parameters depend 4 on the message. A message parameter can contain an integer, packed bit flags, a pointer to a structure containing additional data, and so on. When a message does not use message parameters, they are typically set to NULL. A window procedure must check the message identifier to determine how to interpret the message parameters. Figure 2.1 shows how messages are handled by the application. 2.4 Message Types This section describes the two types of messages: System-Defined Messages Application-Defined Messages 2.4.1 System-Defined Messages The system sends or posts a system-defined message when it communicates with an application. It uses these messages to control the operations of applications and to provide input and other information for applications to process. An application can also send or post system-defined messages. Applications generally use these messages to control the operation of control windows created by using pre-registered window classes. Prefix BM CB DTM EM HDM HKM IPM LB LVM SB SBM STM TB TCM TVM WM Message category Button control Combo box control Date and time picker control Edit control Header control Hot key control IP adress control List box control List view control Status bar window Scroll bar control Static control Toolbar Tab control Tree-view control General window Table 2.1 prefixes and their related message categories 5 Each system-defined message has a unique message identifier and a corresponding symbolic constant (defined in the software development kit (SDK) header files) that states the purpose of the message. For example, the WM_PAINT constant requests that a window paint its contents. Symbolic constants specify the category to which system-defined messages belong. The prefix of the constant identifies the type of window that can interpret and process the message. Table 2.1 contains the example prefixes and their related message categories. General window messages cover a wide range of information and requests, including messages for mouse and keyboard input, menu and dialog box input, window creation and management, and Dynamic Data Exchange (DDE). 2.4.2 Application-Defined Messages An application can create messages to be used by its own windows or to communicate with windows in other processes. If an application creates its own messages, the window procedure that receives them must interpret the messages and provide appropriate processing. 2.5 Message Routing The system uses two methods to route messages to a window procedure: posting messages to a first-in, first-out queue called a message queue, a system-defined memory object that temporarily stores messages, and sending messages directly to a window procedure. Messages posted to a message queue are called queued messages. They are primarily the result of user input entered through the mouse or keyboard, such as WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, and WM_CHAR messages. Other queued messages include the timer, paint, and quit messages: WM_TIMER, WM_PAINT, and WM_QUIT. Most other messages, which are sent directly to a window procedure, are called nonqueued messages. 2.5.1 Queued Messages The system can display any number of windows at a time. To route mouse and keyboard input to the appropriate window, the system uses message queues. The system maintains a single system message queue and one thread-specific message queue for each graphical user interface (GUI) thread. To avoid the overhead of creating a message queue for nonGUI threads, all threads are created initially without a message queue. The system creates a thread-specific message queue only when the thread makes its first call to one of the User or Windows Graphics Device Interface (GDI) functions. Whenever the user moves the mouse, clicks the mouse buttons, or types on the keyboard, the device driver for the mouse or keyboard converts the input into messages and places 6 them in the system message queue. The system removes the messages, one at a time, from the system message queue, examines them to determine the destination window, and then posts them to the message queue of the thread that created the destination window. A thread's message queue receives all mouse and keyboard messages for the windows created by the thread. The thread removes messages from its queue and directs the system to send them to the appropriate window procedure for processing. With the exception of the WM_PAINT message, the system always posts messages at the end of a message queue. This ensures that a window receives its input messages in the proper first in, first out (FIFO) sequence. The WM_PAINT message, however, is kept in the queue and is forwarded to the window procedure only when the queue contains no other messages. Multiple WM_PAINT messages for the same window are combined into a single WM_PAINT message, consolidating all invalid parts of the client area into a single area. Combining WM_PAINT messages reduces the number of times a window must redraw the contents of its client area. The system posts a message to a thread's message queue by filling an MSG structure and then copying it to the message queue. Information in MSG includes: the handle of the window for which the message is intended, the message identifier, the two message parameters, the time the message was posted, and the mouse cursor position. A thread can post a message to its own message queue or to the queue of another thread by using the PostMessage or PostThreadMessage function. An application can remove a message from its queue by using the GetMessage function. To examine a message without removing it from its queue, an application can use the PeekMessage function. This function fills MSG with information about the message. After removing a message from its queue, an application can use the DispatchMessage function to direct the system to send the message to a window procedure for processing. DispatchMessage takes a pointer to MSG that was filled by a previous call to the GetMessage or PeekMessage function. DispatchMessage passes the window handle, the message identifier, and the two message parameters to the window procedure. 2.5.2 Nonqueued Messages Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue. The system typically sends nonqueued messages to notify a window of events that affect it. For example, when the user activates a new application window, the system sends the window a series of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR. These messages notify the window that it has been activated, that keyboard input is being directed to the window, and that the mouse cursor has been moved within the borders of the window. 7 2.6 Message Handling An application must remove and process messages posted to the message queues of its threads. A single-threaded application usually uses a message loop in its WinMain function to remove and send messages to the appropriate window procedures for processing. Applications with multiple threads can include a message loop in each thread that creates a window. 2.6.1 Message Loop A simple message loop consists of one function call to each of these three functions: GetMessage, TranslateMessage, and DispatchMessage. Note that if there is an error, GetMessage returns -1 -- thus the need for the special testing. The GetMessage function retrieves a message from the queue and copies it to a structure of type MSG. It returns a nonzero value, unless it encounters the WM_QUIT message, in which case it returns FALSE and ends the loop. In a single-threaded application, ending the message loop is often the first step in closing the application. An application can end its own loop by using the PostQuitMessage function, typically in response to the WM_DESTROY message in the window procedure of the application's main window. A thread's message loop must include TranslateMessage if the thread is to receive character input from the keyboard. The system generates virtual-key messages (WM_KEYDOWN and WM_KEYUP) each time the user presses a key. A virtual-key message contains a virtual-key code that identifies which key was pressed, but not its character value. To retrieve this value, the message loop must contain TranslateMessage, which translates the virtual-key message into a character message (WM_CHAR) and places it back into the application message queue. The character message can then be removed upon a subsequent iteration of the message loop and dispatched to a window procedure. The DispatchMessage function sends a message to the window procedure associated with the window handle specified in the MSG structure. If the window handle is HWND_TOPMOST, DispatchMessage sends the message to the window procedures of all top-level windows in the system. If the window handle is NULL, DispatchMessage does nothing with the message. An application's main thread starts its message loop after initializing the application and creating at least one window. Once started, the message loop continues to retrieve messages from the thread's message queue and to dispatch them to the appropriate windows. The message loop ends when the GetMessage function removes the WM_QUIT message from the message queue. Only one message loop is needed for a message queue, even if an application contains many windows. DispatchMessage always dispatches the message to the proper window; 8 this is because each message in the queue is an MSG structure that contains the handle of the window to which the message belongs. 2.7 Message Filtering An application can choose specific messages to retrieve from the message queue (while ignoring other messages) by using the GetMessage or PeekMessage function to specify a message filter. The filter is a range of message identifiers (specified by a first and last identifier), a window handle, or both. GetMessage and PeekMessage use a message filter to select which messages to retrieve from the queue. Message filtering is useful if an application must search the message queue for messages that have arrived later in the queue. It is also useful if an application must process input (hardware) messages before processing posted messages. 2.8 Posting and Sending Messages Any application can post and send messages. Like the system, an application posts a message by copying it to a message queue and sends a message by passing the message data as arguments to a window procedure. To post messages, an application uses the PostMessage function. An application can send a message by calling the SendMessage, BroadcastSystemMessage, SendNotifyMessage etc. functions. 2.8.1 Posting Messages An application typically posts a message to notify a specific window to perform a task. PostMessage creates an MSG structure for the message and copies the message to the message queue. The application's message loop eventually retrieves the message and dispatches it to the appropriate window procedure. An application can post a message without specifying a window. If the application supplies a NULL window handle when calling PostMessage, the message is posted to the queue associated with the current thread. Because no window handle is specified, the application must process the message in the message loop. This is one way to create a message that applies to the entire application, instead of to a specific window. Occasionally, you may want to post a message to all top-level windows in the system. An application can post a message to all top-level windows by calling PostMessage and specifying HWND_TOPMOST in the hwnd parameter. 2.8.2 Sending Messages An application typically sends a message to notify a window procedure to perform a task immediately. The SendMessage function sends the message to the window procedure corresponding to the given window. The function waits until the window procedure 9 completes processing and then returns the message result. Parent and child windows often communicate by sending messages to each other. For example, a parent window that has an edit control as its child window can set the text of the control by sending a message to it. The control can notify the parent window of changes to the text that are carried out by the user by sending messages back to the parent. 2.9 Window Classes Each window class has an associated window procedure shared by all windows of the same class. The window procedure processes messages for all windows of that class and therefore controls their behavior and appearance. A process must register a window class before it can create a window of that class. Registering a window class associates a window procedure, class styles, and other class attributes with a class name. When a process specifies a class name in the CreateWindow or CreateWindowEx function, the system creates a window with the window procedure, styles, and other attributes associated with that class name. This section discusses the following topics. Types of Window Classes How the System Locates a Window Class Registering a Window Class Elements of a Window Class 2.9.1 Types of Window Classes There are three types of window classes [3]: System Classes Application Global Classes Application Local Classes These types differ in scope and in when and how they are registered and destroyed. System Classes A system class is a window class registered by the system. Many system classes are available for all processes to use, while others are used only internally by the system. Because the system registers these classes, a process cannot destroy them. Table 2.2 describes the system classes that are available for use by all processes [5]. 10 Class Button ComboBox Edit ListBox ScrollBar Static Description The class for a button. The class for a combo box. The class for an edit control. The class for a list box. The class for a scroll bar. The class for a static control. Table 2.2 System windows classes Table 2.3 describes the system classes that are available only for use by the system [5]. They are listed here for completeness sake. Class #32768 #32769 #32770 #32771 Description The class for a menu. The class for the desktop window. The class for a dialog box. The class for the task switch window. Table 2.3 Kernel window classes Application Global Classes An application global class is a window class registered by an executable or dynamic-link library (DLL) that is available to all other modules in the process. For example, a .dll can call the RegisterClass function to register a window class that defines a custom control as an application global class so that a process that loads the .dll can create instances of the custom control [3]. To remove an application global class and free the storage associated with it, use the UnregisterClass function. Application Local Classes An application local class is any window class that an executable or .dll registers for its exclusive use. Although you can register any number of local classes, it is typical to register only one. This window class supports the window procedure of the application's main window. 11 The system destroys a local class when the module that registered it closes. An application can also use the UnregisterClass function to remove a local class and free the storage associated with it. 2.9.2 How the System Locates a Window Class The system maintains a list of structures for each of the three types of window classes. When an application calls the CreateWindow or CreateWindowEx function to create a window with a specified class, the system uses the following procedure to locate the class. 1. Search the list of application local classes for a class with the specified name whose instance handle matches the module's instance handle. (Several modules can use the same name to register local classes in the same process.) 2. If the name is not in the application local class list, search the list of application global classes. 3. If the name is not in the application global class list, search the list of system classes. All windows created by the application use this procedure, including windows created by the system on the application's behalf, such as dialog boxes. It is possible to override system classes without affecting other applications. That is, an application can register an application local class having the same name as a system class. This replaces the system class in the context of the application but does not prevent other applications from using the system class. 2.9.3 Registering a Window Class A window class defines the attributes of a window, such as its style, icon, cursor, menu, and window procedure. The first step in registering a window class is to fill in a WNDCLASSEX structure with the window class information. Next, pass the structure to the RegisterClassEx function. If you register the window class using the ANSI version of RegisterClassEx, RegisterClassExA, the application requests that the system pass text parameters of messages to the windows of the created class using the ANSI character set; if you register the class using the Unicode version of RegisterClassEx, RegisterClassExW, the application requests that the system pass text parameters of messages to the windows of the created class using the Unicode character set. The IsWindowUnicode function enables applications to query the nature of each window. The executable or DLL that registered the class is the owner of the class. The system determines class ownership from the hInstance member of the WNDCLASSEX structure passed to the RegisterClassEx function when the class is registered. For DLLs, the hInstance member must be the handle to the .dll instance. 12 In Windows 95/Windows 98/Windows Me, the class is destroyed when the owner closes or is unloaded. For this reason, the process must destroy all windows using the class before the owner closes or is unloaded. But in Windows NT, Windows 2000 and Windows XP, the class is not destroyed when the .dll that owns it is unloaded. Therefore, if the system calls the window procedure for a window of that class, it will cause an access violation, because the .dll containing the window procedure is no longer in memory. The process must destroy all windows using the class before the .dll is unloaded and call the UnregisterClass function. 2.9.4 Elements of a Window Class The elements of a window class define the default behavior of windows belonging to the class. The application that registers a window class assigns elements to the class by Element Class Name Window Procedure Address Instance Handle Class Cursor Class Icons Class Background Brush Class Menu Purpose Distinguishes the class from other registered classes. Pointer to the function that processes all messages sent to windows in the class and defines the behavior of the window. Identifies the application or .dll that registered the class. Defines the mouse cursor that the system displays for a window of the class. Defines the large icon and the small icon (Windows 95/98/Me, Windows NT 4.0 and later). Defines the color and pattern that fill the client area when the window is opened or painted. Specifies the default menu for windows that do not explicitly define a menu. Class Styles Defines how to update the window after moving or resizing it, how to process double-clicks of the mouse, how to allocate space for the device context, and other aspects of the window. Extra Class Specifies the amount of extra memory, in bytes, that the system should Memory reserve for the class. All windows in the class share the extra memory and can use it for any application-defined purpose. The system initializes this memory to zero. Extra Window Specifies the amount of extra memory, in bytes, that the system should Memory reserve for each window belonging to the class. The extra memory can be used for any application-defined purpose. The system initializes this memory to zero. Table 2.4 window class elements 13 setting appropriate members in a WNDCLASSEX structure and passing the structure to the RegisterClassEx function. The window class elements are as shown in table 2.4. Although a complete window class consists of many elements, the system requires only that an application supply a class name, the window-procedure address, and an instance handle. Use the other elements to define default attributes for windows of the class, such as the shape of the cursor and the content of the menu for the window. One must initialize any unused members of the WNDCLASSEX structure to zero or NULL. Class Name Every window class needs a Class Name to distinguish one class from another. Assign a class name by setting the lpszClassName member of the WNDCLASSEX structure to the address of a null-terminated string that specifies the name. Because window classes are process specific, window class names need to be unique only within the same process. Also, because class names occupy space in the system's private atom table, one should keep class name strings as short a possible. The GetClassName function retrieves the name of the class to which a given window belongs. Window Procedure Address Every class needs a window-procedure address to define the entry point of the window procedure used to process all messages for windows in the class. The system passes messages to the procedure when it requires the window to carry out tasks, such as painting its client area or responding to input from the user. A process assigns a window procedure to a class by copying its address to the lpfnWndProc member of the WNDCLASSEX structure. Instance Handle Every window class requires an instance handle to identify the application or .dll that registered the class. The system requires instance handles to keep track of all of modules. The system assigns a handle to each copy of a running executable or .dll. The system passes an instance handle to the entry-point function of each executable and .dll. The executable or .dll assigns this instance handle to the class by copying it to the hInstance member of the WNDCLASSEX structure. In Windows 95/Windows 98/Windows Me, multiple instances of the same application or .dll use the same code segment, but each has its own data segment. The system uses an instance handle to identify the data segment that corresponds to a particular instance of an application or .dll. 14 2.10 About Window Procedures Each window is a member of a particular window class. The window class determines the default window procedure that an individual window uses to process its messages. All windows belonging to the same class use the same default window procedure. For example, the system defines a window procedure for the combo box class (COMBOBOX); all combo boxes then use that window procedure [5]. An application typically registers at least one new window class and its associated window procedure. After registering a class, the application can create many windows of that class, all of which use the same window procedure. Because this means several sources could simultaneously call the same piece of code. 2.10.1 Structure of a Window Procedure A window procedure is a function that has four parameters and returns a signed value. The parameters consist of a window handle, a UINT message identifier, and two message parameters declared with the WPARAM and LPARAM data types. Message parameters often contain information in both their low-order and high-order words. The interpretation of the return value depends on the particular message. Because it is possible to call a window procedure recursively, it is important to minimize the number of local variables that it uses. When processing individual messages, an application should call functions outside the window procedure to avoid excessive use of local variables, possibly causing the stack to overflow during deep recursion. 2.10.2 Default Window Procedure The default window procedure function, DefWindowProc defines certain fundamental behavior shared by all windows. The default window procedure provides the minimal functionality for a window. An application-defined window procedure should pass any messages that it does not process to the DefWindowProc function for default processing. 2.11 Subclassing Window Subclassing is a technique that allows an application to intercept messages destined for another window [6]. An application can augment, monitor, or modify the default behavior of a window by intercepting messages meant for another window. Subclassing is an effective way to change or extend the behavior of a window without redeveloping the window. When a window is created, the 32-bit versions of the Microsoft Windows™ operating system take the address of the window procedure in the WNDCLASS structure and copy it to the new window's information structure. When a message is sent to the window, Windows calls the window procedure through the address in the window's information structure. To subclass a window, you substitute a new window procedure that 15 receives all the messages meant for the original window by substituting the window procedure address with the new window procedure address. 2.11.1 Types of Subclassing The two types of subclassing are instance subclassing and global subclassing. Instance subclassing is subclassing an individual window's information structure. With instance subclassing, only the messages of a particular window instance are sent to the new window procedure. Global subclassing is replacing the address of the window procedure in the WNDCLASS structure of a window class. All subsequent windows created with this class have the substituted window procedure's address. Global subclassing affects only windows created after the subclass has occurred. At the time of the subclass, if any windows of the window class that is being globally subclassed exist, the existing windows are not affected by the global subclass. If the application needs to affect the behavior of the existing windows, the application must subclass each existing instance of the window class. 2.12 Qt for windows Qt is a C++ toolkit for multiplatform GUI and application development. In addition to the C++ class library, Qt includes tools to make writing applications fast and straightforward. Qt's multiplatform capabilities and internationalization support ensure that Qt applications reach the widest possible market. Qt/Windows uses the Win32 API and GDI for events and drawing primitives. Qt does not use MFC or any other toolkit. In particular, Qt does not use the inflexible "common controls", but rather provides its own more powerful, customizable widgets [9]. Qt provides a full set of widgets. Widgets are visual elements that are combined to create user interfaces. Buttons, menus, scroll bars, message boxes, and application windows are all examples of widgets. Qt's widgets are not arbitrarily divided between "controls" and "containers"; all widgets can be used both as controls and as containers. Custom widgets can easily be created by sub-classing existing Qt widgets, or created from scratch on the rare occasion when this is necessary. Widgets are instances of QWidget or one of its subclasses. 16 Figure 2.2 An extract from the QWidget class hierarchy Qt/Windows creates a window when a widget is created and the class name of this window is ‘QWidget’. This class has an associated window procedure shared by all windows of the ‘QWidget’ class. Thus, in Qt, all visual controls share the same class name as well as the same window procedure. 2.12 Rational Robot Award-winning IBM® Rational® Robot V2003 automates functional testing of graphical user interfaces. With Rational Robot user can create, modify, and execute automated functional, distributed functional, regression and smoke tests for software applications that are built using a wide variety of integrated development environments (IDEs) and languages [10]. Ease New Testers into Automation IBM Rational Robot is the best-of-breed functional testing tool that facilitates success even before testers have learned advanced scripting skills. And it ships with the tester’s desktop, IBM Rational Test Manager, from which testers plan, organize, execute, manage and report on all testing activities, including reporting on manual testing. This dual testand-manage capability is the ideal starting point for automating testing. Give Advanced Testers a Powerful Tool IBM Rational Robot is an extensible, flexible functional testing tool that experienced testers can use to modify test scripts and improve the depth of their testing. With Rational Robot V2003 you can: • Automate regression and configuration testing • Extend test scripts with conditional logic and call any DLL or Windows API function IBM Rational Robot captures all HTML and DHTML properties, including link targets and non-visible data. 17 Rational Robot provides test cases for objects such as menus, lists, alphanumeric characters, and bitmaps, and allows you to create user-defined test cases that call external DLLs or executables. It offers specialized test cases for environment-specific objects such as Java controls, PowerBuilder DataWindows, ActiveX Controls, Special Oracle Forms objects, OCXs, Visual Basic objects, and VBXs. Quick and Easy Visual Analysis IBM Rational Robot automatically logs all test results, color-coding them in the test log viewer for fast visual analysis. By double-clicking on an entry, Rational Robot brings you directly to the corresponding line in the test script for fast analysis. Multiple IDE and Language Support Rational Robot supports the following IDE and languages Java Environments Microsoft Visual Studio.NET HTML, XML and DHTML Applications Oracle Developer/2000 Visual Basic Applications PowerBuilder Applications Unfortunately, it does not support Qt. 18 Chapter 3 Analysis 3.1 Introduction This chapter describes the results of the analysis on why Rational Robot cannot communicate with Qt widgets. As it has been mentioned earlier, there is no proper documentation about how Rational Robot interacts with objects, some sample applications have been created with Visual C++ & Visual Basic, the languages that are supported by robot. Applying Rational Robot on those two environments’ applications some conclusions have been drawn. 3.2 How Rational Robot Interacts with object While recording scripts, when the user clicks on an object, Rational Robot gets the object type by getting the class name of the window associated with the object. There is a window API called GetClassName to retrieve the class name of the window. Robot internally maintains a list of mapping between the window class name and the object type. From that list it gets the object type. Then it sends messages corresponding to that object type to retrieve more information about where the user has clicked on an object. For Example, when a user clicks on an item of a listbox, the following actions occur, Rational Robot retrieves the handle of the window associated with the list box by calling windows API WindowFromPoint. Then it calls the GetClassName API to retrieve the class name of the window. For a VC++ app it finds the class name as ‘ListBox’ and for a VB App it finds ‘ThunderListBox’. For the both class names Rational Robot sees the object as a listbox since it maintains an object-type mapping for known class names. Figure 3.1 shows the interaction between Rational Robot and AUT. 19 GetClassName() Rational Robot ListBox Send WindowMessages related to ListBox Get the corrosponding result Figure 3.1 Interaction between Rational Robot and win32 application After determining the object type as listbox Rational Robot sends messages related to listbox. First of all it sends LB_GETCOUNT message to the window associated with the listbox. As VB or VC++ is a standard Windows programming environment, all message handlers for all controls are fully implemented. So when the listbox control gets the LB_GETCOUNT message it returns total number of items in the listbox. Robot sends the LB_GETCURSEL to the listbox; it returns the index of the currently selected item which one is selected due to the mouse click. Robot sends LB_GETTEXTLEN to listbox; it returns the length of the selected item. Finally robot sends LB_GETTEXT to retrieve the text of the currently selected item. Thus Rational Robot gets the attributes of an object. 3.3 Why Rational Robot cannot recognize Qt objects? “During recording, Robot recognizes all the standard Windows GUI objects that you click, such as check boxes and list boxes. Each of these objects is associated with one of a fixed list of object types. The association of an object with an object type is generally based on the class name of the window associated with the object.” [11] In Qt all GUI Objects ( e.g. ListBox, Button etc) are derived from QWidget, and the class name of the windows associated with these GUI objects is ‘QWidget’ . That is why Rational Robot sees all objects (Listbox, Button) etc as same object. 20 3.4 Why Rational Robot cannot read attributes of an object? “An object might look and act like a standard toolbar but might actually not respond correctly to the messages that are sent to a standard toolbar” [11]. Rational Robot retrieves attributes of a window control by sending Windows messages to the window associated with the object. E.g. To get the number of elements in a Listbox Rational Robot sends LB_GETCOUNT message to the window associated with the listbox, then a normal win32 listbox return the number of elements. But Qt Objects does not response with standard Windows messages, that’s why Rational Robot cannot retrieve the attributes of an object. 3.5 Observations From the above analysis it is clear that there are two main obstacles which prevent communication between Rational Robot and Qt. Firstly, all Qt objects register themselves as QWidget which prevents them from being identified as different object types. The other one is absence of message handlers. As Qt objects do not interact with each other by message passing, there is no implementation of control Windows messages like LB_GETCOUNT, LB_GETTEXT etc in Qt. 21 Chapter 4 Technical Solutions 4.1 Introduction An important goal is to achieve a solution that is fast and has as small overhead as possible. In this chapter the existing Qt toolkit’s work flow is discussed and the proposed solutions are also designed. 4.2 Existing work flow The existing work flow is divided into two parts, the object creation operation and the message handler operation. 4.2.1 Object Creation Operation In Qt all visual objects are derived from QWidget class. QWidget class has only one constructor with three parameters parent, name and flags. If parent parameter is 0, the new widget becomes a top-level window. If parent is another widget, this widget becomes a child window inside parent. The new widget is deleted when its parent is deleted. On the Windows platform the name parameter is used in the caption of the window. The frame parameter is used to customize the window frame of a top-level widget. In the QWidget constructor a window is created with ‘QWidget’ class name. This window is used to receive events for mouse and keyboard input, menu and dialog box input etc. When other objects that are derived from the QWidget class are created they always call the constructor of the QWidget class in their constructor. Thus QWidget and its sub classes always create windows with ‘QWidget’ class name. The figure 4.1 shows what happens in existing Qt when a ‘QLineEdit’ or QLabel object is created. 23 QWidget(…) { Register Class ”QWidget” Create a window ’QWidget’ Type Do other initialization } QFrame(…):QWidget(…) { Do initialization …………. } QLineEdit(…):QFrame(…) { Do initialization …………. } QLabel(…):QFrame (…) { Do initialization …………. } Figure 4.1 Object creation in existing Qt In the figure 4.1 it is clear that when any object is created a ‘QWidget’ type window is created. So, in Qt every visual object’s window is ‘QWidget’ type. 4.2.2 Message Handling Operation In existing Qt, as every visual object is of ‘QWidget’ type, every Windows message is handled in a single WndProc. In Qt’s WndProc only the messages with prefix WM_ are QtWndProc (msg,…..) { switch(msg) { case WM_LBUTTONDOWN : …….. break; case WM_....... // General window messages …………. break; } Return DefWindowProc(…) } Figure 4.2 Windows message handlers in existing Qt 24 handled. The messages with WM_ prefix are general window messages that cover a wide range of information and requests, including messages for mouse and keyboard input, menu and dialog box input, window creation and management. But in Qt’s WndProc there is no message handler for controls (Listbox, Combobox,..) that Rational Robot can interact with. 4.3 Proposed operation flow The aim of this design is to add functionality to Qt, so it registers different Control objects using the corresponding class names allowing Rational Robot to send the corresponding messages to the controls. 4.3.1 Object Creation Operation To give all controls different names, an extra constructor has been added to the QWidget Class as well as to its intermediate subclasses. In this constructor an extra parameter, ClassName, has been added. When a control is created it passes its class name as parameter to its super class. In the QWidget constructor, this ClassName parameter is used to register a new class if a class with the same name has not yet been created. Thus every control is registered as its corresponding class name. Now Rational Robot would recognize different controls as different types. QWidget(ClassName,…) { Register Class ClassName Create a window ClassName Type Do other initialization } QFrame(ClassName,…): QWidget(ClassName ,…) { Do initialization …………. } QLineEdit(…): QFrame(“QLineEdit”, …) { Do initialization …………. } QLabel(…): QFrame (“QLabel”,…) { Do initialization …………. } Figure 4.3 Object creation in proposed Qt 25 In figure 4.3 it is clear that when the QLineEdit widget is created, a parameter with “QLineEdit” is sent to its parent QFrame. QFrame sends it to QWidget, then QWidget register a class with QLineEdit and a window is created using this class. Other control widgets register their class name in the same manner. 4.3.2 Message Handling Operation The messages that are sent by the Rational Robot to communicate with the application have been identified. Message handlers should be added for those messages in the Qt’s WndProc. In figure 4.4 skeleton of the proposed QtWndProc has been shown. There is only one window procedure in the whole Qt toolkit. So, this QtWndProc is called for each and every message generated from any of the Qt control. The message handlers should be added very carefully, as this procedure is called very frequently. QtWndProc(msg,…..) { switch(msg) { case WM_LBUTTONDOWN : …….. break; case WM_....... // General window messages …………. break; case LB_..... // all messages related to Listbox …… break ………….All messages for TabBar, Listview, ComboBox etc. has been added. } } Return DefWindowProc(…) Figure 4.4 Windows message handlers in proposed Qt 4.4 Alternative Solution In the previous solution Qt’s source has been changed. So it is necessary to do the whole work again when a new release of Qt arrives. An alternative solution alleviates the need to modify the Qt source. 26 It is possible to get the class name of a Qt object during runtime, because QWidget class has a member function called className which returns the object’s original class name. But Rational Robot uses only Windows API GetClassName to get the class name. So, by hooking the windows API GetClassName, the object’s original class name can be supplied to the Rational Robot. For Message handling issue, by sub classing ‘QWidget’ class, all the missing message handlers can be added to the sub classed window procedure. Subclassed QWidget’s WndProc Hook GetClassName API, Return control’s classname instead of ‘QWidget’. GetClassName() Rational Robot ”QListBox” Solve classname Added all missing message handlers Message has been processes in subclassed WndProc Send WindowMessages related to ListBox Get the corresponding result Figure 4.5 Interactions between Rational Robot and Qt Application in proposed system In figure 4.5 a proposed work flow has been shown for a list box control. If a user clicks on an item in the list box, Rational Robot calls GetClassName API. The hooked function will be called. In the hooked function the original class name QListBox will be retrieved and returned to the Rational Robot. Then Rational Robot sends messages related to listbox. As the list box is sub classed and all the message handlers are added, it responds with the expected messages. Thus Rational Robot can interact with the application properly. 27 28 Chapter 5 Implementation 5.1 Introduction In order to implement the design of the previous chapter, the kernel of Qt has been modified. The procedure turned out to be very time consuming since almost all of the internal execution flow of the Qt had to be understood. Reliable functionality is essential, since changes are made in the kernel of Qt, it could go terribly wrong if the added code does not work properly. 5.2 Software Tools To implement the design following tools have been used. 5.2.1 Visual Studio 6 The Visual Studio 6.0 family of development products includes many development environments. Among those environments Visual C++ and Visual Basic have been used. Visual C++ is a very powerful IDE for developing C/C++ applications, services, and controls for Win32 platforms, including Windows 95/98 and Windows NT/2000. As Qt does not have its own IDE, for adding, modifying and compiling the source code of Qt Visual C++ is used. Visual Basic provides a complete set of tools to simplify rapid application development including ActiveX™ technologies, Data access features etc. Visual Basic is used to create some sample applications, consisting ActiveX component written in Qt during the implementation process. 5.2.2 Qt Designer Qt Designer is a full-fledged GUI builder. Qt Designer makes it easy to experiment with user interface design. The GUI of ExPERT has been developed in Qt Designer. As ExPERT is a very large application and needs a couple of hours to compile, sample applications were created using Qt Designer to observe the effects of changing the source code of Qt during implementation process. 29 5.2.3 Microsoft SPY++ Microsoft Spy++ is a Win32-based utility that gives a graphical view of the system’s processes, threads, windows, and window messages. As Rational Robot does not come with technical documentation, SPY++ has been used to find out what window messages are sent by Rational Robot during interaction with the application under test. 5.3 Coding and Testing 5.3.1 Modifying the Qt kernel The goal of this project is to enable ExPERT with Rational Robot. The Qt objects that are used in ExPERT have been identified. A test application has been written with all of those objects using Qt Designer. The purpose of the test application is to shorten the implementation process. As the changes are made in Qt’s kernel, for every change made a recompilation of the application is needed. Recompilation of ExPERT takes a couple of hours. It is clear from the design, no object’s properties or methods have been changed, only a single parameter has been added to the object’s constructor and some message handlers have been added. The message handler will not execute, unless it gets the corresponding message. Normal Qt applications do not get these messages. Only Rational Robot sends these messages during interaction with the application. So, the added code does not execute in applications that are written with this modified version of Qt unless the application is tested using Rational Robot. The Implementation is done in modular basis. Every Object (QListBox, QListView, QLineEdit etc.) is considered as a single module. Modules are implemented and tested one by one. If one works properly then another is implemented. For example, LB_GETCOUNT message handler has been written as follows: LB_GETCOUNT is sent to retrieve the total number of elements in the list box. A pointer of the QListBox can be found from the Application’s list of widgets that Qt internally maintains for every application. Then QListBox object has the member function count() which return the total number of items in the listbox [8]. This is return by LB_GETCOUNT. Similarly other messages have been implemented. Every message structure is studied and values are return by calling appropriate methods of Qt Classes. Every Message handlers are written in the Windows main procedure, the number of local variables have been kept to a minimum. This is because it is possible to call a window procedure recursively. 30 5.3.2 Alternative solution An alternative solution has also been implemented. There are two processes hooking the API GetClassName and sub classing the ‘QWidget’ class. Based on DelayLoadProfileDLL.CPP, by Matt Pietrek for MSJ February 2000, a dll is written, which uses the windows CBT hook to load the dll in the all running process address spaces [7]. Then it hooks the GetClassName API of Rational Robot process and it hooks the RegisterClassName API of the process of Qt application under test. RegisterClassName is hooked because when the application is trying to register the class ‘QWidget’, the hooked function is called. In this hooked function, ‘QWidget’ has been sub classed. Thereafter every window created with ‘QWidget’ class name, gets the new WndProc in which all the message handlers have been implemented. These message handlers are actually implemented in the previous solution. In the Qt application all controls are of the ‘QWidget’ class, but it is possible to get the original class name (i.e. program defined class name) of the control during runtime. In the hooked function of GetClassName, the original class name is acquired. As the hook function is on the Rational Robot address space, it cannot directly get the class name of the Qt object which is running in a different address space. So, inter process communication is needed. This inter process communication is done by message passing. Rational Robot address space AUT address space Qt’s SubClassed WndProc GetClassName Hook function QT_GETCLASSNAME Send Message and wait until it returns the index of the class name. (User Defined Message) Find the Original class name and return the index of this class name. Index of the ClassName Figure 4.5 Retrieving Qt class name of an object in proposed system As class names are predefined, a list of class names is maintained on the both sides. Only the index is passed to another application. So, the inter process communication is minimal. After getting the original class name, the hooked GetClassName function returns it to Rational Robot. 31 While recording script Rational Robot tries to get the class names of all windows of the AUT for every single click. So, for a large application it has a significant overhead to perform inter process communication for retrieving class names of every windows each time. A list of window handles and corresponding class name index is maintained to minimize the inter process communication. As class name index is used instead of class name itself the list consumes a very small amount of memory. 32 Chapter 6 Conclusion This chapter summarizes the work presented and compares the different solutions. This chapter also describes the implementation difficulties and possible future works. 6.1 Implementation Results As two different solutions have been presented, evaluation is necessary to figure out which one is the best approach. In the first approach, the Qt kernel has been modified and in the alternative approach a separate dll is written. The following table shows the relative pros and cons of the two different approaches. Performance Memory Modified Qt Separate DLL For application with thousands of GUI objects, it is significantly faster than alternative solution. It needs very small amount of extra system memory. For Small amount of GUI objects the performance almost the same. Significant amount of system memory is needed Effect on other running It has no effect of other running As dll is loaded into the process processes. address space of all of the running processes. It has small overhead to other running processes. Recompilation Recompilation of both the Qt and No recompilation is needed. the application are needed after Only the host dll needs to be changes have been made. running before the application and the Rational Robot are executed. New Release of Qt Have to rewrite the whole code in Only recompilation is needed the new version of Qt. Table 6.1 Pros and cons of the two different approaches of the solution. 33 Although the “separate dll” approach has some performance penalties, it is more desirable from the industrial point of view. This is because there is no need to modify Qt after a new release of it. 6.2 Implementation Difficulties The main difficulty was to find out how Rational Robot interacts with other objects. This was done by capturing and examining carefully the messages that Rational Robot sends to interact with applications. Rational Robot only supports standard windows object. But Qt has some special composite objects such as QTable. Rational Robot has no support for objects like QTable which has rows and columns. QTable has been implemented as normal List Box. Rational Robot also cannot recognize popup menu other than system popup menu. A wrapper class of QPopupMenu has been written which creates a system popup menu instead of QPopupMenu. Another major problem was debugging. As the code that has been written only executes during execution of Rational Robot on the application and the code itself resides in a dll, it is not possible to trace it. Debug string has been written to a file to understand what is happening. Compilation time is another problem. As the code is written in the kernel of the Qt, after any modification the whole Qt needs to recompile. Compilation of Qt takes a significant amount of time. Rational Robot also lacks user documentations. For example, there is no documentation about how to select an object containing in an ActiveX component for insertion of a verification point. At long last it has been found that if the Alt key is down during object selection Rational Robot can select objects containing in an ActiveX. 6.3 Summary As it is mentioned earlier due to the time limitation the target has been set to implement a communication interface between the Qt components of ExPERT and Rational Robot. The objective is fully accomplished. Now, with this communication interface Rational Robot can recognize the objects of ExPERT and it can now record test scripts. Rational Robot can run the previously recorded scripts. 34 Rational Robot can get the attributes of the objects. Rational Robot can make verification point of any type. Though this solution only work for the objects that are used in the ExPERT, it can easily be extended to make it work with the whole Qt toolkit. 6.4 Future Work In this thesis the design and implementation of the communication interface between a set of Qt objects and Rational Robot are discussed. Obviously more work should be done to make it work efficiently with the whole set of Qt toolkit. The possible future work might be Implementing rest of the objects of the Qt toolkit. Finding a way to update the list of window handles when a window of AUT is destroyed. Finding a way to feed new objects to the Rational Robot. This is because in Qt it is possible to make customize widget that might be totally different from any existing controls. The ideas and notions introduced in this thesis could be applicable to a wider spectrum of application domains and not necessarily limited to Rational Robot application. Thus formalizing the model would help generalizing Qt to work with different testing applications. 35 Bibliography [1] Andrei Alexandrescu. Modern C++ Design, Addison-Wesley Pub Co; 1st edition (February 13, 2001) [2] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns, Addison-Wesley Pub Co, 1st edition (January 15, 1995). [3] Johnson M. Hart. Win32 System Programming, Addison-Wesley Pub Co; 2nd Book and CD-ROM edition (September 29, 2000) [4] Johnson, R. E., Foote, B. (1988). Designing reusable classes. Journal of ObjectOriented Programming, [5] MSDN Library Visual Studio 6.0, Microsoft Developer Networks, available at: http://msdn.microsoft.com/ [6] Petzold, Charles. Programming Windows [Fifth Edition], Microsoft Press. [7] Pietrek, Matt. Under the Hood Microsoft Systems Journal, February 2000 — Vol 15 No 2 [8] Qt Reference Documentation http://www.trolltech.com/products/qt/whitepaper/qt-whitepaper.html, verified 200312-08 [9] Qt Whitepaper, http://www.trolltech.com/products/qt/whitepaper/qt-whitepaper.html, verified 200312-08 [10] Rational® Robot Automated Test http://www.wilsonmar.com/1robot.htm verified 2003-12-08 [11] Rational® Robot User Guide, Rational® TestManager v2003.6.0, 2003 37 Appendix A Terminology This section describes some of the terms used through out the document. ActiveX All component technologies that are built on the Microsoft Component Object Model (COM). API AUT Application Programming Interface Application Under Test DLL ExPERT GDI Dynamic Link Library The software for planning & preparation, data initializations, exercise execution and analysis & evaluation of military training. Graphic Display Interface GUI Graphical User Interface IDE Integrated Development Environment Win32 The application programming interface in Windows 95/98, Windows NT/2000, and Windows CE that enables applications to use the 32-bit instructions available on 80386 and higher processors. Window control A predefined child window used in conjunction with another application window to provide a standardized way for users to make selections, carry out commands, and perform input and output tasks. Window handle A 32-bit value, assigned by windows kernel that uniquely identifies a window. 39 Appendix B List of Window Messages Following table shows the window massages that are handled in the project and their corresponding widgets. Widget Window Message LB_GETCOUNT LB_GETITEMRECT QListBox LB_GETCURSEL LB_GETTEXTLEN LB_GETTEXT TCM_HITTEST TCM_GETITEM QTabBar TCM_GETITEMRECT TCM_GETITEMCOUNT TVM_HITTEST TVM_GETITEM TVM_GETNEXTITEM QListView TVM_GETITEMRECT TVM_GETCOUNT TVM_EXPAND TVM_ENSUREVISIBLE 41 Widget Window Message CB_GETCOUNT CB_GETCURSEL QComboBox CB_GETLBTEXTLEN CB_GETLBTEXT LB_GETCOUNT LB_GETITEMRECT QTable LB_GETCURSEL LB_GETTEXTLEN LB_GETTEXT EM_GETLINECOUNT QLineEdit QDateTimeEditor QTimeEdit WM_GETTEXTLENGTH QRadioButton BM_GETCHECK QCheckBox BM_GETCHECK WM_GETTEXT 42 Avdelning, Institution Division, Department Datum Date 2003-12-17 Institutionen för datavetenskap 581 83 LINKÖPING Språk Language Svenska/Swedish X Engelska/English Rapporttyp Report category Licentiatavhandling X Examensarbete C-uppsats D-uppsats ISBN ISRN LITH-IDA-EX--03/078--SE Serietitel och serienummer Title of series, numbering ISSN Övrig rapport ____ URL för elektronisk version http://www.ep.liu.se/exjobb/ida/2003/dd-d/078/ Titel Title Communication Interface between Rational Robot and Qt objects Författare Author Nasir Uddin Ahmed Sammanfattning Abstract Automated black box, GUI-level regression test tools are popular in the industry. Currently, IBM Rational Robot being one of the best testing tools supports wide verity of integrated development environments (IDEs) and languages. Unfortunately it does not support Qt, the multiplatform C++ GUI toolkit. The excellent documentation, clean interface, and a sensible approach to the object oriented paradigm makes Qt one of the most popular GUI toolkits in the world. The project describes why Rational Robot cannot recognize the Qt objects and their properties. The findings show that Qt objects lack Windows message handlers and all objects register their class names with the same parent object name instead of their own class name. The project describes two different solutions for the problem. The first solution is very strait, Qt kernel has been modified and message handlers have been added. In the second solution, Qt object windows have been sub classed and inter process communication has been used. These two solutions have been evaluated. Nyckelord Keyword Automated testing tools, C++, inter process communication, Qt, Rational Robot, test automation, Windows messages, window sub classing.