【问题标题】:Sending letter 'i' with SendKeys使用 SendKeys 发送字母“i”
【发布时间】:2012-02-19 10:08:35
【问题描述】:

我用 c# Windows Forms 做了一个屏幕键盘。我使用Sendkeys.Send() 函数发送击键。除了字母 i 之外的所有字母都可以正常工作。当我在 Microsoft Word 打开时按键盘上的字母 i 时,它会发送 Ctrl + Alt + I并打开打印对话框。 Notepad++ 也一样。但是当我尝试在记事本中输入时它工作正常。

在我的代码中,我发送带有SendKeys.Send(value); 的键,其中值是按下的按钮的文本。我得到带有以下代码的文本:

string s = ((Button)sender).Text;

关于为什么它不能正常工作的任何 cmets?

编辑:我用一个按钮创建了一个新的 Windows 窗体项目,整个代码如下。还是行不通。任何想法将不胜感激。

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

        private void button1_Click(object sender, EventArgs e)
        {
            SendKeys.Send("i");
        }

        // Prevent form being focused
        const int WS_EX_NOACTIVATE = 0x8000000;
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams ret = base.CreateParams;
                ret.ExStyle |= WS_EX_NOACTIVATE;
                return ret;
            }
        }  
    }

重写的功能是防止表单被聚焦。这样我就可以将击键发送到具有焦点的其他应用程序。

【问题讨论】:

  • 肯定在这部分代码吗? value 是什么,这不是关键字吗?在某些情况下,您可能会发现使用(object as MyClass) 进行转换而不是使用((MyClass)object) 进行转换。如果 obj 不是 MyClass,第二个将返回 null,而不是抛出类转换异常。
  • 对不起。它将是字符串 s 而不是值 s。即使我这样做,结果也不会改变:Sendkeys.Send("i");
  • 您是否使用调试器检查s 的值?这将帮助您缩小问题范围。
  • 是的,在调试器的Sendkeys函数中字符串的值为“i”。我创建了一个按钮并在 onclick 事件中添加了 Sendkeys.Sends("i") 但结果没有改变。
  • @DaveFerguson 我意识到问题是因为我有土耳其语操作系统。如果我将语言更改为英语,该代码运行良好。但在土耳其语中不起作用。现在首先我检测当前应用程序的界面语言并根据语言发送密钥。当界面是英文时,我用 Sendkeys.Send("+{I}") 来做。如果有人需要,我可以发送详细的答案。感谢所有的答案...

标签: c# winforms pinvoke sendkeys


【解决方案1】:

两种选择:

1- 模拟按键,见http://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys(VS.71).aspx

示例:

public static void ManagedSendKeys(string keys)
        {
            SendKeys.SendWait(keys);
            SendKeys.Flush();
        }

2- 向窗口发送一个键,按下按钮 x 秒

[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
public static void KeyboardEvent(Keys key, IntPtr windowHandler, int delay)
        {
            const int KEYEVENTF_EXTENDEDKEY = 0x1;
            const int KEYEVENTF_KEYUP = 0x2;
            keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
            Thread.Sleep(delay);
            keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
        }

【讨论】:

    【解决方案2】:

    您没有调用“SetForegroundWindow”Win32 API 方法。因此,您的“SendKeys”调用可能会将密钥发送到您的应用,而不是预期的目标应用。

    这是 MSDN 上的一个示例:

    How to: Simulate Mouse and Keyboard Events in Code

    另外,下面是示例中的代码:

    using System;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace SimulateKeyPress
    {
        class Form1 : Form
        {
            private Button button1 = new Button();
    
            [STAThread]
            public static void Main()
            {
                Application.EnableVisualStyles();
                Application.Run(new Form1());
            }
    
            public Form1()
            {
                button1.Location = new Point(10, 10);
                button1.TabIndex = 0;
                button1.Text = "Click to automate Calculator";
                button1.AutoSize = true;
                button1.Click += new EventHandler(button1_Click);
    
                this.DoubleClick += new EventHandler(Form1_DoubleClick);
                this.Controls.Add(button1);
            }
    
            // Get a handle to an application window.
            [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindow(string lpClassName,
                string lpWindowName);
    
            // Activate an application window.
            [DllImport("USER32.DLL")]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
    
            // Send a series of key presses to the Calculator application.
            private void button1_Click(object sender, EventArgs e)
            {
                // Get a handle to the Calculator application. The window class
                // and window name were obtained using the Spy++ tool.
                IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator");
    
                // Verify that Calculator is a running process.
                if (calculatorHandle == IntPtr.Zero)
                {
                    MessageBox.Show("Calculator is not running.");
                    return;
                }
    
                // Make Calculator the foreground application and send it 
                // a set of calculations.
                SetForegroundWindow(calculatorHandle);
                SendKeys.SendWait("111");
                SendKeys.SendWait("*");
                SendKeys.SendWait("11");
                SendKeys.SendWait("=");
            }
    
            // Send a key to the button when the user double-clicks anywhere 
            // on the form.
            private void Form1_DoubleClick(object sender, EventArgs e)
            {
                // Send the enter key to the button, which raises the click 
                // event for the button. This works because the tab stop of 
                // the button is 0.
                SendKeys.Send("{ENTER}");
            }
        }
    }
    

    【讨论】:

    • 我刚刚让我的应用程序无法聚焦。因此,即使在我单击我的应用程序上的按钮后,最后一个应用程序也会始终聚焦。这种方法是错误的吗?当我在记事本和写字板上尝试时它可以工作,但在 ms word 和记事本++ 上不起作用
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 2016-09-09
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多