У меня есть окно со списком, созданным владельцем, во внешнем приложении (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
);