xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<Button Width="100" Margin="30" Click="Button_Click">应用</Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Window x:Class="Carl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="卡尔一键释放技能-linger" Height="700" Width="525"
Loaded="Window_Loaded"
Left="100"
Top="30"
Icon="icon.ico"
Deactivated="Window_Deactivated"
>
<Window.Background>
<ImageBrush ImageSource="carl.jpg" />
</Window.Background>
<ScrollViewer>
<StackPanel >
<Button Width="100" Margin="30" Click="Button_Click">应用</Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Margin="0,0,50,0"
Foreground="Red"
FontSize="15">
按键</TextBlock>
<TextBlock
Foreground="Red"
FontSize="15">技能</TextBlock>
</StackPanel>
<StackPanel Name="main">
<!--
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox Width="50" Height="20" MaxLength="1" Margin="20">
</TextBox>
<ComboBox Name="cb" Width="100" Height="20">
<ComboBoxItem>急速冷却</ComboBoxItem>
<ComboBoxItem>浑沌陨石</ComboBoxItem>
<ComboBoxItem>超震声波</ComboBoxItem>
<ComboBoxItem>强袭飓风</ComboBoxItem>
<ComboBoxItem>熔炉精灵</ComboBoxItem>
<ComboBoxItem>冰墙</ComboBoxItem>
<ComboBoxItem>电磁脉冲</ComboBoxItem>
<ComboBoxItem>幽灵漫步</ComboBoxItem>
<ComboBoxItem>阳炎冲击</ComboBoxItem>
<ComboBoxItem>灵动迅捷</ComboBoxItem>
</ComboBox>
</StackPanel>-->
</StackPanel>
</StackPanel>
</ScrollViewer>
</Window>
c#:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading;
namespace Carl
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
//using System.Runtime.InteropServices;记得添加
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
//安装钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, ref KeyboardHookStruct lParam);
//卸载钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
public delegate int HookProc(int nCode, Int32 wParam,ref KeyboardHookStruct lParam);
HookProc KeyboardHookProcedure;
public const int WH_KEYBOARD_LL = 13;
const int WM_CHAR = 0x102;
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
IntPtr npWnd, childWnd;
static int hKeyboardHook = 0;
[StructLayout(LayoutKind.Sequential)]
public struct KeyboardHookStruct
{
public int vkCode;//表示一个1到254间的虚拟键盘码
public int scanCode;//表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;
}
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 10;i++ )
addNew();
ht = new Hashtable();
init(0, "1", "急速冷却");
init(1, "2", "浑沌陨石");
init(2, "3", "超震声波");
init(3, "4", "强袭飓风");
init(4, "5", "熔炉精灵");
init(5, "6", "冰墙");
init(6, "7", "电磁脉冲");
init(7, "8", "幽灵漫步");
init(8, "9", "阳炎冲击");
init(9, "0", "灵动迅捷");
}
void updateKeyValue()
{
ColdSnap = (char)(ht["急速冷却"].ToString().ToCharArray())[0];
ChaosMeteor = toVcode("浑沌陨石");
DefeaningBlast = toVcode("超震声波");
Tornado = toVcode("强袭飓风");
ForgedSpirit = toVcode("熔炉精灵");
IceWall = toVcode("冰墙");
EMP = toVcode("电磁脉冲");
GhostWalk = toVcode("幽灵漫步");
SunStrike = toVcode("阳炎冲击");
Alacrity = toVcode("灵动迅捷");
}
char toVcode(string str)
{
char ch = (char)(ht[str].ToString().ToCharArray())[0];
//小写还要转成大写
if(ch >= 'a' && ch <='z')
ch = (char)(ch - 'a' +'A');
return ch;
}
void init(int index,string key,string tec)
{
StackPanel sp = (StackPanel)main.Children[index];
ComboBox cbb = (ComboBox)sp.Children[1];
TextBox tbb = (TextBox)sp.Children[0];
tbb.Text = key;
cbb.SelectedValue = tec;
ht.Add((cbb.SelectedItem).ToString(),tbb.Text);
}
void addNew()
{
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
sp.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
TextBox tb = new TextBox();
tb.Width = 50;
tb.Height = 20;
tb.Margin = new Thickness(20);
tb.MaxLength = 1;
sp.Children.Add(tb);
ComboBox cb2 = new ComboBox();
cb2.Width = 100;
cb2.Height = 20;
//原来下面添加的字符串不是ComboxItem
cb2.Items.Add("急速冷却");
cb2.Items.Add("浑沌陨石");
cb2.Items.Add("超震声波");
cb2.Items.Add("强袭飓风");
cb2.Items.Add("熔炉精灵");
cb2.Items.Add("冰墙");
cb2.Items.Add("电磁脉冲");
cb2.Items.Add("幽灵漫步");
cb2.Items.Add("阳炎冲击");
cb2.Items.Add("灵动迅捷");
sp.Children.Add(cb2);
main.Children.Add(sp);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//npWnd = FindWindow("notepad", null);//刚开始用记事本作为测试
// if (npWnd == IntPtr.Zero)
// {
// MessageBox.Show("找不到窗口");
// return;
//}
// childWnd = FindWindowEx(npWnd, IntPtr.Zero, "Edit", null);
childWnd = FindWindow(null, "Warcraft III");
if (childWnd == IntPtr.Zero)
{
MessageBox.Show("魔兽3未启动,设置失败");
return;
}
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess())
using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule)
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
}
//冰 Q 雷W 火E
//急速冷却 (Y) 技能组合:QQQ+R ColdSnap = 1
// 浑沌陨石 (D) 技能组合:EEW+R ChaosMeteor =2
//超震声波 (B) 技能组合:QWE+R DefeaningBlast =3
//强袭飓风 (X) 技能组合:WWQ+R Tornado =4
//熔炉精灵 (F) 技能组合:EEQ+R ForgedSpirit =5
//冰墙 (G) 技能组合:QQE+R IceWall =6
//电磁脉冲 (C) 技能组合:WWW+R EMP =7
//幽灵漫步 (V) 技能组合:QQW+R GhostWalk =8
//阳炎冲击 (T) 技能组合:EEE+R SunStrike =9
//灵动迅捷 (Z) 技能组合:WWE+R Alacrity = 0
Hashtable ht = new Hashtable();
//用户输入决定哪个键对应哪个技能,比如用户 "急速冷却" 对应于 i键
//则令 ColdSnap等于 ht["急速冷却"] = i的虚拟码
//以下是默认值
int ColdSnap = '1';
int ChaosMeteor = '2';
int DefeaningBlast = '3';
int Tornado = '4';
int ForgedSpirit = '5';
int IceWall = '6';
int EMP = '7';
int GhostWalk = '8';
int SunStrike = '9';
int Alacrity = '0';
void RunAlacrity()
{ //WWE+R Z
Run('W', 'W', 'E', 'R', 'Z');
}
void RunSunStrike()
{ //EEE+R T
Run('E', 'E', 'E', 'R', 'T');
}
void RunGhostWalk()
{ //QQW+R V
Run('Q', 'Q', 'W', 'R', 'V');
}
void RunEMP()
{ //WWW+R C
Run('W', 'W', 'W', 'R', 'C');
}
void RunIceWall()
{ //QQE+R G
Run('Q', 'Q', 'E', 'R', 'G');
}
void RunForgedSpirit()
{ //EEQ+R F
Run('E', 'E', 'Q', 'R', 'F');
}
void RunTornado()
{//WWQ+R X
Run('W', 'W', 'Q', 'R', 'X');
}
void RunDefeaningBlast()
{ //QWE+R B
Run('Q', 'W', 'E', 'R', 'B');
}
void RunChaosMeteor()
{//EEW+R
Run('E','E','W','R','D');
}
void RunColdSnap()
{
SendMessage(childWnd, WM_KEYDOWN, 'Q', 0);
SendMessage(childWnd, WM_KEYUP, 'Q', 0);
SendMessage(childWnd, WM_KEYDOWN, 'Q', 0);
SendMessage(childWnd, WM_KEYUP, 'Q', 0);
SendMessage(childWnd, WM_KEYDOWN, 'Q', 0);
SendMessage(childWnd, WM_KEYUP, 'Q', 0);
SendMessage(childWnd, WM_KEYDOWN, 'R', 0);
SendMessage(childWnd, WM_KEYUP, 'R', 0);
Thread.Sleep(300);
SendMessage(childWnd, WM_KEYDOWN, 'Y', 0);
SendMessage(childWnd, WM_KEYUP, 'Y', 0);
/*
SendMessage(childWnd, WM_CHAR, 'Q', 0);
SendMessage(childWnd, WM_CHAR, 'Q', 0);
SendMessage(childWnd, WM_CHAR, 'Q', 0);
SendMessage(childWnd, WM_CHAR, 'R', 0);
SendMessage(childWnd, WM_CHAR, 'Y', 0);*/
}
void Run(int a, int b, int c, int d, int e)
{
SendMessage(childWnd, WM_KEYDOWN, a, 0);
SendMessage(childWnd, WM_KEYUP, a, 0);
SendMessage(childWnd, WM_KEYDOWN, b, 0);
SendMessage(childWnd, WM_KEYUP, b, 0);
SendMessage(childWnd, WM_KEYDOWN, c, 0);
SendMessage(childWnd, WM_KEYUP, c, 0);
SendMessage(childWnd, WM_KEYDOWN, d, 0);
SendMessage(childWnd, WM_KEYUP, d, 0);
Thread.Sleep(300);
SendMessage(childWnd, WM_KEYDOWN, e, 0);
SendMessage(childWnd, WM_KEYUP, e, 0);
}
private int KeyboardHookProc(int nCode, Int32 wParam, ref KeyboardHookStruct lParam)
{
// MessageBox.Show("截获到消息");
// if (wParam == WM_KEYDOWN)
// MessageBox.Show(lParam.vkCode.ToString());
//为何我这里验证-号的虚拟码是189呢,算了不用这个了
if (wParam == WM_KEYDOWN &&enable)//可以识别小a了
{
if (lParam.vkCode == ColdSnap)
{
RunColdSnap();
}
else if (lParam.vkCode == ChaosMeteor)
{
RunChaosMeteor();
}
else if (DefeaningBlast == lParam.vkCode)
RunDefeaningBlast();
else if (Tornado == lParam.vkCode)
RunTornado();
else if (ForgedSpirit == lParam.vkCode)
RunForgedSpirit();
else if (IceWall == lParam.vkCode)
RunIceWall();
else if (EMP == lParam.vkCode)
RunEMP();
else if (GhostWalk == lParam.vkCode)
RunGhostWalk();
else if (SunStrike == lParam.vkCode)
RunSunStrike();
else if (Alacrity == lParam.vkCode)
RunAlacrity();
else
return CallNextHookEx(hKeyboardHook, nCode, wParam, ref lParam);
return 1;
//根据返回值的范围决定是否继续传播
//以下方法是可行的
//返回1阻止消息继续传播
//返回0消息继续传播
}
//交给下一个钩子处理消息
return CallNextHookEx(hKeyboardHook, nCode, wParam,ref lParam);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
childWnd = FindWindow(null, "Warcraft III");
if (childWnd == IntPtr.Zero)
{
MessageBox.Show("魔兽3未启动,设置失败");
return;
}
ht.Clear();
foreach(StackPanel sp in main.Children)
{
ComboBox cbb = (ComboBox)sp.Children[1];
TextBox tbb = (TextBox)sp.Children[0];
if (null != cbb.SelectedItem && tbb.Text != null)
{
// ht.Add(tbb.Text, (cbb.SelectedItem).ToString());
ht.Add((cbb.SelectedItem).ToString(), tbb.Text);
// MessageBox.Show(tbb.Text + ((ComboBoxItem)cbb.SelectedItem).ToString());
//MessageBox.Show( (cbb.SelectedItem).ToString());
}
}
updateKeyValue();
}
bool enable = false;//因为是系统钩子,所以避免挂钩本程序的按键
private void Window_Deactivated(object sender, EventArgs e)
{
enable = true;//失去焦点时再起效
}
}
}