Настройка списка выбранных элементов другой программы - PullRequest
2 голосов
/ 10 июня 2009

Я хочу иметь возможность выбрать, какой элемент будет выбран в списке другой программы (у меня нет доступа к его коду). На самом деле, это SysListView32, который я предполагаю, то же самое. У меня уже есть следующий код, который, к сожалению, несмотря на компиляцию, кажется, ничего не делает (хотя SendMessage () возвращает 1).

process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, 0xD14); 

 _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 

 lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
 lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED; 

 WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL); 
 int abc = ::SendMessage((HWND)0x00050D30, LVM_SETITEMSTATE, (WPARAM)2, (LPARAM)_lvi); 
 VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);

Ответы [ 4 ]

1 голос
/ 01 июля 2009

Следующий код работает для меня как шарм:

HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, 0x0000c130);
LPVOID epLvi = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

LVITEM lvi;
lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
SIZE_T cbWritten = 0;
WriteProcessMemory(hProcess, epLvi, &lvi, sizeof(lvi), &cbWritten);
DWORD dw = SendMessage((HWND)0x00020C4C, LVM_SETITEMSTATE, 1, (LPARAM)epLvi);

VirtualFreeEx(hProcess, epLvi, 4096, MEM_DECOMMIT | MEM_RELEASE);
CloseHandle(hProcess);

Существует несколько причин, по которым ваш код может не работать:

  • как упоминал Майкл Данн, вам нужно зарезервировать и зафиксировать адресное пространство. Интересно, что ваш пример только пытается MEM_COMMIT память, но затем MEM_RELEASE это (что противоположно MEM_RESERVE);
  • возможно, у вас недостаточно прав для процесса, которому принадлежит окно;
  • Ваш процесс и целевой процесс могут иметь разную битность. В этом случае могут потребоваться некоторые трюки с размером конструкции.

Если все это не работает, я бы порекомендовал попробовать другой подход: IAccessible может быть полезно здесь. Обычные отказы от ответственности здесь: путаница с окнами других процессов и адресным пространством требует осторожного подхода и его следует по возможности избегать.

0 голосов
/ 13 июня 2009

Если вы застряли, есть проект с открытым исходным кодом, называемый AutoHotKey, который может создавать сценарии, которые могут легко выбирать элементы в списках и т. Д.

0 голосов
/ 24 июня 2009

Вы должны зарезервировать адресное пространство перед выделением памяти. Вы можете сделать оба сразу, изменив MEM_COMMIT на MEM_RESERVE|MEM_COMMIT

0 голосов
/ 11 июня 2009

Как вы инициализируете остальные элементы исходного LV_ITEM, который копируется в память целевого процесса? Включаете ли вы флаг LVIF_STATE в элемент «mask» исходного LV_ITEM? Если нет, то ListView будет игнорировать значения «state» и «stateMask», которые вы пытаетесь указать.

...