2017-09-30 110 views
3

我想創建鍵盤在Windows中的Swype表單中使用C#虛擬鍵盤(Swype輸入比如鍵盤)Windows窗體應用程序C#

enter image description here

我有兩個問題:一個 。我無法重現手指輕掃動作。 b。我無法識別不同密鑰下的字母。

對於第一個問題:

我所使用的圖形類和筆類,並使用它像這樣:

bool draw; 
    Graphics g; 
    Pen p; 
    int prevX; 
    int prevY; 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     draw = false; 
     g = CreateGraphics(); 
     p = new Pen(Color.Black, 2); 
    } 

    private void Form1_MouseDown(object sender, MouseEventArgs e) 
    { 
     draw = true; 
     prevX = e.X; 
     prevY = e.Y; 
    } 

    private void Form1_MouseUp(object sender, MouseEventArgs e) 
    { 
     draw = false; 
    } 

    private void Form1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (draw) 
     { 
      g.DrawLine(p, prevX, prevY, e.X, e.Y); 
      prevX = e.X; 
      prevY = e.Y; 
     } 
    } 

但這裏的問題是,它開始從左上角畫的屏幕而不是按鈕的位置。它也沒有畫出按鈕。路徑中的任何控件都與該行重疊。

對於第二期:

a。我使用鼠標放下事件來設置一個布爾值「允許」爲true,然後當鼠標移動時,我嘗試獲取按鈕的文本。就像上面的圖片一樣。我試着從字母「S」開始,當我移過其他字母時,只有字母「S」保持記錄。其他方法的鼠標輸入或鼠標懸停事件甚至不會發生。

b。我也試過使用dragdrop事件,但它不起作用。我不確定,但我假設按鈕不是可拖動的對象拖動事件不起作用。

我不明白或困惑如何實現我的目標。

+0

我認爲,當你開始繪製從左上角到鼠標位置得到一條線嗎?這可能是因爲你的prevx/prevy變量是默認的(0),在這種情況下,你想延遲繪圖,直到第二次鼠標移動事件,這應該給你正確的結果。我不能評論其餘的問題,儘管 – Charleh

+0

這是非常重要的。您不能使用按鈕控件,它們會剪裁您繪製的任何東西並擁有自己的鼠標處理功能。使用Paint事件必須讓它們*看起來像按鈕。 –

+0

@HansPassant有沒有辦法在運動時檢測字母? – Akhil

回答

2

您可以創建自定義控件並自己處理其繪圖。

但是,如果你要使用按鈕控件,並希望籠絡這些按鈕,你可以把一個透明的面板上的按鈕疊加並繪製輕掃路徑,通過透明面板:

enter image description here

透明面板

using System.Windows.Forms; 
public class TransparentPanel : Panel 
{ 
    const int WS_EX_TRANSPARENT = 0x20; 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT; 
      return cp; 
     } 
    } 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
    } 
} 

表格樣本

這只是一個演示透明控件使用的例子。要做到這一點,就足以創造一個形式和替換它與下面的代碼內容:

TransparentPanel overlay; 
TableLayoutPanel table; 
List<Point> points = new List<Point>(); 
List<String> keys = new List<string>(); 
public Form1() 
{ 
    overlay = new TransparentPanel() { Dock = DockStyle.Fill }; 
    this.Controls.Add(overlay); 

    table = new TableLayoutPanel() 
    { ColumnCount = 6, RowCount = 4, Dock = DockStyle.Fill }; 
    this.Controls.Add(table); 

    var list = Enumerable.Range('A', 'Z' - 'A' + 1) 
     .Select(x => ((char)x).ToString()).ToList(); 

    list.ForEach(x => table.Controls.Add(new Button() 
    { Text = x, Width = 32, Height = 32 })); 

    overlay.MouseDown += OverlayMouseDown; 
    overlay.MouseMove += OverlayMouseMove; 
    overlay.MouseUp += OverlayMouseUp; 
    overlay.Paint += OverlayPaint; 
} 
void OverlayMouseMove(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Left) 
     ProccessPoint(e.Location); 
} 
void OverlayMouseDown(object sender, MouseEventArgs e) 
{ 
    Clear(); 
    ProccessPoint(e.Location); 
} 
void OverlayMouseUp(object sender, MouseEventArgs e) 
{ 
    if (points.Count > 0) 
     MessageBox.Show(string.Join(",", keys)); 
    Clear(); 
} 
void OverlayPaint(object sender, PaintEventArgs e) 
{ 
    if (points.Count >= 3) 
     e.Graphics.DrawCurve(Pens.Red, points.ToArray()); 
} 
void ProccessPoint(Point p) 
{ 
    points.Add(p); 
    var c = table.Controls.Cast<Control>() 
     .Where(x => table.RectangleToScreen(x.Bounds) 
     .Contains(overlay.PointToScreen(p))).FirstOrDefault(); 
    if ((c != null) && (keys.Count == 0 || keys[keys.Count - 1] != c.Text)) 
     keys.Add(c.Text); 
    overlay.Invalidate(); 
} 
void Clear() 
{ 
    keys.Clear(); 
    points.Clear(); 
    this.Refresh(); 
}