2009-06-10 3 views
2

Je souhaite pouvoir sélectionner quel élément est sélectionné dans la liste d'un autre programme (je n'ai pas accès à son code). En fait, c'est un SysListView32, que je suppose être le même. J'ai déjà le code suivant, ce qui malheureusement malgré la compilation, semble ne rien faire (même si SendMessage() renvoie 1).Réglage de l'élément sélectionné de la vue liste d'un autre programme

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

Répondre

0

Comment êtes-vous initialisez le reste des membres de la LV_ITEM source qui est copyied dans la mémoire du processus cible? Incluez-vous l'indicateur LVIF_STATE dans le membre "mask" de la source LV_ITEM? Si ce n'est pas le cas, ListView ignore les valeurs "state" et "stateMask" que vous essayez de spécifier.

+0

Pas vraiment: LVM_SETITEMSTATE spécifie que l'état de l'élément sera modifié. Pour ce message, le masque est ignoré. – Rom

0

Si vous êtes coincé, il y a un projet open source appelé AutoHotKey qui peut créer des scripts qui peuvent facilement sélectionner des éléments dans les listes, etc.

0

Vous devez réserver un espace d'adresse avant d'engager la mémoire. Vous pouvez faire les deux à la fois en changeant MEM_COMMIT-MEM_RESERVE|MEM_COMMIT

1

Le code suivant fonctionne comme un charme pour moi:

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

Il y a plusieurs raisons pour lesquelles votre code ne fonctionne pas:

  • comme Michael Dunn mentionné, vous devez réserver et commettre l'espace d'adresse. Intéressant est que votre exemple ne tente que de MEM_COMMIT la mémoire, mais alors MEM_RELEASE est-il (qui est opposé à MEM_RESERVE);
  • vous pourriez ne pas avoir assez de privilèges au processus qui possède la fenêtre;
  • votre processus et le processus cible peuvent être d'une autre taille. Certaines astuces de taille de structure peuvent être nécessaires dans ce cas.

Si tout cela ne fonctionne pas, je vous recommande d'essayer une approche différente: IAccessible pourrait être utile ici. Désistements habituels ici: déconner avec d'autres processus Windows et l'espace d'adresse nécessite une approche prudente et devrait être évitée si possible.

Questions connexes