С# p/invoke, Чтение данных из списка, нарисованного владельцем

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

Уведомление

Мои познания в 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
    );

person Ciel    schedule 13.01.2011    source источник


Ответы (1)


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

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 является указателем на строку, это может быть какая-то внутренняя структура приложения.

person Chris Taylor    schedule 13.01.2011
comment
Я не писал исходный код. Я не уверен, зачем нужно добавлять +24, я просто знаю, что без него это не работает. На самом деле я запустил код C++, но он зависает на некоторых машинах, так что я знаю, что я на правильном пути. - person Ciel; 13.01.2011
comment
Если бы я хотел добавить +24 к версии p/invoke (вторая ссылка), с какой переменной я бы это сделал? Я не уверен, что здесь коррелирует с чем - где мне добавить +24 и +6, как показано в моем коде C #, чтобы получить тот же результат? Любая идея? - person Ciel; 13.01.2011
comment
Да... Второй выглядит хорошо, но он просто не получает данные. Мне нужно иметь возможность добавить буферизацию, как в версии C++. Эти +24 и +6 используются для смещения результата, поэтому он получает строку вместо мусора. - person Ciel; 13.01.2011
comment
@Стейси, Америка онлайн, что это такое? Можно ли где-нибудь достать его и посмотреть на него? Я не в США и не из США, поэтому я не знаю приложение. - person Chris Taylor; 13.01.2011
comment
Ты можешь, но не хочешь, поверь мне. Если бы это не было обязательной частью моего конкретного клиентского приложения, я бы не стал его трогать. Но вы можете получить его по адресу daol.aol.com/software/aoldesktop96 — обязательно прочитайте настройку, чтобы убедиться, что она не пытается сделать какие-либо «по умолчанию» для ваших программ. - person Ciel; 13.01.2011
comment
Если вы решите загрузить его, дайте мне знать, и я свяжусь с вами и покажу вам более подробно, что я делаю. - person Ciel; 13.01.2011