c# 实现虚拟软键盘以及注意的问题

一.焦点的问题
参考链接:https://www.cnblogs.com/loveclumsybaby/articles/3780099.html
软键盘的窗体和普通窗体是有一定的不同,该窗体不会影响其他进程下窗体的光标焦点。
要实现这个技术,必须要把当前窗体设置为浮动工具条才行。这里给出 C# Winform 的实现方法。

        private const int WS_EX_TOOLWINDOW = 0x00000080;
        private const int WS_EX_NOACTIVATE = 0x08000000;

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
                cp.Parent = IntPtr.Zero; // Keep this line only if you used UserControl
                return cp;

                //return base.CreateParams;
            }
        } 

如上代码就是将 Winform 指定为浮动工具条窗体。
二.键盘在z轴的位置
键盘需要位于z字序的最上层主要用到函数SetWindowPos,打开MSDN,查找windows API,很容易找到合适的函数和用法的。
SetWindowPos(
hWnd: HWND; {窗口句柄}
hWndInsertAfter: HWND; {窗口的 Z 顺序}
X, Y: Integer; {位置}
cx, cy: Integer; {大小}
uFlags: UINT {选项}
): BOOL;
//hWndInsertAfter 参数可选值:
HWND_TOP = 0; {在前面}
HWND_BOTTOM = 1; {在后面}
HWND_TOPMOST = HWND(-1); {在前面, 位于任何顶部窗口的前面}
HWND_NOTOPMOST = HWND(-2); {在前面, 位于其他顶部窗口的后面}

x:以客户坐标指定窗口新位置的左边界。
Y:以客户坐标指定窗口新位置的顶边界。
cx:以像素指定窗口的新的宽度。
cy:以像素指定窗口的新的高度。
//uFlags 参数可选值:
SWP_NOSIZE = 1; {忽略 cx、cy, 保持大小}
SWP_NOMOVE = 2; {忽略 X、Y, 不改变位置}
SWP_NOZORDER = 4; {忽略 hWndInsertAfter, 保持 Z 顺序}
SWP_NOREDRAW = 8; {不重绘}
SWP_NOACTIVATE = $10; {不激活}
SWP_FRAMECHANGED = $20; {强制发送 WM_NCCALCSIZE 消息, 一般只是在改变大小时才发送此消息}
SWP_SHOWWINDOW = $40; {显示窗口}
SWP_HIDEWINDOW = $80; {隐藏窗口}
SWP_NOCOPYBITS = $100; {丢弃客户区}
SWP_NOOWNERZORDER = $200; {忽略 hWndInsertAfter, 不改变 Z 序列的所有者}
SWP_NOSENDCHANGING = $400; {不发出 WM_WINDOWPOSCHANGING 消息}
SWP_DRAWFRAME = SWP_FRAMECHANGED; {画边框}
SWP_NOREPOSITION = SWP_NOOWNERZORDER;{}
SWP_DEFERERASE = $2000; {防止产生 WM_SYNCPAINT 消息}
SWP_ASYNCWINDOWPOS = $4000; {若调用进程不拥有窗口, 系统会向拥有窗口的线程发出需求}

指定了SWP_SHOWWINDOW或SWP_HIDEWINDOW,窗口不能被移动或改变大小。

        using System.Runtime.InteropServices;

		public struct WindowRect
		{
  			public int Left;
  			public int Top;
  			public int Right;
  			public int Bottom;
		}

        //z自序
        public const int HWND_TOP = 0;
        public const int HWND_BOTTOM = 1;
        public const int HWND_TOPMOST = -1;
        public const int HWND_NOTOPMOST = -2;
        [DllImport("user32.dll")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags);
        public struct WindowRect
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hWnd, out WindowRect lpRect);


        WindowRect rect = new WindowRect();
        GetWindowRect(this.Handle, out rect);
        SetWindowPos(this.Handle, (IntPtr)HWND_TOPMOST, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, 0);

三.按键功能实现,采用sendkey
使用sendkey最好在send前暂停一下

SendKeys.Send("0");     //0
SendKeys.Send("{BKSP}");//退格键

四.其他
如果要设置透明化等,可以参考GetWindowLong函数,SetLayeredWindowAttributes函数

[DllImport("user32.dll")]//获得有关指定窗口的信息
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

具体可以参考:https://www.cnblogs.com/wingss/p/5116602.html

你可能感兴趣的:(c#笔记)