键盘光标位于c#win表单上的位置。形成 [英] Keyboard Cursor Location on form in c# win. form

查看:150
本文介绍了键盘光标位于c#win表单上的位置。形成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在c#win中找到键盘光标在表单上的位置(x,y)。形成。怎么做到这一点?

[见链接看鼠标光标和键盘光标的区别]



https://www.dropbox.com/s/bcocp5stn0pzvwe/Untitled.png [ ^ ]







提前谢谢

i want to find the keyboard cursor's location (x,y) on form in c# win. form. How to achieve this?
[see the link to see the difference between mouse cursor and keyboard cursor]

https://www.dropbox.com/s/bcocp5stn0pzvwe/Untitled.png[^]



Thanks in advance

推荐答案

'表格上没有#ta键盘位置:有很多潜力位置,取决于哪个控件具有输入焦点。



您可以使用ContainerControl.ActiveControl属性 [ ^ 然后获取该特定控件的键盘输入点:

'There isn#t a "keyboard position" on a form: there are many potential positions, depending on which control has the input focus.

You can find which control in a container has the focus, using the ContainerControl.ActiveControl property[^] and then get the keboard input point for that particular control:
void myTimer_Tick(object sender, EventArgs e)
    {
    string s = "--none--";
    Control c = ActiveControl;
    if (c != null)
        {
        s = c.Name;
        TextBox tb = c as TextBox;
        if (tb != null)
            {
            s += string.Format(" : {0}", tb.SelectionStart);
            }

        }
    theKeyboardIsHere.Text = s;
    }



幸运的是,ActiveControl为您搜索子容器!


Fortunately, ActiveControl searches sub-containers for you!


注意:这里的代码示例已经在Visual Studio 2013中测试并验证,使用Win 8/64计算机上的'AnyCPU构建选项,针对.NET FrameWork 4.5进行编译。



之后一些研究,我发现在某些情况下使用'GetPositionFromCharIndex来确定TextBox 中的插入位置(插入光标点)存在一个已知问题。但是,'GetPositionFromCharIndex适用于RichTextBox。



使用TextBox:



可靠地获取TextBox中的插入点,必须使用WinAPI调用:
Note: code examples here have been tested, and verified, in Visual Studio 2013, compiled against .NET FrameWork 4.5, using the 'AnyCPU build option on a Win 8/64 machine.

After some research, I've found there is a known problem with using 'GetPositionFromCharIndex to determine the caret position (insertion cursor point) in a TextBox under certain circumstances. However, 'GetPositionFromCharIndex works fine with a RichTextBox.

With a TextBox:

To reliably get the caret point in a TextBox, it is necessary to use a WinAPI call:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCaretPos(out Point lpPoint);

这是我发布的原始代码,修改后使用WinAPI'GetCaretPos函数:

Here's the original code I posted modifed to use the WinAPI 'GetCaretPos function:

private Point GetCursorTextBox(TextBox theTextBox)
{
    // see note below on this
    // Control currentActiveControl = ActiveControl;

    // see note below on why this check is here ...
    if (this.ActiveControl != theTextBox)
    {
        this.ActiveControl = theTextBox;
    }`
    
    // get the caret position which is the
    // row-column address of where in the
    // TextBox's Lines collection the insertion cursor is at
    Point chrTbLocation;

    GetCaretPos(out chrTbLocation);

    // index of the character insertion cursor is at
    int selStart = theTextBox.SelectionStart + theTextBox.SelectionLength;

    // line number the insertion cursor is at
    int line = theTextBox.GetLineFromCharIndex(selStart);

    // point in the Screen insertion cursor is at
    Point chrScrnLocation = theTextBox.PointToScreen(chrTbLocation);

    // point in the Form insertion cursor is at
    Point chrFrmLocation = this.PointToClient(chrScrnLocation);

    // for testing only ...

    // this should be identical to the value in 'selStart
    int charPosition = textBox1.GetCharIndexFromPosition(chrTbLocation);

    Console.WriteLine("Caret at: Line: {0} Column: {1} in TextBox: {2}", line, selStart, theTextBox.Name);
    Console.WriteLine("Screen Location: {0} Form Location: {1}", chrScrnLocation, chrFrmLocation);
    Console.WriteLine();

    // see note below on this
    // ActiveControl = currentActiveControl;

    // return the caret point in Form co-ordinates
    return chrFrmLocation;
}

请注意,在方法开始时,将进行检查以确定方法的TextBox参数是否是Form上的当前ActiveControl;如果不是,那么TextBox参数将成为ActiveControl。这样做是因为对'GetCaretPos的调用无法知道表单上的哪个控件(如果有的话)当前是ActiveControl。



但是,请注意,如果从作为参数传入的TextBox的EventHandler调用'GetCursorTextBox方法,例如在TextChanged EventHandler中,那么该检查不是必需的,因为TextChanged事件仅在TextBox为时才会引发ActiveControl。



如果通过'GetCursorTextBox方法更改ActiveControl会给您带来问题,请在方法开头保留当前的ActiveControl,然后将其设置回在方法的最后。执行此操作的代码已显示已注释掉。



使用RichTextBox:



此代码适用于RichTextBox:

Note that at the start of the method, a check is done to determine if the TextBox argument to the method is the current ActiveControl on the Form; if it is not, then the TextBox argument is made the ActiveControl. This is done because the call to 'GetCaretPos has no way of "knowing" which Control on the Form, if any, currently is the ActiveControl.

But, also, note that if you invoke the 'GetCursorTextBox method from an EventHandler of the TextBox passed in as an argument, such as in the TextChanged EventHandler, then that check is not really necessary because the TextChanged event is only going to be raised when the TextBox is the ActiveControl.

If having the ActiveControl changed by the 'GetCursorTextBox method presents a problem for you, then preserve the current ActiveControl at the start of the method, and set it back at the end of the method. Code to do this is shown commented out.

With a RichTextBox:

This code will work fine with a RichTextBox:

private Point GetCursorRichTextBox(RichTextBox theRichTextBox)
{
    // index of the character insertion cursor is at
    int selStart = theRichTextBox.SelectionStart + theRichTextBox.SelectionLength;

    // line number the insertion cursor is at
    int line = theRichTextBox.GetLineFromCharIndex(selStart);

    // point in the TextBox insertion cursor is at
    Point chrTbLocation = theRichTextBox.GetPositionFromCharIndex(selStart);

    // point in the Screen insertion cursor is at
    Point chrScrnLocation = theRichTextBox.PointToScreen(chrTbLocation);

    // point in the Form insertion cursor is at
    Point chrFrmLocation = this.PointToClient(chrScrnLocation);

    // for testing only ...

    // this should be identical to the value in 'selStart
    int charPosition = theRichTextBox.GetCharIndexFromPosition(chrTbLocation);

    Console.WriteLine("Caret at: Line: {0} Column: {1} in RichTextBox: {2}", line, selStart, theRichTextBox.Name);
    Console.WriteLine("Screen Location: {0} Form Location: {1}", chrScrnLocation, chrFrmLocation);
    Console.WriteLine();

    // return the caret point in Form co-ordinates
    return chrFrmLocation; 
}


这篇关于键盘光标位于c#win表单上的位置。形成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆