珂珂的个人博客 - 一个程序猿的个人网站

一个简单的游戏挂机工具(后台)

   以前用来魔兽挂机的,因为那时候要排队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
            }
        }
    }
}



上一篇:jUploader上传

下一篇:个人代码全部开源


0 评论

查看所有评论

给个评论吧