Вверх ↑
Этот топик читают: Гость
Ответов: 94
Рейтинг: 2
#1: 2017-02-12 10:20:49 ЛС | профиль | цитата
Добрый день.
Разрабатываю приложение, которое будет отправлять сообщение в чат игры по нажатию горячей клавиши.
Что касается горячих клавиш - уже все готово и работает как задумано. Выложил схему в соответствующем разделе: http://forum.hiasm.com/topic/66343. Вдруг кому-то пригодится.
А вот с самой отправкой сообщения вышла проблема. Дело в том, что что-бы отправить сообщение, нужно:
1. Нажать F6, чем вызвать поле ввода сообщения;
2. Написать сообщение;
3. Нажать Enter - отправить сообщение.
Я решил проблему просто: эмуляция нажатия F6, вставляю текст (сделал через буфер обмена), эмуляция Enter. И такое решение работает со всеми клавишами и их комбинациями, кроме как с клавишей Alt. Дело в том, что Alt блокирует все клавиши, даже F6. То есть, если я на комбинацию Alt+1 установлю отправку текста в чат, то эмуляцию F6 и Enter возможно выполнить только когда Alt отпущен физически. Единственная разумная идея - отключить Alt на время эмуляции и потом включить.
Вот тот кусок схемы, который отвечает за отправку:

Add(Hub,12309349,1260,266)
{
OutCount=8
link(onEvent2,3047092:doPressUp,[(1320,279)(1320,251)])
link(onEvent3,11542843:doValue,[])
link(onEvent4,16191370:doSetText,[])
link(onEvent5,16191370:doPut,[])
link(onEvent6,11894525:doTimer,[(1345,307)(1345,335)])
link(onEvent7,4550138:doPressUp,[(1339,314)(1339,419)])
link(onEvent8,15271061:doTimer,[(1320,321)(1320,447)])
}
Add(GlobalVar,10397611,1386,371)
{
Name="13"
Data=Integer(13)
}
Add(GlobalVar,11015546,1372,203)
{
Name="117"
Data=Integer(117)
}
Add(ClipboardHook,16191370,1365,287)
{
link(Text,11640289:Value,[(1371,261)(1249,261)(1249,306)(1217,306)])
}
Add(Clipboard,1518316,1407,231)
{
Unicode=0
Point(PutText)
}
Add(Memory,11542843,1407,280)
{
Point(Data)
link(Data,1518316:Text,[])
}
Add(DoData,959419,1407,329)
{
link(onEventData,12345626:doPutText,[])
link(Data,11542843:Value,[])
}
Add(Timer,11894525,1365,329)
{
Interval=200
Enable=1
AutoStop=1
link(onTimer,959419:doData,[])
}
Add(Clipboard,12345626,1456,329)
{
Unicode=0
Point(PutText)
}
Add(KeyEvent,3047092,1365,231)
{
link(Code,11015546:Var,[])
}
Add(KeyEvent,4550138,1379,399)
{
Ctrl=1
link(Code,10397611:Var,[])
}
Add(Timer,15271061,1365,441)
{
Interval=800
Enable=1
AutoStop=1
}
Add(Memory,11640289,1211,266)
{
link(onData,12309349:doEvent1,[])
}

Поиск на форуме привел только к мифическому элементу Joke, но он мне не совсем подходит, так как он заблокирует всю клавиатуру, а мне нужна еще клавиша Enter. Да и сам элемент найти я не смог, что-бы поковырять изучить его.
Если есть у кого-то идеи лучше моих (отправка по отпусканию Alt или отключение Alt), то буду благодарен.
карма: 0

0
vip
#1.1контекстная реклама от партнеров
Ответов: 321
Рейтинг: 10
#2: 2017-02-12 12:57:53 ЛС | профиль | цитата
http://forum.hiasm.com/topic/60108
Вот такую программку сделал 5 лет назад, через sendMessege

Привет всем, сделал программку именуемую Realmlister + wow clicker, вот решил поделиться .
По названию в принципе понятен ее функционал - это быстрый выбор необходимого адреса сервера (realmlist'a) и ВоВ кликер.

Плюсы программы:
К каждому серверу можно добавлять заметки / примечания, которые в следующем будут отображаться в сплывающей подсказке при выборе определенного адреса сервера в Вашем списке.
Кликер не будет мешает посторонним окнам, он работает только с клиентом игры, то есть вы можете спокойно общаться в icq или vk.
При печатании текста в чате, не будет появляться различные символы от автокликера, то есть печатаем как есть и лишнее в чат не лезет...
Имеется возможность пингования серверов и определения ip адреса сервера, например при выборе сервера для игры можно пропинговать интересующий Вам список серверов и начинать играть на том, где пинг будет более стабильный.

Минусы программы:
Если пишете сообщение в чат, то кликать например клавишу "1" он формально не будет. То есть пока не допечатаете и не отправите свое сообщение.

Вот скопировал текст с программы (это есть в программе, можно и там почитать):
Для работы программы необходимо:
Располагать программу в корневой директории игры World Of Warcraft, то есть в папке с wow.exe.
В свойствах realmlist.wtf (wow/data/ruru/realmlist.wtf ) необходимо убрать галочку с опции "Только чтение".

Автокликер:
Нажимаем кнопку "Найти ВоВ", чтобы обнаружить окно игры.
В поле ввода "Key" вводим клавишу, в поле ввода "3000" вводим время.
Время указываем в миллисекундах, 1000 миллисекунд = 1 секунде.
Нажимаем кнопку "Старт/Стоп" для включения и отключения кликера.
Если кликер включен горит зеленая лампочка, и красная в противном случае.

Два способа запуска игры в программе:
Двойной клик по кнопке "Играть" - запуск игры и закрытие программы.
Двойной клик по логотипу "World Of Warcraft" - запуск игры без закрытия программы.

Пингование:
При клике по адресу сервера в левом нижнем углу появится информация о сервере.



Или более сложная программка...

https://wowjp.net/forum/11-295100-1
Или более сложная программка, тут бот для игры, мало того что бот, так еще и чит). То есть сам телепортируется куда надо, сам что-то собирает, аналогично с предыдущим вариантом используется SendMessage

Редактировалось 5 раз(а), последний 2017-02-12 13:20:39
карма: 1

1
Голосовали:lipKAI
Ответов: 94
Рейтинг: 2
#3: 2017-02-12 13:44:45 ЛС | профиль | цитата
Master4eG, спасибо за совет. SendMessage я рассматривал изначально. Но так и не смог понять как определить сообщение. Сейчас буду пытаться разобраться снова.
Сейчас попробую поковырять Microsoft Spy++.

Редактировалось 1 раз(а), последний 2017-02-12 13:52:50
карма: 0

0
Ответов: 94
Рейтинг: 2
#4: 2017-02-13 10:51:28 ЛС | профиль | цитата
В общем, поковыряв Spy++ (очень очень крутая программа), пришел к выводу, что SendMessage действительно то что нужно. Я вызываю нажатие клавиши сообщением WM_KEYUP (открываю чат и эмулирую клавишу Enter для отправки сообщения), а текст пишу через WM_CHAR без необходимости эмулировать нажатия клавиш. Правда придется текст вставлять не целиком, а по-символьно и необходимо решить вопрос с раскладкой клавиатуры.
Я еще подумаю над менее деревянным решением, но во всяком случае я увидел, что мою проблему можно решить - это просвет в моей голове .
Master4eG, огромная благодарность за наводку
карма: 0

0
Ответов: 94
Рейтинг: 2
#5: 2017-02-13 17:00:31 ЛС | профиль | цитата
Все, вопрос полностью решен. Все как указывал выше:
1. Через SendMessage эмулирую нажатие клавишу F6, что-бы открыть чат.
2. Через Srt_Enum отправляю текст по-симовльно в CharToInt и от туда вызываю событие SendMessage (WM_CHAR). Так я вставляю каждый символ в чат.
3. Через SendMessage эмулирую нажатие клавишу Enter - отправляю.

Так как задержки нет, то текст отправляется мгновенно.

Еще раз огромное спасибо за ссылку Master4eG.
карма: 0

0
Ответов: 94
Рейтинг: 2
#6: 2017-02-15 20:44:37 ЛС | профиль | цитата
Решил поделится продолжением решения своей проблемы. К сожалению, последнее описание решения оказалось не "молниеносным", как мне показалось.
Поэтому я пошел дальше и узнал про функцию WIN32 - SendInput, которая используется в программе Auto Hot Key. Порывшись в интернете, я понял, что без IC не обойтись. Начал искать примеры на нашем форуме и нашел пример miver, который он давал:
miver писал(а):

Lora, Вот пример для гугла. Запускаешь и жмешь кнопку . Если мышь не попадает в строку поиска, то поменяй координаты в Math
Add(MainForm,2953706,224,147)
{
Position=1
Point(onChar)
}
Add(Button,3183747,224,98)
{
Left=20
Top=20
link(onClick,6035832:doEvent1,[])
}
Add(Hub,6035832,273,98)
{
link(onEvent1,11696987:doShellExec,[])
link(onEvent2,9055368:doTimer,[])
}
Add(Timer,9055368,308,105)
{
Interval=5000
Enable=1
AutoStop=1
link(onTimer,1546650:doEvent1,[(347,111)(347,146)])
}
Add(InlineCode,13982809,427,301)
{
WorkPoints=#11:doSendInput
DataPoints=#3:txt
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses Windows,kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|20: txt: THI_Event;|56: procedure doSendInput(var _Data:TData; Index:word);|5: end;|0:|14:implementation|0:|34:procedure THiAsmClass.doSendInput;|5:const|29: INPUT_KEYBOARD: DWORD = 1;|29: //Str: string = 'writing';|3:var|14: Str: string;|14: Inp: TInput;|13: I: Integer;|5:begin|32: Str := ReadString(_Data, txt);|12: Sleep(80);|30: for I := 1 to Length(Str) do|7: begin|12: // press|32: Inp.Itype := INPUT_KEYBOARD;|38: Inp.ki.wVk := Ord(UpCase(Str[i]));|24: Inp.ki.dwFlags := 0;|38: SendInput(1, Inp, SizeOf(TInput));|0:|14: // release|32: Inp.Itype := INPUT_KEYBOARD;|38: Inp.ki.wVk := Ord(UpCase(Str[i]));|38: Inp.ki.dwFlags := KEYEVENTF_KEYUP;|38: SendInput(1, Inp, SizeOf(TInput));|14: Sleep(80);|6: end;|4:end;|4:end.|
link(txt,14100768:Text,[])
}
Add(VisualStrings,14100768,427,266)
{
Lines=#5:HiAsm|
Width=81
}
Add(WinExec,11696987,357,91)
{
Param="notepad.exe"
FileName="http://www.google.com"
}
Add(MouseEvent,7752767,434,203)
{
Point(Handle)
link(X,2754826:Result,[])
link(Y,15517310:Result,[(454,187)(489,187)])
}
Add(Math,2754826,441,140)
{
@Hint=#43:аžб‚бб‚бƒаП баЛаЕаВаА аОб‚ аЛаЕаВаОаГаО аВаЕб€б…аНаЕаГаО бƒаГаЛаА баКб€аАаНаА|
OpType=1
Op1=500
ResultType=0
link(Op2,7752767:MouseX,[(454,131)(531,131)(531,250)(440,250)])
AddHint(39,-82,187,26,@Hint)
AddHint(39,-50,42,13,Op1)
}
Add(Hub,1546650,378,140)
{
OutCount=6
link(onEvent1,2754826:doOperation,[])
link(onEvent2,15517310:doOperation,[])
link(onEvent3,7752767:doMove,[(417,160)(417,216)])
link(onEvent4,7752767:doClick,[(424,167)(424,209)])
link(onEvent5,13982809:doSendInput,[(410,174)(410,307)])
}
Add(Math,15517310,483,147)
{
@Hint=#44:аžб‚бб‚бƒаП баВаЕб€б…бƒ аОб‚ аЛаЕаВаОаГаО аВаЕб€б…аНаЕаГаО бƒаГаЛаА баКб€аАаНаА|
OpType=1
Op1=400
ResultType=0
link(Op2,7752767:MouseY,[(496,138)(524,138)(524,243)(447,243)])
AddHint(82,-35,191,26,@Hint)
AddHint(83,-2,42,13,Op1)
}

Я был прав - без IC не обойтись. К сожалению, данный код не отправлял текст в кириллице. Но работал, как мне показалось, идеально - текст отправлялся молниеносно.
Были попытки начать изучать Delphi, совместно с IC, но такой подход отталкивал решение проблемы на несколько недель (минимум) вперед. И вот огромное спасибо Netspirit, который все же помог мне с кириллицей - теперь сообщения отправляются в чат как положено и быстро! С разрешения Netspirit я делюсь данным кодом на форуме, так как по поиску я понял, что подобная проблема поднимается стабильно по нескольку раз в год. Собственно код:
Add(MainForm,2953706,21,105)
{
Position=1
}
Add(Button,10504036,182,210)
{
Left=10
Top=30
Width=100
Caption="Отослать"
link(onClick,11970995:doKeyStroke,[])
}
Add(InlineCode,11970995,266,210)
{
WorkPoints=#61:doKeyStroke=Симулировать набор на клавиатуре указанной строки
EventPoints=#8:onResult|
DataPoints=#3:Str|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|4:uses|29: KOL, Share, Debug, Windows;|0:|0:|4:type|1: |29: PMouseInput = ^TMouseInput;|31: tagMOUSEINPUT = packed record|16: dx: Longint;|16: dy: Longint;|21: mouseData: DWORD;|19: dwFlags: DWORD;|16: time: DWORD;|23: dwExtraInfo: DWORD;|6: end;|30: TMouseInput = tagMOUSEINPUT;|0:|29: PKeybdInput = ^TKeybdInput;|31: tagKEYBDINPUT = packed record|14: wVk: WORD;|16: wScan: WORD;|19: dwFlags: DWORD;|16: time: DWORD;|23: dwExtraInfo: DWORD;|6: end;|30: TKeybdInput = tagKEYBDINPUT;|0:|35: PHardwareInput = ^THardwareInput;|34: tagHARDWAREINPUT = packed record|16: uMsg: DWORD;|18: wParamL: WORD;|18: wParamH: WORD;|6: end;|36: THardwareInput = tagHARDWAREINPUT;|0:|19: PInput = ^TInput;|26: tagINPUT = packed record|17: Itype: DWORD;|19: case Integer of|27: 0: (mi: TMouseInput);|27: 1: (ki: TKeybdInput);|30: 2: (hi: THardwareInput);|6: end;|20: TInput = tagINPUT;|0:|0:|0:|29: THiAsmClass = class(TDebug)|11: private|0:|10: public|21: Str: THI_Event;|29: onResult: THI_Event; |59: procedure doKeyStroke(var _Data: TData; Index: Word);|6: end;|2: |129: function SendInput(cInputs: UINT; var pInputs: TInput; cbSize: Integer): UINT; stdcall; external 'user32.dll' name 'SendInput';|0:|5:const|18: INPUT_MOUSE = 0;|21: INPUT_KEYBOARD = 1;|21: INPUT_HARDWARE = 2;|2: |32: KEYEVENTF_EXTENDEDKEY = $0001;|26: KEYEVENTF_KEYUP = $0002;|28: KEYEVENTF_UNICODE = $0004;|29: KEYEVENTF_SCANCODE = $0008;|2: |22: MAPVK_VK_TO_VSC = 0;|22: MAPVK_VSC_TO_VK = 1;|23: MAPVK_VK_TO_CHAR = 2;|25: MAPVK_VSC_TO_VK_EX = 3;|2: |2: |14:implementation|0:|0:|0:|42:procedure SimulateKeyPress(Key: WideChar);|3:var|31: Input: array[0..1] of TInput;|5:begin|36: FillChar(Input, SizeOf(Input), 0);|18: with Input[0] do|7: begin|28: Itype := INPUT_KEYBOARD;|14: with ki do|9: begin|25: wScan := Word(Key);|34: dwFlags := KEYEVENTF_UNICODE|8: end;|6: end;|18: with Input[1] do|7: begin|28: Itype := INPUT_KEYBOARD;|14: with ki do|9: begin|25: wScan := Word(Key);|54: dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;|8: end;|6: end;|53: SendInput(Length(Input), Input[0], SizeOf(TInput));|4:end;|0:|0:|66:procedure THiAsmClass.doKeyStroke(var _Data: TData; Index: Word); |3:var|16: S: WideString;|13: I: Integer;|5:begin|34: S := ReadString(_Data, Str, '');|2: |28: for I := 1 to Length(S) do|7: begin|27: SimulateKeyPress(S[I]);|6: end;|39: _hi_CreateEvent(_Data, @onResult, 0);|4:end;|0:|0:|4:end.|
link(Str,13116176:Text,[])
}
Add(Edit,13116176,266,154)
{
Left=10
Top=5
Width=365
Text="абвгде"
}

Но что забавно. Начал проверять работоспособность и опять наткнулся на старые грабли: клавиша Alt снова мешает и на комбинацию "Alt +" ничего не поставить.
Вот такая схема, например, почему-то не работает:
Add(MainForm,3267288,770,322)
{
link(onCreate,13842337:doStartHotKey,[])
}
Add(GHotKey,13842337,819,336)
{
Alt=1
Key=49
link(onEventHotKey,11970995:doKeyStroke,[])
}
Add(InlineCode,11970995,868,336)
{
WorkPoints=#61:doKeyStroke=Симулировать набор на клавиатуре указанной строки
EventPoints=#8:onResult|
DataPoints=#3:Str|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|4:uses|29: KOL, Share, Debug, Windows;|0:|0:|4:type|1: |29: PMouseInput = ^TMouseInput;|31: tagMOUSEINPUT = packed record|16: dx: Longint;|16: dy: Longint;|21: mouseData: DWORD;|19: dwFlags: DWORD;|16: time: DWORD;|23: dwExtraInfo: DWORD;|6: end;|30: TMouseInput = tagMOUSEINPUT;|0:|29: PKeybdInput = ^TKeybdInput;|31: tagKEYBDINPUT = packed record|14: wVk: WORD;|16: wScan: WORD;|19: dwFlags: DWORD;|16: time: DWORD;|23: dwExtraInfo: DWORD;|6: end;|30: TKeybdInput = tagKEYBDINPUT;|0:|35: PHardwareInput = ^THardwareInput;|34: tagHARDWAREINPUT = packed record|16: uMsg: DWORD;|18: wParamL: WORD;|18: wParamH: WORD;|6: end;|36: THardwareInput = tagHARDWAREINPUT;|0:|19: PInput = ^TInput;|26: tagINPUT = packed record|17: Itype: DWORD;|19: case Integer of|27: 0: (mi: TMouseInput);|27: 1: (ki: TKeybdInput);|30: 2: (hi: THardwareInput);|6: end;|20: TInput = tagINPUT;|0:|0:|0:|29: THiAsmClass = class(TDebug)|11: private|0:|10: public|21: Str: THI_Event;|29: onResult: THI_Event; |59: procedure doKeyStroke(var _Data: TData; Index: Word);|6: end;|2: |129: function SendInput(cInputs: UINT; var pInputs: TInput; cbSize: Integer): UINT; stdcall; external 'user32.dll' name 'SendInput';|0:|5:const|18: INPUT_MOUSE = 0;|21: INPUT_KEYBOARD = 1;|21: INPUT_HARDWARE = 2;|2: |32: KEYEVENTF_EXTENDEDKEY = $0001;|26: KEYEVENTF_KEYUP = $0002;|28: KEYEVENTF_UNICODE = $0004;|29: KEYEVENTF_SCANCODE = $0008;|2: |22: MAPVK_VK_TO_VSC = 0;|22: MAPVK_VSC_TO_VK = 1;|23: MAPVK_VK_TO_CHAR = 2;|25: MAPVK_VSC_TO_VK_EX = 3;|2: |2: |14:implementation|0:|0:|0:|42:procedure SimulateKeyPress(Key: WideChar);|3:var|31: Input: array[0..1] of TInput;|5:begin|36: FillChar(Input, SizeOf(Input), 0);|18: with Input[0] do|7: begin|28: Itype := INPUT_KEYBOARD;|14: with ki do|9: begin|25: wScan := Word(Key);|34: dwFlags := KEYEVENTF_UNICODE|8: end;|6: end;|18: with Input[1] do|7: begin|28: Itype := INPUT_KEYBOARD;|14: with ki do|9: begin|25: wScan := Word(Key);|54: dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;|8: end;|6: end;|53: SendInput(Length(Input), Input[0], SizeOf(TInput));|4:end;|0:|0:|66:procedure THiAsmClass.doKeyStroke(var _Data: TData; Index: Word); |3:var|16: S: WideString;|13: I: Integer;|5:begin|34: S := ReadString(_Data, Str, '');|2: |28: for I := 1 to Length(S) do|7: begin|27: SimulateKeyPress(S[I]);|6: end;|39: _hi_CreateEvent(_Data, @onResult, 0);|4:end;|0:|0:|4:end.|
link(Str,13116176:Text,[])
}
Add(Edit,13116176,868,287)
{
Left=10
Top=5
Width=365
Text="абвгде"
}

Редактировалось 7 раз(а), последний 2017-02-16 00:42:40
карма: 0

0
6
Сообщение
...
Прикрепленные файлы
(файлы не залиты)