Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / MFC

UI Control Data Spy

Rate me:
Please Sign up or sign in to vote.
5.00/5 (14 votes)
1 Oct 2009CPOL2 min read 56.6K   4.9K   65   7
A tool for capturing data from controls like TreeCtrl, ListCtrl, ComboBox, ListBox, etc.

Image 1

Introduction

This is a tool for capturing text data from UI controls. These include TreeCtrl, ListCtrl, ComboBox, ListBox, HeaderCtrl, Edit, etc. For example, the Windows Explorer folder tree data and folder list data can be obtained in text format.

Usage

Locating a window is similar to that in Microsoft Spy++. The following section will describe the usage step by step:.

  1. The control or window can be located using the Finder tool. It can be clicked and dragged to any window and the corresponding window will be highlighted. Also, the window can be located from the Window Tree.
  2. Clicking the Get Data button will capture the data from the selected window (control).
  3. The captured data can be selected and copied from the text area below the Get Data button, or by just clicking the Copy Data button.

Additionally, the option Smallest Top determines whether to search for the window that has the smallest area. It is useful when a control surrounded by a group box has to be located. If this is not selected, the simple WindowFromPoint API will be used for the search.

Also, the located window can be confirmed by clicking the Flash button. Another way is to right click the Window Tree and select Flash in the context menu.

The data captured from ListCtrl and TreeCtrl are using TAB as delimiters. This helps to easily manage the data to paste and format in MS Word or Excel. The following image shows this:

scrn2.png

The Windows\System folder is captured from Windows Explorer. Then it is pasted and formatted as a table in MS Word, as shown below:

scrn2.png

Points of Interest

Locating a window by the Smallest Top method is really interesting. For that, first of all, the window under the mouse cursor is needed. After that, the all the siblings of this window coming under the same mouse cursor position will be checked for its area (Width x Height). From this, the window having the smallest area will be determined. The main code fragment is given below:

C++
HWND hWnd = ::WindowFromPoint( point ); 

CPoint pointClient( point ); // mouse cursor position
::ScreenToClient( hWnd, &pointClient );

HWND hWndChild = ::ChildWindowFromPoint( hWnd, pointClient );
if(( 0 != hWndChild ) && ::IsWindowVisible( hWndChild ))
{
    hWnd = hWndChild;
}

// smallest top window search
if( m_bFindSmallestTop )
{
    DWORD dwWndArea = MAXDWORD;

    // avoid top level windows
    HWND hWndParent = ::GetParent( hWnd );
    if( 0 != hWndParent )
    {
        if( 0 == ( ::GetWindowLong( hWnd, GWL_STYLE ) & WS_POPUP ))
        {
            // walk through child windows
            HWND hWndChild = ::GetWindow( hWndParent, GW_CHILD );
            while( 0 != hWndChild )
            {
                // ignore hidden windows
                if( ::IsWindowVisible( hWndChild ))
                {
                    // window under the point
                    CRect rect;
                    ::GetWindowRect( hWndChild, &rect );
                    if( rect.PtInRect( point ))
                    {
                        // find smallest
                        DWORD dwChildArea = rect.Width() * rect.Height();
                        if( dwChildArea < dwWndArea )
                        {
                            dwWndArea = dwChildArea;
                            hWnd = hWndChild;
                        }
                    }
                }
                hWndChild = ::GetWindow( hWndChild, GW_HWNDNEXT );
            }
        }
    }
}

For capturing data from different controls like ListCtrl, TreeCtrl, etc., the memory should be allocated within the virtual address space of the process of that window. A class named ProcMem is used for this purpose. It will do the necessary things to simply handle the process memory. The class declaration is given below:

C++
class ProcMem  
{
public:
    ProcMem( HWND hWnd );
    virtual ~ProcMem();

    LPVOID Allocate( DWORD dwSize );
    BOOL Write( LPVOID lpProcMem, LPVOID lpLocalMem, DWORD dwSize );
    BOOL Read( LPVOID lpProcMem, LPVOID lpLocalMem, DWORD dwSize );

private:
    HANDLE m_hProcess;
    CArray<LPVOID, LPVOID> m_arrayMemoryAllocated;
};

History

  • Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNICE Pin
Happyjw Happyjw5-Aug-12 20:29
Happyjw Happyjw5-Aug-12 20:29 
Generalgreat tool Pin
korsuas3-Dec-09 4:32
korsuas3-Dec-09 4:32 
GeneralRe: great tool Pin
Nishad S3-Dec-09 13:28
Nishad S3-Dec-09 13:28 
Generalreally helpful Pin
akuma96601108-Oct-09 20:15
akuma96601108-Oct-09 20:15 
GeneralRe: really helpful Pin
Nishad S8-Oct-09 20:55
Nishad S8-Oct-09 20:55 
GeneralInteresting and sueful tool, thanks! Pin
Tage Lejon1-Oct-09 23:26
Tage Lejon1-Oct-09 23:26 
GeneralRe: Interesting and sueful tool, thanks! Pin
Nishad S5-Oct-09 19:19
Nishad S5-Oct-09 19:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.