PDA

Просмотр полной версии : [Помогите!] использование WinApi на горячих клавишах


Sanych89
11.09.2010, 19:06
пишу для Perfect World, сразу говорю.
суть проблемы: не удаётся сделать переключение между окнами по нажатию комбинаций ctrl+1-ctrl+6 (аналогичное реализовано в Smurf IT!, но мне он не очень нравится - слишком много ненужного, и слишком много хочется изменить, чтобы работало именно так, как мне нравится).
горячие клавиши создаю следующим образом:
id[2] := GlobalAddAtom('Hotkey3');
RegisterHotKey(Handle, id[2], MOD_CONTROL, 49);
обработку делаю

procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;


procedure TForm1.WMHotKey(var Msg: TWMHotKey);
begin
if (Msg.HotKey = id[2]) then BringWindowToTop(clients[1]);
end;


в client[1] записан THandle нужного окна (записываю предварительно, проверял, работает).

и, собственно, эти горячие клавиши работают, если я их нажимаю из окна с программой.

другие горячие клавиши (вызывающие функции работы с памяти - флайхак и джампхак), запущенные не из окна с программой, работают корректно.
беда связана с использованием winapi, или с чем-то ещё? если нужно - могу скинуть полную/предельно облегчённую версию проекта.

Dinmaite
11.09.2010, 19:22
Не совсем понимаю чего ради ты создаешь атом, он тут ненужен, хватило бы простого числа. Кстати атомы закрывать не забываешь?

Sanych89
11.09.2010, 19:39
как раз и нужен, чтобы хоткеи работали из открытого окна с игрой. закрывать не забываю.

Dinmaite
11.09.2010, 19:46
Не нужны они, просто поименуй id'ы свои числами от 1 до n

Sanych89
11.09.2010, 19:54
и правда. не нужны) хорошо, но проблема с не переключением между окнами с игрой осталась актуальной.
и параллельно столкнулся с ещё одной: флайхак, взятый отсюда ([Ссылки могут видеть только зарегистрированные и активированные пользователи]), отказывается работать с не белым ником. для теста использовал персонажа с белым ником, персонажа с красным, и флагнувшегося. когда флаг проходит - летать снова можно.
так. убрал проверку
if (buf<>$0) and (buf<>$10) - заработало, но ник белеет. сейчас поизучаю)

да. у флагнутого 4, у красного 8. сейчас гляну промежуточные стадии.

0-3 - белый, 4-7 - флагнутый, 8-15 - реальные часы пк, 16-19 - полёт белого, 20-23 - полёт флагнутого, 23-31 - полёт красного, 32 - снова белый.
словом, эту проблему решил :) осталось с переключением, с чем и приходил :)

Dinmaite
11.09.2010, 20:08
Я в той теме писал, по поводу того что этот байт на самом деле отвечает не за полет, а за несколько состояний персонажа. Для того что бы избавиться от этого надо убрать проверку, а для того что бы не пропатчить случайно код неподходящего клиента установить проверку описанную во второй статье цикла.

Sanych89
11.09.2010, 20:21
просто выдавалась ошибка, если персонаж является красным или флагнутым. меня это смутило.
а про "на самом деле в по этому адресу находится битовая структура с флагами состояния персонажа, но для простоты мы будем работать с целым байтом" - честно говоря, я только теперь понял, о чём ты говорил. если надо, я переписал проверку, и теперь он адекватно взлетает и садится (уже одной кнопкой)
if (buf<>$0) and (buf<>$10) and (buf <> $4) and (buf <> $8) and (buf <> $14) and (buf <> $18) then
messagebox(0,'Неверная версия клиента','Пишем флайхак',16) else
begin
case buf of
$0: buf:=$10;
$4: buf:=$14;
$8: buf:=$18;
$10:buf:=$0;
$14:buf:=$4;
$18:buf:=$8;
end;
writeprocessmemory(hProcess,ptr(ipbuf+fly_offset), @buf,1,BytesCount);
end;


хм. подозреваю, где-то там же должно быть состояние "под водой". но его тестить не очень удобно, лень искать данж с водоёмом.

Dinmaite
11.09.2010, 20:35
Состояние "под водой" лежит не тут. А проверку ты переписал конечнор правильно, но к примеру если персонаж мертв - вылезет ошибка. Лучше сделай так как это описано во второй статье ""Патчер памяти 2" или "Пишем джампхак"".

Sanych89
11.09.2010, 20:58
про смерть - спасибо, опробую.
с тем, как менять код клиента игры, я ещё недоразобрался. да и проблема не совсем с ним, всё же скину облегчённую версию проекта, где останется только "проблемное".
коротко опишу, что оно делает: берёт Handle одного окна с игрой, по нажатии другой кнопки - Handle другого окна с игрой. дальше, по задумке, при нажатии ctrl+1, будет открываться первое окно, ctrl+2 - второе. но работает это только в случае, если окно программы активно.

Dinmaite
11.09.2010, 21:08
используй SetForegroundWindow.
А еще лучше так SetWindowPos(clients[i],HWND_TOP,0,0,0,0,SWP_NOSIZE or SWP_NOMOVE)

Sanych89
11.09.2010, 21:12
опа. спасибо. с SetForegroundWindow заработало.
пока гуглил, SetWindowPos напарывался, но почему-то решил, что изменение координат - перебор, и лучше пользоваться чем-то более простым