You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
5.9 KiB
C#

9 months ago
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
namespace POSV.Keyboard
{
internal class PopupVirtualKeyboard : Form
{
/// <summary>
/// Creates a new floating virtual keyboard.
/// </summary>
public PopupVirtualKeyboard()
{
//InitializeComponent();
StartPosition = FormStartPosition.Manual;
// Make sure the popup window does not appear in the taskbar.
ShowInTaskbar = false;
MinimizeBox = false;
MaximizeBox = false;
//ControlBox = false;
}
#region Window activation handling
// We need to prevent the keyboard window from activating, otherwise will still focus from our target control.
// Also to achieve this effect, there must be no focusable control in the popup window.
private const int WM_MOUSEACTIVATE = 0x0021;
private const int MA_NOACTIVATE = 0x0003;
private const int WS_EX_NOACTIVATE = 0x08000000;
// Override CreateParams to specify that this Form should not be activated.
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle = createParams.ExStyle & WS_EX_NOACTIVATE;
return createParams;
}
}
protected override void WndProc(ref Message m)
{
// This prevents the window from being activated with the mouse,
// but allows the window to be resized (with the mouse).
if (m.Msg == WM_MOUSEACTIVATE)
{
m.Result = (IntPtr)MA_NOACTIVATE;
}
else
{
base.WndProc(ref m);
}
}
protected override void OnActivated(EventArgs e)
{
Owner.Activate();
}
#endregion
protected override void OnClosing(CancelEventArgs e)
{
// Cancel the Closing event as this will Dispose the form.
e.Cancel = true;
Hide();
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible && CurrentControl != _LastControl && CurrentControl != null)
{
_LastControl = CurrentControl;
}
}
internal Control CurrentControl { get; set; }
private Control _LastControl;
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PopupVirtualKeyboard));
this.SuspendLayout();
//
// PopupVirtualKeyboard
//
this.ClientSize = new System.Drawing.Size(284, 261);
this.DoubleBuffered = true;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "PopupVirtualKeyboard";
this.ShowInTaskbar = false;
this.ResumeLayout(false);
}
/*
public void MoveNearControl(Control control)
{
// We want to show the keyboard near the target control, horizontally centered,
// under the control or above it and without overlapping it, if possible.
// First try to position the Keyboard under the target control.
Point location = control.PointToScreen(Point.Empty);
location.Offset(control.Width / 2 - Width / 2, control.Height);
Location = location;
// And make sure it is in the screen containing the control.
EnsureInScreen(control);
// Now check if this position does not overlap the control.
if (!OverlapsControl(control))
return;
// Now we try to position the Keyboard above the control.
location = control.PointToScreen(Point.Empty);
location.Offset(control.Width / 2 - Width / 2, -Height);
Location = location;
// And again make sure this location is in the screen with the control.
EnsureInScreen(control);
// And check if it does not overlap the control.
if (!OverlapsControl(control))
return;
// If both below and above the control was not a good position, then this means the
// target control is quite large, so show the Keyboard inside it.
location = control.PointToScreen(Point.Empty);
location.Offset(control.Width / 2 - Width / 2, control.Height / 2 - Height / 2);
// And again, make sure the Keybboard is not clipped by the screen.
EnsureInScreen(control);
}
/// <summary>
/// Returns true if the Keyboard overlaps the specified control.
/// </summary>
/// <param name="control">The control for which to check if it is overlapped by the Keyboard.</param>
/// <returns></returns>
private bool OverlapsControl(Control control)
{
Rectangle rect = new Rectangle(control.PointToScreen(Point.Empty), control.Size);
return rect.IntersectsWith(Bounds);
}
/// <summary>
/// Checks if the Keyboard is in the screen containing the specified control, and if
/// the Keyboard is not fully visible, adjusts it's location accordingly.
/// </summary>
/// <param name="control">The control from which the screen is checked. If null, the primary screen is used.</param>
private void EnsureInScreen(Control control)
{
Screen screen = Screen.PrimaryScreen;
if(control != null)
screen = Screen.FromControl(control);
Rectangle rect = screen.WorkingArea;
if (Location.X < rect.Left)
Location = new Point(rect.Left, Location.Y);
if (Location.Y < rect.Top)
Location = new Point(Location.X, rect.Top);
if (Bounds.Right > rect.Right)
Location = new Point(rect.Right - Width, Location.Y);
if (Bounds.Bottom > rect.Bottom)
Location = new Point(Location.X, rect.Bottom - Height);
}
*/
}
}