老话重提。
整个论坛都搜索过了有很多关于《WinKawaks》(一款街机PC模拟器程序)的模拟按键问题都没得到相应的解决。现在的问题是这样,有个a.exe进程,一个b.exe进程。
a.exe进程是WinKawaks。b.exe进程是我们自己的程序。
怎么通过自己程序的逻辑往a.exe程序发送一个按键的操作呢?比如“A”键,键值:"65"Windows API的三种方法 
PostMessage
SendMessage
keybd_event
都试过了没有用。驱动级的WinIo.dll也试过了也没有用。高手在哪啊?出来解决问题啦。

解决方案 »

  1.   

    转换下应该没有什么问题
    搜下CHAR转10进制
      

  2.   


    using System.Runtime.InteropServices;//添加引用
     [DllImport("USER32.DLL")]
            public static extern IntPtr FindWindow(string lpClassName,
                string lpWindowName);//调用FindWindow来激活窗体        [DllImport("USER32.DLL")]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
     private void button1_Click(object sender, EventArgs e)
            {
                IntPtr calculatorHandle = FindWindow(null,"计算器");
                if (calculatorHandle == IntPtr.Zero)
                {
                    MessageBox.Show("Calculator is not running.");
                    return;
                }
                try
                {
                    SetForegroundWindow(calculatorHandle);//将计算器窗口置前                SendKeys.SendWait("2"); //发送
                    Thread.Sleep(10);               
                    SendKeys.SendWait("*");
                    Thread.Sleep(10);
                    SendKeys.SendWait("3");
                    Thread.Sleep(10);
                    SendKeys.SendWait("=");
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }打开系统的计算器试试。
    由于没有激活另一个应用程序的托管方法,因此必须使用本机 Windows 方法强制将焦点放在其他应用程序上摘自MSDN
      

  3.   

    13楼的朋友,windows API我已经全部试过了。没有用额。
      

  4.   

    应为普通的win32窗体是挂接了windows消息。
    而WinKawaks是用DXInput了。直接跳过了windows消息层。
      

  5.   


    敢问一句,查MSDN了么?上面的代码测试了么?
      

  6.   

    上面代码都测试过了。
    楼上的朋友要是也非常有兴趣可以下载
    http://down.paopaoche.net:226/moni/dino.rar
    这是模拟器程序,里面自带一款游戏,模拟器可设置投币按键。
    然后你试试程序可否向这个窗体投递消息。
      

  7.   

    用DXInput做的程序是可以用SendMessage发送按键的,但是发送的消息必须是dx定义的按键扫描码,而非windows定义的按键编码。
      

  8.   

    楼上的朋友可否说详细点呢?
    我现在PostMessage 100 101 102 过去 A键值“65” 投递过去有反映,但是被WinKawaks给拦截了,弹出个信息框内容“KEY:65”。
      

  9.   

    应该是用 directInput 的
      

  10.   

    以前做网游工具的时候 ,, 有的游戏窗体屏蔽了外面的sendmessage
    假如我要从工具发送F2到游戏窗体, 游戏拦截sendmessage 不响应
    但是在游戏里按F2是可以的
    于是用OlyDbg打开,  bp send,  按下F2跟进去
    找到F2的call地址
    然后从工具里hook到游戏进程  直接call这个地址就OK了
      

  11.   

    26楼厉害。是个HOOK。我要的就是这个。问题是不会OD,不会汇编,不会跟。能帮我分析下吗?
      

  12.   

    A的directinput扫描码是0x1E,发这个试试
      

  13.   

    26楼的高手啊,
    winio都不行的话,只有26的方法了,只是不会操作啊~
    期待26楼的详细讲解~
      

  14.   

    就是这样
    call的地址就是WinKawaks响应投币action的method入口地址
    咱觉得念经比看MOV,,PUSH,之类的有意思多了
    OD的教程网上有很多的
      

  15.   

    问题已经得到解决了,推翻一下自己的结论。
    WinIo.dll是可以使用的,是我在网上找的WinIo类有错误,所以之前调试无效。
    先贴出正确的WinIo.dll封装类。再次感谢参与问题的朋友。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;namespace Client
    {
        public class WinIo
        {
            public const int KBC_KEY_CMD = 0x64;
            public const int KBC_KEY_DATA = 0x60;
            [DllImport("winio.dll")]
            public static extern bool InitializeWinIo();
            [DllImport("winio.dll")]
            public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize);
            [DllImport("winio.dll")]
            public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
            [DllImport("winio.dll")]
            public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
            [DllImport("winio.dll")]
            public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
            [DllImport("winio.dll")]
            public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
            [DllImport("winio.dll")]
            public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
            [DllImport("winio.dll")]
            public static extern void ShutdownWinIo();
            [DllImport("user32.dll")]
            public static extern int MapVirtualKey(uint Ucode, uint uMapType);
            public void sendwinio()
            {
                if (InitializeWinIo())
                {
                    KBCWait4IBE();
                }        }
            ///等待键盘缓冲区为空
            private void KBCWait4IBE()
            {
                int dwVal = 0;
                do
                {
                    bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
                }
                while ((dwVal & 0x2) > 0);
            }
            /// 模拟键盘标按下
            public void MykeyDown(int vKeyCoad)
            {
                int btScancode = 0;
                btScancode = MapVirtualKey((byte)vKeyCoad, 0);
                KBCWait4IBE(); // 等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// 发送命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)0xe2, 1);// 写入按键信息
                KBCWait4IBE(); // '等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按下键
            }
            /// 模拟键盘弹出
            public void MykeyUp(int vKeyCoad)
            {
                int btScancode = 0;
                btScancode = MapVirtualKey((byte)vKeyCoad, 0);
                KBCWait4IBE(); // '等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)0xe0, 1);// '写入按键信息
                KBCWait4IBE(); // '等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送写入命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入释放键
            }
            /// 模拟鼠标按下
            public void MyMouseDown(int vKeyCoad)
            {
                int btScancode = 0;
                btScancode = MapVirtualKey((byte)vKeyCoad, 0);
                KBCWait4IBE(); // '等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1);// '发送写入命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);// '写入信息按下键
            }
            /// 模拟鼠标弹出
            public void MyMouseUp(int vKeyCoad)
            {
                int btScancode = 0;
                btScancode = MapVirtualKey((byte)vKeyCoad, 0);
                KBCWait4IBE(); // '等待键盘缓冲区为空
                SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1); //'发送写入命令
                KBCWait4IBE();
                SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);// '写入信息释放键
            }
      

  16.   


            //----------------------------------------------------------------------------------------------------------------------------
            //下面为动作代码,请自行添加
            //----------------------------------------------------------------------------------------------------------------------------
            public enum Key
            {
                //      鼠标动代码:
                move = 0x0001,
                leftdown = 0x0002,
                leftup = 0x0004,
                rightdown = 0x0008,
                rightup = 0x0010,
                middledown = 0x0020,
                //键盘动作代码:
                VK_LBUTTON = 1,      //鼠标左键 
                VK_RBUTTON = 2,     //鼠标右键 
                VK_CANCEL = 3,    //Ctrl+Break(通常不需要处理) 
                VK_MBUTTON = 4,    //鼠标中键 
                VK_BACK = 8,      //Backspace 
                VK_TAB = 9,      //Tab 
                VK_CLEAR = 12,    //Num Lock关闭时的数字键盘5 
                VK_RETURN = 13,   //Enter(或者另一个) 
                VK_SHIFT = 16,    //Shift(或者另一个) 
                VK_CONTROL = 17,   //Ctrl(或者另一个) 
                VK_MENU = 18,    //Alt(或者另一个) 
                VK_PAUSE = 19,    //Pause 
                VK_CAPITAL = 20,   //Caps Lock 
                VK_ESCAPE = 27,   //Esc 
                VK_SPACE = 32,    //Spacebar 
                VK_PRIOR = 33,    //Page Up 
                VK_NEXT = 34,    //Page Down 
                VK_END = 35,     //End 
                VK_HOME = 36,    //Home 
                VK_LEFT = 37,     //左箭头 
                VK_UP = 38,      //上箭头 
                VK_RIGHT = 39,    //右箭头 
                VK_DOWN = 40,     //下箭头 
                VK_SELECT = 41,    //可选 
                VK_PRINT = 42,    //可选 
                VK_EXECUTE = 43,   //可选 
                VK_SNAPSHOT = 44,  //Print Screen 
                VK_INSERT = 45,   //Insert 
                VK_DELETE = 46,    //Delete 
                VK_HELP = 47,      //可选 
                VK_NUM0 = 48,        //0
                VK_NUM1 = 49,        //1
                VK_NUM2 = 50,        //2
                VK_NUM3 = 51,        //3
                VK_NUM4 = 52,        //4
                VK_NUM5 = 53,        //5
                VK_NUM6 = 54,        //6
                VK_NUM7 = 55,        //7
                VK_NUM8 = 56,        //8
                VK_NUM9 = 57,        //9
                VK_A = 65,          //A
                VK_B = 66,          //B
                VK_C = 67,          //C
                VK_D = 68,          //D
                VK_E = 69,          //E
                VK_F = 70,          //F
                VK_G = 71,          //G
                VK_H = 72,          //H
                VK_I = 73,          //I
                VK_J = 74,          //J
                VK_K = 75,          //K
                VK_L = 76,          //L
                VK_M = 77,          //M
                VK_N = 78,          //N
                VK_O = 79,          //O
                VK_P = 80,          //P
                VK_Q = 81,          //Q
                VK_R = 82,          //R
                VK_S = 83,          //S
                VK_T = 84,          //T
                VK_U = 85,          //U
                VK_V = 86,          //V
                VK_W = 87,          //W
                VK_X = 88,          //X
                VK_Y = 89,          //Y
                VK_Z = 90,          //Z
                VK_NUMPAD0 = 96,    //0
                VK_NUMPAD1 = 97,    //1
                VK_NUMPAD2 = 98,    //2
                VK_NUMPAD3 = 99,    //3
                VK_NUMPAD4 = 100,    //4
                VK_NUMPAD5 = 101,    //5
                VK_NUMPAD6 = 102,    //6
                VK_NUMPAD7 = 103,    //7
                VK_NUMPAD8 = 104,    //8
                VK_NUMPAD9 = 105,    //9
                VK_NULTIPLY = 106,  //数字键盘上的* 
                VK_ADD = 107,    //数字键盘上的+ 
                VK_SEPARATOR = 108, //可选 
                VK_SUBTRACT = 109,  //数字键盘上的- 
                VK_DECIMAL = 110,  //数字键盘上的. 
                VK_DIVIDE = 111,   //数字键盘上的/
                VK_F1 = 112,
                VK_F2 = 113,
                VK_F3 = 114,
                VK_F4 = 115,
                VK_F5 = 116,
                VK_F6 = 117,
                VK_F7 = 118,
                VK_F8 = 119,
                VK_F9 = 120,
                VK_F10 = 121,
                VK_F11 = 122,
                VK_F12 = 123,
                VK_NUMLOCK = 144,  //Num Lock 
                VK_SCROLL = 145,    // Scroll Lock 
                middleup = 0x0040,
                xdown = 0x0080,
                xup = 0x0100,
                wheel = 0x0800,
                virtualdesk = 0x4000,
                absolute = 0x8000
            }
        }
    }
      

  17.   

    ,怎么用呢? 激活目标窗体然后直接调用WinIo里的方法么?