Здравствуйте, Alexander G, Вы писали:
AG>Невиртуальные и не должны. Всё ли правильно делаете?
AG> Сообщение WM_NOTIFY отсылается родителю SysListView32, а не ему самому, сам SysListView32 в параметрах сообщения
AG> перед отправкой заполняются соответствующие поля NMLVDISPINFO
AG> это сообщение нельзя слать из другого процесса
Привожу код, с помощью которого я это делал.
Первые два пункта выполнил, а вот про третий не знал (в статье про LVN_GETDISPINFO на MSDN'e про это не говорится, но наверное подразумевается). Я так понимаю, что необходимо встроить свою Dll в другой процесс и посылать это сообщение из нее?
Спасибо за наводку, вечером попробую.
int GetListViewItemText2(HWND handle, int row, int column, LPTSTR text, int size) {
const int SIZE = 512;
TCHAR item[SIZE];
LPTSTR _item;
unsigned long pid;
HANDLE process;
NMLVDISPINFO info, *_info;
GetWindowThreadProcessId(handle, &pid);
process = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
FALSE,
pid);
//log(string("process: ") + to_string((llong) process));
_info = (NMLVDISPINFO*) VirtualAllocEx(process, NULL, sizeof(NMLVDISPINFO), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
_item = (LPTSTR) VirtualAllocEx(process, NULL, SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
memset(&info, 0, sizeof(NMLVDISPINFO));
memset(item, 0, SIZE);
int controlId = GetDlgCtrlID(handle);
info.hdr.code = LVN_GETDISPINFO;
info.hdr.idFrom = controlId;
info.hdr.hwndFrom = handle;
info.item.iItem = row;
info.item.mask = LVIF_TEXT;
info.item.iSubItem = column;
info.item.pszText = _item;
info.item.cchTextMax = SIZE;
SIZE_T* bytes = new SIZE_T;
*bytes = 0;
LRESULT res = WriteProcessMemory(process, _info, &info, sizeof(NMLVDISPINFO), bytes);
if (!res) {
DWORD error = GetLastError();
log(string("WriteProcessMemory error: ") + to_string((llong) error));
}
HWND parent = (HWND) GetWindowLongPtr(handle, GWL_HWNDPARENT);
res = SendMessage(parent, WM_NOTIFY, (WPARAM) controlId, (LPARAM) _info);
res = ReadProcessMemory(process, _item, item, SIZE, bytes);
if (!res) {
DWORD error = GetLastError();
log(string("ReadProcessMemory error: ") + to_string((llong) error));
}
// TODO: refactor
int i;
for (i = 0; i + 1 < size && item[i]; ++i) {
text[i] = item[i];
}
text[i] = 0;
int result = _tlen(item);
VirtualFreeEx(process, _info, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
delete bytes;
CloseHandle(process);
return result;
}