C # p / invoke, чтение данных из нарисованного владельцем списка - PullRequest
1 голос
/ 13 января 2011

У меня есть поле со списком отобранных владельцем во внешнем приложении ( America Online ), из которого мне нужно получить данные для создания компонента, чтобы помочь людям с его удобством использования. (утилита сделает доступ к некоторым вещам более простым и т. д.).

Примечание

Мои знания C ++ очень плохие . Я программист C #.

У меня есть hWnd в поле списка, о котором идет речь, но, похоже, он нарисован владельцем. Использование LB_GETTEXT возвращает неверные данные, я просто получаю мусор (он отображается в моем отладчике как набор китайских иероглифов), и выполнение LB_GETITEMDATA возвращает почти то же самое.

Я полагаю, это потому, что на нарисованном владельцем списке есть графика. Делая много копаний, я обнаружил других в прошлом с этой проблемой. Я обнаружил следующий код, который должен исправить эту проблему. Однако это не так. Код размещен ниже, а вопросы под ним.

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 );
        }
    }
}

Мое понимание, каким бы ограниченным оно ни было, заключается в том, что lListItemHold=lListItemHold+24 пытается учесть любую «структуру» в ListBox, пройти через первые 24 байта и вернуть то, что осталось. Однако это, похоже, не работает для меня.

Может кто-нибудь пролить свет на то, что я могу попробовать? Я знаю, что цепляюсь за соломинку как есть. Я кодирую это в C #, поэтому эта функция используется с использованием p/invoke, например:

    [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 Ответ

1 голос
/ 13 января 2011

У меня есть два сообщения в блоге по теме

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

Это, однако, для элемента управления ListView, но вы можете взглянуть на код.Второй пост использует P / Invoke для достижения этого в .NET.

1- Почему вы добавляете 24 в lListItemHold?

2 - Вы уверены, что lListItemhold - указатель на строку,это может быть какая-то внутренняя структура приложения.

...