以前用来魔兽挂机的,因为那时候要排队2个小时,上了就不想下,其实就是简单的每隔一段时间跳跃一下,这样不至于太久不动被服务器T掉。不知道按键精灵怎么后台,就是魔兽不是当前窗口也可以操作。原理就是找到魔兽窗口句柄向它发送空格消息
xaml代码
<Window x:Class="WOW.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="魔兽世界挂机工具" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="100"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="200"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <StackPanel Grid.Column="1" Grid.Row="1"> <WrapPanel> <TextBlock Text="魔兽世界句柄:" Width="80"></TextBlock> <TextBox IsEnabled="False" Width="50" x:Name="txtHandler"></TextBox> </WrapPanel> <WrapPanel Margin="0,10,0,0"> <TextBlock Text="时间间隔(s):" Width="80"></TextBlock> <TextBox Text="30" Width="50" x:Name="txtInterval"></TextBox> </WrapPanel> <WrapPanel Margin="0,10,0,0"> <Button Content="启动(F10)" x:Name="btnSubmit" Click="btnSubmit_Click"></Button> </WrapPanel> </StackPanel> </Grid> </Window>
后台代码
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WOW { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } [DllImport("user32.dll")] private static extern bool IsWindowVisible(int hWnd); [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); //设置由不同线程产生的窗口的显示状态 [DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd); //是否最小化 [DllImport("user32.dll")] private static extern bool IsZoomed(IntPtr hWnd); //是否最大化 [DllImport("user32.dll")] private static extern IntPtr SetActiveWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); [DllImport("user32.dll")] private static extern bool SetCursorPos(int X, int Y); [DllImport("user32.dll")] private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo); [DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll")] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags); //ShowWindow参数 private const int SW_HIDE = 0; private const int SW_SHOWNORMAL = 1; private const int SW_SHOWMINIMIZED = 2; private const int SW_SHOWMAXIMIZED = 3; private const int SW_SHOWNOACTIVATE = 4; private const int SW_RESTORE = 9; private const int SW_SHOWDEFAULT = 10; //SendMessage参数 private const int WM_KEYDOWN = 0X100; private const int WM_KEYUP = 0X101; private const int WM_SYSCHAR = 0X106; private const int WM_SYSKEYUP = 0X105; private const int WM_SYSKEYDOWN = 0X104; private const int WM_CHAR = 0X102; #region 遍历所有窗口得到句柄 //定义委托方法CallBack,枚举窗口API(EnumWindows),得到窗口名API(GetWindowTextW)和得到窗口类名API(GetClassNameW) public delegate bool CallBack(int hwnd, int lParam); [DllImport("user32")] public static extern int EnumWindows(CallBack x, int y); [DllImport("user32.dll")] private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")] private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); public bool Recall(int hwnd, int lParam) { StringBuilder sb = new StringBuilder(256); IntPtr PW = new IntPtr(hwnd); GetWindowTextW(PW, sb, sb.Capacity); //得到窗口名并保存在strName中 string strName = sb.ToString(); GetClassNameW(PW, sb, sb.Capacity); //得到窗口类名并保存在strClass中 string strClass = sb.ToString(); // this.listBox1.Items.Add(strName + " " + strClass); if (strName.IndexOf("窗口名关键字") >= 0 && strClass.IndexOf("类名关键字") >= 0) { return false; //返回false中止EnumWindows遍历 } else { return true; //返回true继续EnumWindows遍历 } } #endregion /// <summary> /// 发送一个字符串 /// </summary> /// <param name="myIntPtr">窗口句柄</param> /// <param name="Input">字符串</param> public void InputStr(IntPtr myIntPtr, string Input) { byte[] ch = (ASCIIEncoding.ASCII.GetBytes(Input)); for (int i = 0; i < ch.Length; i++) { SendMessage(myIntPtr, WM_SYSKEYDOWN, Convert.ToInt32(ch[i]), 0); SendMessage(myIntPtr, WM_SYSKEYUP, Convert.ToInt32(ch[i]), 0); // SendMessage(PW, WM_CHAR, ch, 0); } } // 利用鼠标和键盘模拟向窗口发送数据 //SetWindowPos(PW, (IntPtr)(-1), 0, 0, 0, 0, 0x0040 | 0x0001); //设置窗口位置 //SetCursorPos(476, 177); //设置鼠标位置 //mouse_event(0x0002, 0, 0, 0, 0); //模拟鼠标按下操作 //mouse_event(0x0004, 0, 0, 0, 0); //模拟鼠标放开操作 //SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X20, 0); //输入空格(0x20) //SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X09, 0); //输入TAB(0x09) //SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X0D, 0); //输入ENTER(0x0d) //向魔兽世界发送空格 private void SendWowSpace() { while (true) { IntPtr myIntPtr = FindWindow(null, "魔兽世界"); //null为类名,可以用Spy++得到,也可以为空 // ShowWindow(myIntPtr, SW_RESTORE); //将窗口还原 // SetForegroundWindow(myIntPtr); //如果没有ShowWindow,此方法不能设置最小化的窗口 if (myIntPtr != null) { SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X20, 0); //输入空格(0x20) SendMessage(myIntPtr, WM_SYSKEYUP, 0X20, 0); } Thread.Sleep(Convert.ToInt32(this.txtInterval.Text) * 1000); } } Thread th = null; private void btnSubmit_Click(object sender, RoutedEventArgs e) { if (this.btnSubmit.Tag == null) { th = new Thread(new ThreadStart(SendWowSpace)); th.Start(); this.btnSubmit.Content = "停止(F12)"; this.btnSubmit.Tag = 1; //遍历所有窗口得到句柄 //CallBack myCallBack = new CallBack(Recall); //EnumWindows(myCallBack, 0); //打开窗口 // Process proc = Process.Start(@"目标程序路径"); //SetActiveWindow(proc.MainWindowHandle); // SetForegroundWindow(proc.MainWindowHandle); //打开窗口 //Process proc = Process.Start(@"e:\\魔兽世界\\WOW.exe"); // proc.Start(); 与下面句等同效果? //SetActiveWindow(proc.MainWindowHandle); } else { #region 停止 try { this.btnSubmit.Content = "启动(F10)"; this.btnSubmit.Tag = null; th.Abort(); } catch { } #endregion } } } }