|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Хэндл окна - без класса и имени
Ситуация проста. Клепаю оверлей для упрощения некоторых действий в игре. Чтобы передать игре действия, достаточно просто передавать окну игры нужные комбинации клавиш - это не проблема.
Проблема в том, что мне нужно получить handle этого окна, чтобы что-то в него передать. По названию я его получить не могу: добрые и умные разработчики, видимо, тешатся каждым патчем, и добавляют его номер и цифровой код к названию окна игры. Очень желательно, чтобы прога могла ловить несколько версий игры без необходимости обновлять её руками. Просить пользователя ткнуть мышкой в окно или написать номер/код патча - неспортивно. Ок, обратимся к классу окна. Здесь нас тоже ждёт облом: класс - SDL_app, и у нас есть немаленький риск поймать совсем не то, что мы хотим. При разработке проги не для себя такая жирная вероятность проблем с программой - совершенно не вариант. Номер версии в файлах в папке с игрой нигде не встречается. В мета-данных exe-файла тоже нет этого номера. Единственное, что остаётся неизменно версия от версии - это название процесса. Проверено. Вопрос: как в таких условиях получить-таки злополучный handle искомого окна? Заранее спасибо. Если не ты, то кто? (с) Терри Пратчетт Не забывайте ставить плюсы и говорить спасибо! |
#2
|
||||
|
||||
Первое, что приходит в голову - перечислить окна (EnumWindows) и по косвенным признакам (имя процесса окна, кусок текста в названии окна и т.д.) выявить нужное.
jmp $ ; Happy End! The Cake Is A Lie. |
#3
|
||||
|
||||
Ага, я уже сам догадался до этого. Код даже искать не пришлось, взял по поисковому запросу в гугле.
Для исторической справки: Код:
function SearchForWindow(const Caption: String): HWND; var hWin: HWND; buff: array [0..255] of Char; begin hWin:= GetWindow(GetForegroundWindow, GW_HWNDFIRST); while hWin <> 0 do begin GetWindowText(hWin, buff, 255); if Pos(Caption, buff) <> 0 then break; hWin:= GetWindow(hWin, GW_HWNDNEXT); end; Result:= hWin; end; Однако, теперь у меня другая проблема. которая вводит меня в ступор. Спрошу здесь, дабы не создавать новую тему. Я не могу отправить ничему сообщение SendMessage/PostMessage из приложения. То есть буквально. Пробовал отправить сообщение Notepad-подобной программе, случайную комбинацию в оконное приложение, етц. Не работает как вот это: Код:
SendMessage(Handle,WM_SETFOCUS,0,0); Код:
SendMessage(Handle, WM_KEYDOWN, ord('G'), 0); sleep(100); SendMessage(Handle, WM_KEYUP, ord('G'), 0); Handle определяется 100% верно, я проверил. ShowWindow работает стабильно. Что нужно: переключить фокус на окно (если это выбрано в опциях), передать ему нужную комбинацию клавиш. Если не ты, то кто? (с) Терри Пратчетт Не забывайте ставить плюсы и говорить спасибо! |
#4
|
||||
|
||||
1. Получаешь список хендлов, примерно так:
Код:
function GetWindowClass( Handle : THandle ) : String; var WText : PChar; TxtBuf : String; begin GetMem( WText,255 ); GetClassName( Handle,WText,255 ); TxtBuf := WText; Result := TxtBuf; FreeMem( WText ); end; var wnd: hwnd; begin ListBox1.clear; wnd := GetWindow(handle, gw_hwndfirst); while wnd <> 0 do begin if (wnd <> Application.Handle) // Собственное окно and IsWindowVisible(wnd) // Невидимые окна and (GetWindow(wnd, gw_owner) = 0) // Дочерние окна then ListBox1.Items.Add(GetWindowClass(wnd));//wnd сохраняем в переменную для последующих манипуляций wnd := GetWindow(wnd, gw_hwndnext); end; ListBox1.ItemIndex := 0; end; 2. Потом, если имя класса наше, определяем исполняемый файл: 1 способ Код:
function getfilepath(const winh: thandle): string; var snapshoth: thandle; pe32: tprocessentry32; prid: cardinal; begin result := ''; snapshoth := createtoolhelp32snapshot(th32cs_snapprocess, 0); if snapshoth = -1 then exit; pe32.dwsize := sizeof(pe32); getwindowthreadprocessid(winh, prid); if process32first(snapshoth, pe32) then repeat if pe32.th32processid = prid then begin result := pe32.szexefile; break; end; until not process32next(snapshoth, pe32); closehandle(snapshoth) end; 2 способ Код:
function getappfilename (hwnd: thandle) :string; var dpid: dword; hhandle: thandle; begin getwindowthreadprocessid(hwnd, @dpid); setlength (result, max_path); hhandle := openprocess(process_query_information or process_vm_read, true, dpid); if getmodulefilenameex (hhandle, 0, pchar (result), max_path) > 0 then setlength (result, strlen (pchar (result))); end; procedure tform1.formcreate(sender: tobject); var handle :thandle; begin handle := findwindow (nil, 'microsoft excel - Книга2'); edit1.text := getappfilename (handle); end; Последний раз редактировалось Vayrus, 17.10.2015 в 18:47. |
Этот пользователь сказал Спасибо Vayrus за это полезное сообщение: | ||
EvilRussian (21.10.2015)
|