自定义屏幕键盘和过滤下拉列表不能很好地播放

时间:2017-01-03 18:21:59

标签: c# winforms combobox selection on-screen-keyboard

我的winforms应用程序中有一个自定义的屏幕十键盘,除了一个具有一些自定义过滤代码的下拉列表外,似乎在任何地方都可以正常工作。我已经竭尽全力让这个键盘以我能想象到的每一种方式都不相互作用。这里有代码隐藏(如果重要的话,numpad0,numpad1等都是标签)

public partial class TenKeyForm : Form
{
    private const int WM_NCLBUTTONDOWN = 0xA1;
    private const int HT_CAPTION = 0x2;
    private const int WM_MOUSEACTIVATE = 0x0021, MA_NOACTIVATE = 0x0003;
    private const int WS_EX_NOACTIVATE = 0x08000000;

    protected override bool ShowWithoutActivation { get { return true; } }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_MOUSEACTIVATE)
        {
            m.Result = (IntPtr)MA_NOACTIVATE;
            return;
        }
        base.WndProc(ref m);
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle |= WS_EX_NOACTIVATE;
            return createParams;
        }
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool ReleaseCapture();

    public TenKeyForm()
    {
        InitializeComponent();
        MouseDown += MouseDownHandler;

        numpad0.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("0"); });
        numpad1.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("1"); });
        numpad2.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("2"); });
        numpad3.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("3"); });
        numpad4.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("4"); });
        numpad5.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("5"); });
        numpad6.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("6"); });
        numpad7.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("7"); });
        numpad8.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("8"); });
        numpad9.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("9"); });
        numpadDot.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("."); });
        numpadBack.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("+{TAB}"); });
        numpadForward.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("{TAB}"); });
        numpadBackspace.MouseUp += new MouseEventHandler(delegate (object o, MouseEventArgs e) { SendKeys.Send("{BS}"); });

        SetStyle(ControlStyles.Selectable, false);
    }

    private void MouseDownHandler(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }
    }
}

同样,除了单个ComboBox之外,这适用于各种文本框,屏蔽输入等。此ComboBox上有一些额外的验证,以防止输入无效的选择。基本上,如果它有一个条目" 500"和" 550"打字" 5"跳到" 500"在列表中,除了" 5"您键入了高亮显示,以便下一个击键将替换它,即5 00。除了" 5"它会拒绝任何东西。或" 0"在此刻。键入另外5个突出显示55 0,依此类推。这是该位的代码隐藏:

    private void ValidateDropDown(object sender, KeyPressEventArgs e)
    {
        ToolStripComboBox tcb = (ToolStripComboBox)sender;
        ComboBox cb = tcb.ComboBox;
        cb.DroppedDown = true;
        string strFindStr = "";
        if (e.KeyChar == (char)8)
        {
            if (cb.SelectionStart <= 1)
            {
                cb.Text = "";
                return;
            }

            if (cb.SelectionLength == 0)
                strFindStr = cb.Text.Substring(0, cb.Text.Length - 1);
            else
                strFindStr = cb.Text.Substring(0, cb.SelectionStart - 1);
        }
        else
        {
            if (cb.SelectionLength == 0)
                strFindStr = cb.Text + e.KeyChar;
            else
                strFindStr = cb.Text.Substring(0, cb.SelectionStart) + e.KeyChar;
        }
        int intIdx = -1;
        // Search the string in the ComboBox list.
        intIdx = cb.FindString(strFindStr);
        if (intIdx != -1)
        {
            cb.SelectedText = "";
            cb.SelectedIndex = intIdx;
            cb.SelectionStart = strFindStr.Length;
            cb.SelectionLength = cb.Text.Length;
            e.Handled = true;
        }
        else
            e.Handled = true;
    }

现在十键可以正常工作,但是这个ComboBox,如果你输入一个真正的键盘,这个ComboBox可以很好地工作。屏幕键盘甚至可以在第一次按键时正常工作,但是十键表单上的任何后续mousedown事件似乎在ComboBox上执行类似SelectAll()的操作,从而否定了精心设置的选择。打字&#34; 55&#34;在上面的示例中,没有导航到55 0,而是导航到5 00两次,每次点击都会替换整个文本。

造成这种奇怪行为的原因是什么?如何阻止它?

更新:这似乎是ToolStrip ComboBoxes特有的一个问题,应该考虑在这里包含它。另外:AutoCompleteMode = AutoCompleteMode.SuggestAppend

1 个答案:

答案 0 :(得分:1)

如何设置AutoCompleteMode

我做了测试并设置了它:

AutoCompleteMode = AutoCompleteMode.Suggest;

解决了所描述的问题。

编辑1

我找到了该问题的解决方法,您可以添加:

toolStripComboBox1.SelectionLength=0;

SendKey函数之前。