发送带有SendKeys的字母“i”

9
我使用C# Windows Forms创建了一个屏幕键盘。我使用Sendkeys.Send()函数发送按键。除了字母i外,其他所有字母都可以正常工作。当我在打开Microsoft Word时按下键盘上的字母i时,它会发送Ctrl + Alt + I并打开打印对话框。在Notepad++中也是如此。但在记事本中尝试输入时,它可以正常工作。
在我的代码中,我使用SendKeys.Send(value);发送按键,其中value是按下的按钮的文本。我使用以下代码获取文本:
string s = ((Button)sender).Text;

有关为什么它不能正常工作的任何评论?

编辑:我创建了一个只包含按钮的新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是什么,它不是一个关键字吗?在某些情况下,你可能会发现,与其使用 ((MyClass)object) 进行强制转换,不如使用 (object as MyClass) 进行强制转换。后者如果 obj 不是 MyClass 类型,则返回 null,而不是抛出类转换异常。 - MoonKnight
非常抱歉,应该使用字符串 s 而不是值 s。即使我这样做:Sendkeys.Send("i"); 结果也不会改变。 - Ozgur Dogus
你使用调试器检查了s的值吗?这将有助于缩小问题范围。 - Kendall Frey
是的,在调试器中Sendkeys函数中字符串的值为"i"。我创建了一个按钮,并在onclick事件中添加了Sendkeys.Sends("i"),但结果没有改变。 - Ozgur Dogus
1
@DaveFerguson 我意识到问题是因为我使用的是土耳其操作系统。如果我将语言更改为英语,则代码可以正常工作,但在土耳其语下无法正常工作。现在,我首先检测当前应用程序的界面语言,并根据语言发送键。当界面为英语时,我使用Sendkeys.Send("+{I}")来执行此操作。如果有人需要详细答案,我可以提供。感谢所有的回答... - Ozgur Dogus
显示剩余3条评论
2个回答

1

你没有调用“SetForegroundWindow”Win32 API方法。因此,你的“SendKeys”调用很可能会将按键发送到你的应用程序,而不是目标应用程序。

以下是MSDN上的示例:

如何在代码中模拟鼠标和键盘事件

此外,这里是示例中的代码:

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和Notepad ++上无效。 - Ozgur Dogus

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);
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接