Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get item names from a .NET applications list control using winapi or mfc

Tags:

c++

winapi

mfc

So basically i have this software which outputs data in a list form. Thanks to the comments here we have understood that it is most likely written in .NET.

I want to scan the list so i can do some algorithms on the data.

Using Spy++ i found that what holds this list is titled "Panel2" and i can get the handle to this (its class is "WindowsForms10.Window.8.app") using EnumChildWindows.

However i don't know how to get to the list itself so i can read its items. I have tried EnumChildWindows on the "Panel2" handle and outputting the caption of all those windows but they are all empty.

Can panel2 be the actuall list? If so could i just cast it to (CListCtrl*) ?

Axilles mentions in the comments that it probably is written in .NET, wold it be possible to get the controlID / handle to the list using something like http://reflector.red-gate.com/download.aspx?TreatAsUpdate=1 ?

   CWnd* mainWindow;
    CWnd* panel;
    CListCtrl* list;



BOOL CALLBACK findWindow( HWND hwnd,LPARAM lParam)
{
    char text[8];
    GetWindowText(hwnd,text,8);

    if(strcmp(text,"Fetcher") == 0)
    {
        mainWindow= CWnd::FromHandle(hwnd);

        return false;
    }

    return true;
}

BOOL CALLBACK findPanel(HWND hwnd,LPARAM lParam)
{

    char text[7];
    GetWindowText(hwnd,text,7);

    if(strcmp(text,"Panel2") == 0)
    {
        panel = CWnd::FromHandle(hwnd);

        return false;
    }

    return true;
}


void CAnalyzeDlg::OnBnClickedButton1()
{
    mainWindow = 0;

    while(mainWindow == 0)
    {
    ::EnumWindows(findWindow,0);
    }

    mainWindow ->ActivateTopParent();

    while(panel == 0) ::EnumChildWindows(mainWindow ->m_hWnd,findPanel,0);

    CWnd* pointTest = NULL;

    CString text = "";

    int xx = 337;
    int yy = 95;

    while(yy < 1024 && (pointTest == NULL || strcmp(text,"") == 0 || strcmp(text,"Panel2") == 0))
    {
        pointTest = mainWindow->ChildWindowFromPoint(CPoint(xx,yy));
        yy++;
        if(pointTest != 0)
            pointTest->GetWindowTextA(text);
    }



    if(strcmp(text,"") != 0)
        MessageBox(0,text,0); // This never shows

}
like image 402
David Avatar asked Nov 08 '12 09:11

David


1 Answers

Spy++ is an excellent tool, but it's not .Net aware. I suggest trying UISpy.exe on the application as well to see it is able to find more elements than Spy++. UISpy.exe can be found at http://msdn.microsoft.com/en-us/library/ms727247.aspx and there is ManagedSpy.exe as well http://msdn.microsoft.com/en-us/magazine/cc163617.aspx

You can be certain if the application is a .Net application or not by attaching a debugger to it (either Visual Studio or WinDBG; I'd recommend the free version of VC++ if you don't have Visual Studio already as I'm not sure that the C# version has native debugging support). Another option is to utilize depends.exe from the Windows Platform SDK or even just ProcessExplorer.exe from http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx to see what DLLs are loaded into the process (i.e. a .Net app will have the core .Net DLLs loaded).

If the list is actually a Windows Presentation Forms (WPF) list you will likely have to utilize the .Net UIAutomation classes to access the list's contents. UIAutomation is documented here: http://msdn.microsoft.com/en-us/library/ms747327.aspx

Edit: UISpy.exe is now obsolete according to MSDN docs:

Note The Accessible Explorer and UI Spy tools are obsolete and no longer available. Developers should use Inspect or AccScope instead.

like image 109
Josh Heitzman Avatar answered Oct 19 '22 21:10

Josh Heitzman