| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- 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 KeyBoard
- {
- /// <summary>
- /// MainWindow.xaml 的交互逻辑
- /// </summary>
- public partial class MainWindow : Window
- {
- // Windows API 导入
- [DllImport("user32.dll")]
- static extern IntPtr GetForegroundWindow();
- [DllImport("user32.dll")]
- static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
- [DllImport("user32.dll")]
- static extern IntPtr GetFocus();
- [DllImport("user32.dll")]
- static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
- [DllImport("user32.dll")]
- static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll")]
- static extern bool PostThreadMessage(uint idThread, uint Msg, IntPtr wParam, IntPtr lParam);
- [DllImport("kernel32.dll")]
- static extern uint GetCurrentThreadId();
- // 消息常量
- const uint WM_CHAR = 0x0102;
- const uint WM_KEYDOWN = 0x0100;
- const uint WM_KEYUP = 0x0101;
- const uint WM_LBUTTONDOWN = 0x0201;
- const uint WM_LBUTTONUP = 0x0202;
- // 当前活动窗口句柄
- private IntPtr targetWindow = IntPtr.Zero;
- private uint targetThreadId = 0;
- private uint currentThreadId = 0;
- public MainWindow()
- {
- InitializeComponent();
- }
- private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- // 创建按钮样式
- if (!this.Resources.Contains("KeyboardButtonStyle"))
- {
- var style = new System.Windows.Style(typeof(System.Windows.Controls.Button));
- style.Setters.Add(new System.Windows.Setter(System.Windows.Controls.Button.WidthProperty, 60.0));
- style.Setters.Add(new System.Windows.Setter(System.Windows.Controls.Button.HeightProperty, 50.0));
- style.Setters.Add(new System.Windows.Setter(System.Windows.Controls.Button.MarginProperty, new Thickness(2)));
- this.Resources.Add("KeyboardButtonStyle", style);
- }
- // 获取当前线程ID
- currentThreadId = GetCurrentThreadId();
- }
- // 在窗口失去焦点时保存目标窗口信息
- private void Window_Deactivated(object sender, EventArgs e)
- {
- // 获取当前活动窗口
- targetWindow = GetForegroundWindow();
- if (targetWindow != IntPtr.Zero)
- {
- GetWindowThreadProcessId(targetWindow, out targetThreadId);
- }
- }
- // 使用PreviewMouseDown事件而不是Click事件
- private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
- {
- e.Handled = true; // 阻止事件继续传播
- var button = sender as System.Windows.Controls.Button;
- if (button?.Tag != null)
- {
- char keyChar = button.Tag.ToString()[0];
- SendCharacter(keyChar);
- }
- // 防止按钮获得焦点
- this.Focus();
- }
- private void Space_PreviewMouseDown(object sender, MouseButtonEventArgs e)
- {
- e.Handled = true;
- SendCharacter(' ');
- this.Focus();
- }
- private void Backspace_PreviewMouseDown(object sender, MouseButtonEventArgs e)
- {
- e.Handled = true;
- SendBackspace();
- this.Focus();
- }
- // 发送字符到目标窗口
- private void SendCharacter(char ch)
- {
- if (targetWindow != IntPtr.Zero && targetThreadId != 0)
- {
- // 附加到目标线程的输入队列
- AttachThreadInput(currentThreadId, targetThreadId, true);
- // 发送字符消息
- PostMessage(targetWindow, WM_CHAR, new IntPtr(ch), IntPtr.Zero);
- // 分离线程输入
- AttachThreadInput(currentThreadId, targetThreadId, false);
- }
- else
- {
- // 如果没有保存目标窗口,则发送到当前活动窗口
- IntPtr currentForegroundWindow = GetForegroundWindow();
- if (currentForegroundWindow != IntPtr.Zero)
- {
- PostMessage(currentForegroundWindow, WM_CHAR, new IntPtr(ch), IntPtr.Zero);
- }
- }
- }
- // 发送退格键
- private void SendBackspace()
- {
- IntPtr windowToSend = targetWindow != IntPtr.Zero ? targetWindow : GetForegroundWindow();
- if (windowToSend != IntPtr.Zero)
- {
- uint threadId = targetThreadId != 0 ? targetThreadId : GetWindowThreadProcessId(windowToSend, out _);
- if (threadId != 0)
- {
- AttachThreadInput(currentThreadId, threadId, true);
- PostMessage(windowToSend, WM_KEYDOWN, new IntPtr(0x08), IntPtr.Zero); // VK_BACK
- PostMessage(windowToSend, WM_KEYUP, new IntPtr(0x08), IntPtr.Zero);
- AttachThreadInput(currentThreadId, threadId, false);
- }
- }
- }
- // 关闭按钮
- private void CloseButton_Click(object sender, RoutedEventArgs e)
- {
- this.Close();
- }
- }
- }
|