C#模拟按键问题!

Byte_ 2010-11-24 09:20:44


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;

namespace DNmouse
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

#region 定义ASCII
byte Key_Ctrl = 17;//Ctrl
byte Key_V = 86;//V
byte Key_Shang = 38;//向上
byte Key_Enter = 13;//Enter
byte Key_Value = 87;//
#endregion

private string WinFromName;
private IntPtr pKeyboardHook = IntPtr.Zero;//键盘钩子句柄
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);// 钩子委托声明
//键盘钩子委托实例不能省略变量
private HookProc KeyboardHookProcedure;
static int hk = 0; //声明键盘钩子处理的初始值。
//底层键盘钩子
public const int idHook = 13;
//安装钩子
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
//卸载钩子
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
//寻找目标进程窗口
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

//设置进程窗口到最前
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//模拟键盘事件
[DllImport("User32.dll")]
public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
//释放按键的常量
private const int KEYEVENTF_KEYUP = 2;



//使用此功能,通过信息钩子继续下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
Int32 wParam, IntPtr lParam);
public event KeyEventHandler KeyDownEvent;

//键盘结构
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; //定一个虚拟键码。该代码必须有一个价值的范围1至254 。
public int scanCode; // 指定的硬件扫描码的关键。
public int flags; // 键标志
public int time; // 指定的时间戳记的这个讯息。
public int dwExtraInfo; // 指定额外信息相关的信息。
}

private const int WM_KEYDOWN = 0x100;//KEYDOWN

private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN


private void Form1_Load(object sender, EventArgs e)
{
this.CenterToScreen();
this.comboBox1.Items.Clear();//清除
Process[] processs = Process.GetProcesses();//获取所有
Process p;
try
{
for (int i = 0; i < processs.Length; i++)
{
p = processs[i];//将第i位的进程传赋值给p
this.comboBox1.Items.Add(p.ProcessName);
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
}

private void timer1_Tick(object sender, EventArgs e)
{
Process[] processs = Process.GetProcesses();//获取所有
Process p;
string proceName = comboBox1.Text;
for (int i = 0; i < processs.Length; i++)
{
p = processs[i];
if (proceName.Equals(p.ProcessName))
{
label1.Text = p.MainWindowTitle;
}
}
}

private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(comboBox1.Text))
{
MessageBox.Show("请选择进程", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (checkBox1.Checked == false)
{
label1.Text = "";
}
else if (string.IsNullOrEmpty(txt_Neirong.Text))
{
MessageBox.Show("请输入喊话内容", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{
timer1.Start();
WinFromName = label1.Text;
}
if (!string.IsNullOrEmpty(WinFromName))
{
IntPtr wc = FindWindow(null, WinFromName);
SetForegroundWindow(wc);
//this.txt_Neirong.SelectAll();
//this.txt_Neirong.Copy();
}
else
{
timer2.Stop();
MessageBox.Show("注意!找不到游戏窗口!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (checkBox2.Checked == true)
{
timer2.Interval = 4000;
timer2.Start();
}
this.Hide();
notifyIcon1.ShowBalloonTip(500, "我在汉化", "我在喊话", ToolTipIcon.Info);
}

private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
timer2.Stop();
}

private void timer2_Tick(object sender, EventArgs e)
{
//keybd_event(Key_Ctrl, 0, 0, 0);//没有KEYEVENTF_KEYUP即为长按 长按Ctrl

keybd_event(Key_V, 0, 0, 0);//按下V


keybd_event(Key_Enter, 0, 0, 0);//按下回车
keybd_event(Key_V, 0, KEYEVENTF_KEYUP, 0);//放开V
keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开回车

//Strat();

//keybd_event(Key_Shang, 0, 0, 0);//按下上
//keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开上

//keybd_event(Key_Ctrl, 0, KEYEVENTF_KEYUP, 0);//放开Ctrl 、、这个可以省略
//keybd_event(Key_Enter, 0, 0, 0);//按下回车
//keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开回车
}

private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
}
}

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
}

private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
{
timer1.Stop();
timer2.Stop();
Application.Exit();
}

//public void Strat()
//{
// if (hk == 0)
// {
// KeyboardHookProcedure = new HookProc(KeyboardHookProc);
// IntPtr pIn = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
// hk = SetWindowsHookEx(idHook, KeyboardHookProcedure, pIn, 0);
// if (hk == 0)
// {
// throw new Exception("安装键盘钩子失败");
// }
// }
//}



//private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
//{
// // 侦听键盘事件
// if ((nCode >= 0) && (KeyDownEvent != null))
// {
// KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// // raise KeyDown
// if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
// {
// Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
// KeyEventArgs e = new KeyEventArgs(keyData);
// KeyDownEvent(this, e);
// }
// IntPtr wcHandle = FindWindow(null, WinFromName);
// if (wcHandle != IntPtr.Zero)
// {
// //设置游戏窗口到最前
// SetForegroundWindow(wcHandle);
// byte VK_key = 87;
// keybd_event(VK_key, 0, 0, 0);//按下小键盘7
// }

// //如果返回1,则结束消息,这个消息到此为止,不再传递。
// //如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递,也就是传给消息真正的接受者

// }
// return CallNextHookEx(hk, nCode, wParam, lParam);
//}
}
}









主要问题是这段


private void timer2_Tick(object sender, EventArgs e)
{
//keybd_event(Key_Ctrl, 0, 0, 0);//没有KEYEVENTF_KEYUP即为长按 长按Ctrl

keybd_event(Key_V, 0, 0, 0);//按下V


keybd_event(Key_Enter, 0, 0, 0);//按下回车
keybd_event(Key_V, 0, KEYEVENTF_KEYUP, 0);//放开V
keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开回车

//Strat();

//keybd_event(Key_Shang, 0, 0, 0);//按下上
//keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开上

//keybd_event(Key_Ctrl, 0, KEYEVENTF_KEYUP, 0);//放开Ctrl 、、这个可以省略
//keybd_event(Key_Enter, 0, 0, 0);//按下回车
//keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开回车
}






为什么我代码里面写先按V之后再按下回车,我测试之后为什么程序只按下了V,回车就不按了呢?
...全文
1212 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
DreamOnTheGo 2010-12-30
  • 打赏
  • 举报
回复
QQ的 ctrl+ v不能用这样模拟的 需要 其他方法的 我上次在 csdn上看到了的你搜搜
coolszy 2010-11-25
  • 打赏
  • 举报
回复
keybd_event(Key_V, 0, 0, 0);//按下V


keybd_event(Key_Enter, 0, 0, 0);//按下回车
keybd_event(Key_V, 0, KEYEVENTF_KEYUP, 0);//放开V
keybd_event(Key_Enter, 0, KEYEVENTF_KEYUP, 0);//松开回车

每句代码之间加入Thread.Sleep(100);
ZengHD 2010-11-24
  • 打赏
  • 举报
回复
没用QQ测试过,不知道什么情况

Byte_ 2010-11-24
  • 打赏
  • 举报
回复
块来人看看啊!!!急啊!!!
Byte_ 2010-11-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zenghd 的回复:]
用记事本测试,没有问题
[/Quote]


嗯,我也测试了,记事本没有问题,但是用QQ对话框的话就不行了,为什么呢?
wolftop 2010-11-24
  • 打赏
  • 举报
回复
按键之间Sleep(500)试试
ZengHD 2010-11-24
  • 打赏
  • 举报
回复
用记事本测试,没有问题

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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