C# p/invoke, Reading data from an Owner Drawn List Box

 ̄綄美尐妖づ 提交于 2020-01-14 04:24:11

问题


I have an Owner Drawn List Box in an external application (America Online) that I need to get data out of for building a component to assist people with its usability. (the utility will be making access of certain things more simple, etc).

Notice

My knowledge of C++ is very poor. I am a C# programmer.

I have the hWnd to the List Box in question, but it appears to be owner drawn. Using LB_GETTEXT returns bad data, I just get junk (it renders in my debugger as a bunch of chinese characters) and going through LB_GETITEMDATA returns much the same.

I believe this is because the owner drawn list box has graphics on it. Doing a lot of digging, I have discovered others in the past with this problem. I have unearthed the following code that is supposed to remedy this issue. However it does not. The code is posted below, and the issues beneath it.

void GetListItemData( HWND hListWnd, long index, char *outputResult )
{
    int result;
    DWORD processID;
    HANDLE hProcess;
    char *itemData;
    char sDataRead[5];
    DWORD bytes;
    DWORD lListItemHold, lListItemDataHold;
    *outputResult=0;

    if( hListWnd )
    {
        GetWindowThreadProcessId( hListWnd, &processID );

        hProcess=OpenProcess( 0x10|0xf0000|PROCESS_VM_READ, 0, processID );

        if( hProcess )
        {
            lListItemHold=(DWORD)SendMessage( hListWnd, LB_GETITEMDATA, index-1, 0 );
            lListItemHold=lListItemHold+24;

            result=ReadProcessMemory( hProcess, (void *)lListItemHold, &sDataRead, 4, &bytes );
            if( !result )
            {
                RaiseWinErr();
            }

            memcpy( &lListItemDataHold, &sDataRead, 4 );
            lListItemDataHold=lListItemDataHold+6;

            ReadProcessMemory( hProcess, (void *)lListItemDataHold, outputResult, 16, &bytes );

            CloseHandle( hProcess );
        }
    }
}

My understanding, limited as it is, is that lListItemHold=lListItemHold+24 tries to account for whatever 'structure' is in the ListBox and pass through the first 24 bytes of it, and return what remains. However this does not seem to be working for me.

Can anyone shed some light on things I could try? I know I am grasping at straws as it is. I am coding this in C#, so this function is used using p/invoke such as follows;

    [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void RetrieveListItem(
        System.IntPtr hWnd,
        System.Int32 index,
        [MarshalAs(UnmanagedType.LPArray)]byte[] buffer
    );

    [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void RetrieveListItem(
        System.IntPtr hWnd,
        System.Int32 index,
        [MarshalAs(UnmanagedType.LPTStr)]System.Text.StringBuilder buffer
    );

回答1:


I have two blog posts on the topic

http://taylorza.blogspot.com/2009/08/archive-hacking-my-way-across-process.html http://taylorza.blogspot.com/2010/06/crossing-process-boundary-with-net.html

These however are for a ListView control, but you might want to take a look at the code. The second post is using P/Invoke to achieve this in .NET.

1- Why are you adding 24 to lListItemHold?

2- Are you sure lListItemhold is a pointer to a string, it might be some internal structure of the application.



来源:https://stackoverflow.com/questions/4680795/c-sharp-p-invoke-reading-data-from-an-owner-drawn-list-box

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!