Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.10.2015, 02:19
Аватар для EvilRussian
EvilRussian EvilRussian вне форума
Начинающий
 
Регистрация: 21.12.2010
Адрес: Россия, Красноярский край
Сообщения: 177
Репутация: 22
По умолчанию Хэндл окна - без класса и имени

Ситуация проста. Клепаю оверлей для упрощения некоторых действий в игре. Чтобы передать игре действия, достаточно просто передавать окну игры нужные комбинации клавиш - это не проблема.
Проблема в том, что мне нужно получить handle этого окна, чтобы что-то в него передать. По названию я его получить не могу: добрые и умные разработчики, видимо, тешатся каждым патчем, и добавляют его номер и цифровой код к названию окна игры. Очень желательно, чтобы прога могла ловить несколько версий игры без необходимости обновлять её руками. Просить пользователя ткнуть мышкой в окно или написать номер/код патча - неспортивно.
Ок, обратимся к классу окна. Здесь нас тоже ждёт облом: класс - SDL_app, и у нас есть немаленький риск поймать совсем не то, что мы хотим. При разработке проги не для себя такая жирная вероятность проблем с программой - совершенно не вариант.
Номер версии в файлах в папке с игрой нигде не встречается. В мета-данных exe-файла тоже нет этого номера.
Единственное, что остаётся неизменно версия от версии - это название процесса. Проверено.

Вопрос: как в таких условиях получить-таки злополучный handle искомого окна?

Заранее спасибо.
__________________
Если не ты, то кто?
(с) Терри Пратчетт

Не забывайте ставить плюсы и говорить спасибо!
Ответить с цитированием
  #2  
Старый 15.10.2015, 21:57
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Первое, что приходит в голову - перечислить окна (EnumWindows) и по косвенным признакам (имя процесса окна, кусок текста в названии окна и т.д.) выявить нужное.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #3  
Старый 15.10.2015, 23:48
Аватар для EvilRussian
EvilRussian EvilRussian вне форума
Начинающий
 
Регистрация: 21.12.2010
Адрес: Россия, Красноярский край
Сообщения: 177
Репутация: 22
По умолчанию

Ага, я уже сам догадался до этого. Код даже искать не пришлось, взял по поисковому запросу в гугле.

Для исторической справки:
Код:
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  
Старый 17.10.2015, 18:45
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
По умолчанию

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)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:31.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter