Keybd_Event为什么在游戏中模拟按键失效了??求解!

zhanghao16 2007-03-13 09:15:34
前因:这段时间小弟玩《三国群英传三》打到三国归魏。因为难度太高,所以在网下查了密技。可是每次要敲击一串字符,故想写一个类拟于按键精灵的东西简化输入。例如,开启游戏Debug-后输入ods3on。加钱-输入money99999。我想做成按F1模拟ods3on,F2模拟money99999.
思路:做一个全局键盘勾子。当在游戏中勾到F1时,用Keybd_Event模拟键盘按下ods3on。当勾到F2时,用用Keybd_Event模拟键盘按下money99999.
问题:完成代码后,在记事本,IE地址栏都可以成功实现按下F1显示ods3on,接下F2显示money99999。可在《三国群英传三》游戏中使用无效。
相关代码:
{sg.dll}
library sg;

uses
SysUtils,
Classes,
WinTypes,
WinProcs,
Messages;

var
IsHooked: Boolean;
HookHandle: HHook;

function HookProc(nCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if (nCode > -1) then
begin
if (wParam = VK_F1) then
begin
if ((lParam shr 31) =1) then
begin
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), 0,0);
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('D'), MapVirtualKey(Ord('D'),0), 0,0);
Keybd_Event(Ord('D'), MapVirtualKey(Ord('D'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('S'), MapVirtualKey(Ord('S'),0), 0,0);
Keybd_Event(Ord('S'), MapVirtualKey(Ord('S'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('3'), MapVirtualKey(Ord('3'),0), 0,0);
Keybd_Event(Ord('3'), MapVirtualKey(Ord('3'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), 0,0);
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('N'), MapVirtualKey(Ord('N'),0), 0,0);
Keybd_Event(Ord('N'), MapVirtualKey(Ord('N'),0), KEYEVENTF_KEYUP,0);
//MessageBeep(0);
end;
Result := 1;
end//打开密技
else if (wParam = VK_F2) then
begin
if ((lParam shr 31) =1) then
begin
Keybd_Event(Ord('M'), MapVirtualKey(Ord('M'),0), 0,0);
Keybd_Event(Ord('M'), MapVirtualKey(Ord('M'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), 0,0);
Keybd_Event(Ord('O'), MapVirtualKey(Ord('O'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('N'), MapVirtualKey(Ord('N'),0), 0,0);
Keybd_Event(Ord('N'), MapVirtualKey(Ord('N'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('E'), MapVirtualKey(Ord('E'),0), 0,0);
Keybd_Event(Ord('E'), MapVirtualKey(Ord('E'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('Y'), MapVirtualKey(Ord('Y'),0), 0,0);
Keybd_Event(Ord('Y'), MapVirtualKey(Ord('Y'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), 0,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), 0,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), 0,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), 0,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), KEYEVENTF_KEYUP,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), 0,0);
Keybd_Event(Ord('9'), MapVirtualKey(Ord('9'),0), KEYEVENTF_KEYUP,0);
//MessageBeep(0);
end;
Result := 1;
end//每城钱财加99999
else
Result := 0;
end
else
Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;

function SetHook: Boolean; stdcall;
begin
Result := False;
if IsHooked then
Exit;
HookHandle := SetWindowsHookEx(WH_KEYBOARD, HookProc, HInstance, 0);
Result := HookHandle <> 0;
end;

function RemoveHook: Boolean; stdcall;
begin
Result := False;
if (not IsHooked) and (HookHandle <>0) then
Result := UnHookWindowsHookEx(HookHandle);
IsHooked := False;
end;

exports
SetHook name 'SetHook',
RemoveHook name 'RemoveHook',
HookProc name 'HookProc';

begin
IsHooked := False;
end.

{sanguo3.exe}
unit sanguo3
...
...
function SetHook; external 'sg.dll' name 'SetHook';
function RemoveHook; external 'sg.dll' name 'RemoveHook';


procedure TForm1.Button1Click(Sender: TObject);
begin
if SetHook then
Caption := '三国密技-启动'
else Caption := '三国密技-启动失败'
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if RemoveHook then
Caption := '三国密技-关闭'
else Caption := '三国密技-关闭失败'
end;
...
...
...全文
4398 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhanghao16 2007-06-10
  • 打赏
  • 举报
回复
真的很对不起啊,前段时间出差了,一直没有再回来看这贴子。其实这个问题到现在我还是没有解决。大概是跟DX编程有关吧。DX下很多东西都感觉怪怪的。比如说,一个简单的抓屏程序,可就是抓不到DX窗口播放的视频。好像把硬件加速什么的降低才可以抓出来。
说题扯远了,就说这个问题吧,希望各位前辈多多讨论指导!如果哪位朋友有相关的资料和书籍,也希望能在这里给出链接或查询关键字。
liuy_yy 2007-03-29
  • 打赏
  • 举报
回复
楼主 你的问题解决了么?我最近遇到了与你同样的问题 希望能向你请教下:)
QQ 397681150
MSN forever_baggio1994@hotmail.com
ly_liuyang 2007-03-29
  • 打赏
  • 举报
回复
游戏采用DirectInput技术
Keybd_Event是不行的!!
所以需要驱动级别下的IO口的键盘模拟!
zhanghao16 2007-03-17
  • 打赏
  • 举报
回复
谢谢楼上几位朋友的回复。WH_JOURNALRECORD Hook、WH_JOURNALPLAYBACK Hook我会试试的。
可是我还是很想知道我用Keybd_Event为什么就不可以模拟成功呢?道理何在?难到硬件键盘按下与这个API模拟还是不同吗?
marry2000 2007-03-16
  • 打赏
  • 举报
回复
WH_JOURNALRECORD Hook
WH_JOURNALPLAYBACK Hook
用这两种hook应该可以的
zhhf1025 2007-03-16
  • 打赏
  • 举报
回复
按键精灵为何可以做到?而模拟按键确不行?
dooing 2007-03-15
  • 打赏
  • 举报
回复
如果只是为了达到这样的功能直接用“按键精灵”就可以完成了啊。
如果是为了讨论编程那另当别论。
zhanghao16 2007-03-15
  • 打赏
  • 举报
回复
楼上两个朋友,可以给个思路吗?比如说,游戏可能是用什么开发的?怎么解决问题呢?
我在这里问这个问题,当然就是想知道原因。怎么可以随便给我推介个“按键精灵”?太不像话了。
dreamnyj 2007-03-14
  • 打赏
  • 举报
回复
游戏开发用的不是MFC也不是VCL,SO,游戏一般都是自己开发的一些东西。
所以你得找出这个游戏是如何处理键盘操作的
zhanghao16 2007-03-14
  • 打赏
  • 举报
回复
为什么没有人回我的贴子呀?真的很着急,想得到大家的帮肋。
我试过了,在游戏中可以HOOK到F1,F2按下,但就是模拟键盘不行。在游戏中用手工敲可以,用Keybd_Event模拟的就不行。

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧