C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)相关的知识,希望对你有一定的参考价值。

当我最小化winform窗口时,我想接受记事本或文本编辑器输入的数据!
当winform或其控件失去焦点时,winform中的textbox能接收到键盘输入的数据

全局键盘钩子,如下,你再把键盘钩子的数据弄到textbox就可以了。
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections.Generic;
namespace HookGlobal

/// <summary>
/// 这个类可以让你得到一个在运行中程序的所有键盘事件
/// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息
/// </summary>
/// <remarks>
/// 修改:lihx
/// 修改时间:04.11.8
/// </remarks>
public class KeyBordHook

private const int WM_KEYDOWN = 0x100;
private const int WM_KEYUP = 0x101;
private const int WM_SYSKEYDOWN = 0x104;
private const int WM_SYSKEYUP = 0x105;
//全局的事件
public event KeyEventHandler OnKeyDownEvent;
public event KeyEventHandler OnKeyUpEvent;
public event KeyPressEventHandler OnKeyPressEvent;
static int hKeyboardHook = 0; //键盘钩子句柄
//鼠标常量
public const int WH_KEYBOARD_LL = 13; //keyboard hook constant
HookProc KeyboardHookProcedure; //声明键盘钩子事件类型.
//声明键盘钩子的封送结构类型
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct

public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;

//装置钩子的函数
[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 bool UnhookWindowsHookEx(int idHook);
//下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
[DllImport("user32")]
public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
//先前按下的键
public List<Keys> preKeys = new List<Keys>();
/// <summary>
/// 墨认的构造函数构造当前类的实例并自动的运行起来.
/// </summary>
public KeyBordHook()

Start();

//析构函数.
~KeyBordHook()

Stop();

public void Start()

//安装键盘钩子
if (hKeyboardHook == 0)

KeyboardHookProcedure = new HookProc(KeyboardHookProc);
//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
Process curProcess = Process.GetCurrentProcess();
ProcessModule curModule = curProcess.MainModule;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
if (hKeyboardHook == 0)

Stop();
throw new Exception("SetWindowsHookEx ist failed.");



public void Stop()

bool retKeyboard = true;
if (hKeyboardHook != 0)

retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;

//如果卸下钩子失败
if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");

private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)

if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))

KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
//当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
//中的对应的键增加
if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)

preKeys.Add(keyData);


//引发OnKeyDownEvent
if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
OnKeyDownEvent(this, e);

//引发OnKeyPressEvent
if (OnKeyPressEvent != null && wParam == WM_KEYDOWN)

byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode,
MyKeyboardHookStruct.scanCode,
keyState,
inBuffer,
MyKeyboardHookStruct.flags) == 1)

KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
OnKeyPressEvent(this, e);


//当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
//中的对应的键删除
if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (IsCtrlAltShiftKeys(keyData))

for (int i = preKeys.Count - 1; i >= 0; i--)

if (preKeys[i] == keyData)

preKeys.RemoveAt(i);




//引发OnKeyUpEvent
if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
OnKeyUpEvent(this, e);


return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);


private Keys GetDownKeys(Keys key)

Keys rtnKey = Keys.None;
foreach (Keys keyTemp in preKeys)

switch (keyTemp)

case Keys.LControlKey:
case Keys.RControlKey:
rtnKey = rtnKey | Keys.Control;
break;
case Keys.LMenu:
case Keys.RMenu:
rtnKey = rtnKey | Keys.Alt;
break;
case Keys.LShiftKey:
case Keys.RShiftKey:
rtnKey = rtnKey | Keys.Shift;
break;
default:
break;


rtnKey = rtnKey | key;
return rtnKey;

private Boolean IsCtrlAltShiftKeys(Keys key)

switch (key)

case Keys.LControlKey:
case Keys.RControlKey:
case Keys.LMenu:
case Keys.RMenu:
case Keys.LShiftKey:
case Keys.RShiftKey:
return true;
default:
return false;



参考技术A 失去焦点的控件添加一个Validated事件
事件里面写 txtbox1.Focus()
至于获取另一个窗口的数据
首先两个窗口同个命名空间
某窗口被获取的数据用public修饰(如public int a=0)
另外一个就可以通过 form1.a
这个是我想的 - - 没有测试过 自己试试
参考技术B C# 全局键盘钩子. 参考技术C 能不能说的再明白点... 有图吗 参考技术D 关键词:HOOK

C#窗体及控件的快捷键 设置

1.怎样设置一个控件的快捷键(只按一个字母实现;及如何选择伴随shift,ctrl,alt实现)?
2.怎样设置整个窗体快捷键(不论焦点在哪,随时呼出。像F1)?
3.Accesskey属性在那里,说是可以在这个属性里直接键入快捷键就行?!

初学,解答麻烦详细,3Q
问题 "2.怎样设置整个窗体快捷键(不论焦点在哪,随时呼出。像F1)? " 的补充:

不是要呼出窗体,还是针对(执行)某一控件的功能。
旨在不限焦点!

一、常规键盘快捷键
按键 目的
Ctrl + A 全选
Ctrl + B 整理收藏夹
Ctrl + C 复制
Ctrl + D 删除/添加收藏
Ctrl + E 搜索助理
Ctrl + F 查找
Ctrl + H 历史记录
Ctrl + I 收藏夹
Ctrl + J IE7.0里的源
Ctrl + L =Ctrl+O 打开
Ctrl + M 网页搜索框中的确定(等于回车)
Ctrl + N 新窗口
Ctrl + P 打印
Ctrl + R 刷新
Ctrl + S 保存
Ctrl+T IE7.0打开新选项卡
Ctrl + V 粘贴
Ctrl + W 关闭当前窗口
Ctrl + X 剪切
Ctrl + Z 撤消
F1 帮助
F2 重命名
F3 搜索
F4 地址栏
F5 刷新
F6 切换元素
F7 DoS下专用功能
F8 Windows 启动选项
F9 Excel 中计算公式
F10 激活菜单栏
F11 切换全屏
F12 Word 里另存文档
Windows键 打开开始菜单
Windows键+D 显示桌面
Windows键+E 打开资源管理器
Windows键+F 查找所有文件
Windows键+L 切换用户
Windows键+M 最小化所有窗口
Windows键+R 运行命令
Windows键+U 辅助工具
DELETE 删除。
Shift + Delete 永久删除所选项,而不将它放到“回收站”中。
拖动某一项时按 CTRL 复制所选项。
拖动某一项时按 CTRL + SHIFT 创建所选项目的快捷键。
F2 重新命名所选项目。
CTRL + 向右方向键 将插入点移动到下一个单词的起始处。
CTRL + 向左方向键 将插入点移动到前一个单词的起始处。
CTRL + 向下方向键 将插入点移动到下一段落的起始处。
CTRL + 向上方向键 将插入点移动到前一段落的起始处。
CTRL + SHIFT + 方向键 突出显示一块文本。
SHIFT + 方向键 在窗口或桌面上选择多项,或者选中文档中的文本。
Ctrl + A 选中全部内容。
F3 搜索文件或文件夹。
Alt + Enter 查看所选项目的属性。/切换全屏
Alt + F4 关闭当前项目或者关闭计算机
Alt + 空格键 为当前窗口打开快捷菜单。
Ctrl + F4 在允许同时打开多个文档的程序中关闭当前文档。
Alt + Tab 在打开的项目之间切换。
Alt + Esc 以项目打开的顺序循环切换。
F6 在窗口或桌面上循环切换屏幕元素。
F4 显示“我的电脑”和“Windows 资源管理器”中的“地址”栏列表。
Shift + F10 显示所选项的快捷菜单。
Alt + 空格键 显示当前窗口的“系统”菜单。
Ctrl + Esc 显示“开始”菜单。
ALT + 菜单名中带下划线的字母 显示相应的菜单。
在打开的菜单上显示的命令名称中带有下划线的字母 执行相应的命令。
F10 激活当前程序中的菜单条。
右方向键 打开右边的下一菜单或者打开子菜单。
左方向键 打开左边的下一菜单或者关闭子菜单。
F5 刷新当前窗口。
BackSpace 在“我的电脑”或“Windows 资源管理器”中查看上一层文件夹。
Esc 取消当前任务。
将光盘插入到 CD-ROM 驱动器时按 SHIFT 键 阻止光盘自动播放。
二、对话框快捷键
按键 目的
Ctrl + Tab 在选项卡之间向前移动。
Ctrl + Shift +Tab 在选项卡之间向后移动。
Tab 在选项之间向前移动。
Shift + Tab 在选项之间向后移动。
ALT + 带下划线的字母 执行相应的命令或选中相应的选项。
Enter 执行活选项动或按钮所对应的命令。
空格键 如果活选项动是复选框,则选中或清除该复选框并在文档初始位置增加一个空格。
方向键 活选项动是一组选项按钮时,请选中某个按钮。
F1 显示帮助。
F4 显示当前列表中的项目。
BackSpace 如果在“另存为”或“打开”对话框中选中了某个文件夹,则打开上一级文件夹。
三、自然键盘快捷键
在“Microsoft 自然键盘”或包含 Windows 徽标键(简称WIN) 和“应用程序”键(简称KEY) 的其他兼容键盘中,您可以使用以下快捷键。
按键 目的
WIN 显示或隐藏"开始"菜单。
WIN+ BREAK 显示"系统属性"对话框。
WIN+ D 显示桌面。
WIN+ M 最小化所有窗口。
WIN+ Shift + M 还原最小化的窗口。
WIN+ E 打开"我的电脑"。
WIN+ F 搜索文件或文件夹。
CTRL+WIN+ F 搜索计算机。
WIN+ F1 显示 Windows 帮助。
WIN+ L 如果连接到网络域,则锁定您的计算机,或者如果没有连接到网络域,则切换用户。
WIN+ R 打开"运行"对话框。
KEY 显示所选项的快捷菜单。
WIN+ U 打开"工具管理器"。
四、辅助键盘快捷键
按键 目的
右侧 SHIFT 键八秒钟 切换“筛选键”的开和关。
左边的 ALT + 左边的 SHIFT + PRINT SCREEN 切换“高对比度”的开和关。
左边的 ALT + 左边的 SHIFT + NUM LOCK 切换“鼠标键”的开和关。
Shift 键五次 切换“粘滞键”的开和关。
Num Lock 键五秒钟 切换“切换键”的开和关。
WIN+ U 打开“工具管理器”。
“Windows 资源管理器”键盘快捷键
按键 目的
END 显示当前窗口的底端。
主页 显示当前窗口的顶端。
NUM LOCK + 数字键盘的星号 (*) 显示所选文件夹的所有子文件夹。
NUM LOCK + 数字键盘的加号 (+) 显示所选文件夹的内容。
NUM LOCK + 数字键盘的减号 (-) 折叠所选的文件夹。
左方向键 当前所选项处于展开状态时折叠该项,或选定其父文件夹。
右方向键 当前所选项处于折叠状态时展开该项,或选定第一个子文件夹
还有一些常用软件的快捷键 如 photoshop的
工具箱(多种工具共用一个快捷键的可同时按【Shift】加此快捷键选取)
矩形、椭圆选框工具 【M】
裁剪工具 【C】
移动工具 【V】
套索、多边形套索、磁性套索 【L】
魔棒工具 【W】
喷枪工具 【J】
画笔工具 【B】
像皮图章、图案图章 【S】
历史记录画笔工具 【Y】
像皮擦工具 【E】
铅笔、直线工具 【N】
模糊、锐化、涂抹工具 【R】
减淡、加深、海棉工具 【O】
钢笔、自由钢笔、磁性钢笔 【P】
添加锚点工具 【+】
删除锚点工具 【-】
直接选取工具 【A】
文字、文字蒙板、直排文字、直排文字蒙板 【T】
度量工具 【U】
直线渐变、径向渐变、对称渐变、角度渐变、菱形渐变 【G】
油漆桶工具 【K】
吸管、颜色取样器 【I】
抓手工具 【H】
缩放工具 【Z】
默认前景色和背景色 【D】
切换前景色和背景色 【X】
切换标准模式和快速蒙板模式 【Q】
标准屏幕模式、带有菜单栏的全屏模式、全屏模式 【F】
临时使用移动工具 【Ctrl】
临时使用吸色工具 【Alt】
临时使用抓手工具 【空格】
打开工具选项面板 【Enter】
快速输入工具选项(当前工具选项面板中至少有一个可调节数字) 【0】至【9】
循环选择画笔 【[】或【]】
选择第一个画笔 【Shift】+【[】
选择最后一个画笔 【Shift】+【]】
建立新渐变(在”渐变编辑器”中) 【Ctrl】+【N】
文件操作
新建图形文件 【Ctrl】+【N】
用默认设置创建新文件 【Ctrl】+【Alt】+【N】
打开已有的图像 【Ctrl】+【O】
打开为... 【Ctrl】+【Alt】+【O】
关闭当前图像 【Ctrl】+【W】
保存当前图像 【Ctrl】+【S】
另存为... 【Ctrl】+【Shift】+【S】
存储副本 【Ctrl】+【Alt】+【S】
页面设置 【Ctrl】+【Shift】+【P】
打印 【Ctrl】+【P】
旋转画布【Ctrl】+【T】
打开“预置”对话框 【Ctrl】+【K】
显示最后一次显示的“预置”对话框 【Alt】+【Ctrl】+【K】
设置“常规”选项(在预置对话框中) 【Ctrl】+【1】
设置“存储文件”(在预置对话框中) 【Ctrl】+【2】
设置“显示和光标”(在预置对话框中) 【Ctrl】+【3】
设置“透明区域与色域”(在预置对话框中) 【Ctrl】+【4】
设置“单位与标尺”(在预置对话框中) 【Ctrl】+【5】
设置“参考线与网格”(在预置对话框中) 【Ctrl】+【6】
设置“增效工具与暂存盘”(在预置对话框中) 【Ctrl】+【7】
设置“内存与图像高速缓存”(在预置对话框中) 【Ctrl】+【8】
编辑操作
还原/重做前一步操作 【Ctrl】+【Z】
还原两步以上操作 【Ctrl】+【Alt】+【Z】
重做两步以上操作 【Ctrl】+【Shift】+【Z】
剪切选取的图像或路径 【Ctrl】+【X】或【F2】
拷贝选取的图像或路径 【Ctrl】+【C】
合并拷贝 【Ctrl】+【Shift】+【C】
将剪贴板的内容粘到当前图形中 【Ctrl】+【V】或【F4】
将剪贴板的内容粘到选框中 【Ctrl】+【Shift】+【V】
自由变换 【Ctrl】+【T】
应用自由变换(在自由变换模式下) 【Enter】
从中心或对称点开始变换 (在自由变换模式下) 【Alt】
限制(在自由变换模式下) 【Shift】
扭曲(在自由变换模式下) 【Ctrl】
取消变形(在自由变换模式下) 【Esc】
自由变换复制的象素数据 【Ctrl】+【Shift】+【T】
再次变换复制的象素数据并建立一个副本 【Ctrl】+【Shift】+【Alt】+【T】
删除选框中的图案或选取的路径 【DEL】
用背景色填充所选区域或整个图层 【Ctrl】+【BackSpace】或【Ctrl】+【Del】
用前景色填充所选区域或整个图层 【Alt】+【BackSpace】或【Alt】+【Del】
弹出“填充”对话框 【Shift】+【BackSpace】
从历史记录中填充 【Alt】+【Ctrl】+【Backspace】
图像调整
调整色阶 【Ctrl】+【L】
参考技术A 首先设置窗体的KeyPreview属性为True.

在窗体的KeyDown事件中写入处理的代码.不管是按什么键,都要先经过form的keydown事件
参考技术B private void Form1_KeyDown(object sender, KeyEventArgs e)

//只按一个键
if (e.KeyCode == Keys.Enter)

//...............

else if (e.KeyCode == Keys.A)

//......................



//和alt,ctrl,shift组合使用的快捷键
private void Form1_KeyDown(object sender, KeyEventArgs e)


//这里可以是e.Alt,e.shift,e.ctrl
if (e.Alt && e.KeyCode == Keys.A)

MessageBox.Show(" ");



对于你的第二个问题,你可以在form1的keyDown事件中写,不过非常重要是,要将Form1的KeyPreview属性改为true,这样就可以解决你的第二个问题了。本回答被提问者采纳
参考技术C 那就麻烦了 得用全局钩子 截获键盘信息后发消息 M我 给你代码 参考技术D 不限焦点的话有点难,要调用系统API。

以上是关于C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)的主要内容,如果未能解决你的问题,请参考以下文章

C# winform中咋实现当文本框获得焦点时,如何切换到中文输入法或英文输入法啊?

c#怎么寻找焦点在哪个控件上

关于winform登录窗体的文本框问题

Winform中Treeview控件失去焦点,如何将选择的节点还设置为高亮显示?

在winform上添加用户控件过多时出现闪烁

WinForm中变Enter键为Tab键实现焦点转移的方法