背景
當前做的一個上位機需運行在工控機上,眾所周知,工控機不可能配備鍵盤,只能是觸屏,而我當前的上位機需要輸入參數,於是之前的解決辦法既是調用Windows自帶的OSK.exe
虛擬鍵盤,方法在我的另一外一篇博客Visual studio之C# 調用系統軟鍵盤(外部"osk.exe")中已詳述,但這種做法有兩個致命缺陷,一是由於調用了外部.exe
程序,國產殺毒軟件會將我的上位機判定為疑似病毒文件(手動微笑);二是,若是該虛擬鍵盤被提前打開,我就沒辦法繼續打開該軟鍵盤使其在我的上位機界面之上,而該軟鍵盤不是由我打開,我就獲取不到它的Process
,也就無法將其關閉重新打開,工控機的界面通常不會出現任務欄,因此虛擬鍵盤要是沒有實體鍵盤就永遠無法打開,頭疼至極。於是就想到自己實現軟鍵盤。便有此文,做個記錄。
首先強調一下,本軟鍵盤非真正意義的軟鍵盤,只是用了很笨的方法在同一個界面上提供了一個數字輸入的解決方案,實際效果如下:
正文
-
為了不讓按鍵在點擊的時候獲取焦點,所以我采用了
label
控件,一共12個控件,分別是0,1...9,退格,清除
,對應的name
分別為,keyb0,keyb1,```keb9,keybback,keybclear
,對應的Text
就是相應的0,1,2...9,退格,清除
,為了調整所有按鍵大小,屬性Autosize
應該設置為false
。 -
在窗體
Load
事件中,添加所有label
控件的單擊事件mybutton_clicked
,
private void lazerctrl_Load(object sender, EventArgs e)
{
// 注冊鍵盤按鍵單擊事件
keyb1.Click += new EventHandler(mybutton_clicked);
keyb2.Click += new EventHandler(mybutton_clicked);
keyb3.Click += new EventHandler(mybutton_clicked);
keyb4.Click += new EventHandler(mybutton_clicked);
keyb5.Click += new EventHandler(mybutton_clicked);
keyb6.Click += new EventHandler(mybutton_clicked);
keyb7.Click += new EventHandler(mybutton_clicked);
keyb8.Click += new EventHandler(mybutton_clicked);
keyb9.Click += new EventHandler(mybutton_clicked);
keyb0.Click += new EventHandler(mybutton_clicked);
keybback.Click += new EventHandler(mybutton_clicked);
keybclear.Click += new EventHandler(mybutton_clicked);
}
在鼠標按鍵事件中,將控件代表的數字值,填入到頁面上最后一個獲取到焦點的TextBox
,內。這個lastfocustextbox
后面說明,
// 執行按鍵操作
void mybutton_clicked(object sender, EventArgs e)
{
Label clickbtn = (Label)sender;
string strkey = clickbtn.Text;
if ((lastfocustextbox == textBoxmhpU) || (lastfocustextbox == textBoxmhpD)
|| (lastfocustextbox == textBoxCWhpU) || (lastfocustextbox == textBoxCWhpD)
|| (lastfocustextbox == textBoxmptU) || (lastfocustextbox == textBoxmptD)
|| (lastfocustextbox == textBoxCWptU) || (lastfocustextbox == textBoxCWptD))
{//不可編輯的textbox就跳過
}
else
{
if (strkey == "退格")
{
string strNew = this.lastfocustextbox.Text;
if (strNew.Length >= 1)
{
strNew = strNew.Substring(0, strNew.Length - 1);
this.lastfocustextbox.Text = strNew;
this.lastfocustextbox.SelectionStart = this.lastfocustextbox.Text.Length;
}
this.lastfocustextbox.Focus();
}
else if (strkey == "清除")
{
lastfocustextbox.Clear();
}
else
{
lastfocustextbox.AppendText(strkey);
}
}
}
- 為了獲知當前聚焦在哪個
TextBox
,就需要在窗體Load
事件注冊所有TextBox
的Enter
事件,並在事件中將最后一次獲得聚焦的TextBox
賦值給前文提及的lastfocustextbox
中,所以我說這是笨方法。: )
private void lazerctrl_Load(object sender, EventArgs e)
{
// 注冊textbox獲取焦點事件
textBoxmp.Enter += new EventHandler(text_getfocused);
textBoxhz.Enter += new EventHandler(text_getfocused);
textBoxduty.Enter += new EventHandler(text_getfocused);
textBoxmlpU.Enter += new EventHandler(text_getfocused);
textBoxmtU.Enter += new EventHandler(text_getfocused);
textBoxmlpD.Enter += new EventHandler(text_getfocused);
textBoxmtD.Enter += new EventHandler(text_getfocused);
textBoxCWp.Enter += new EventHandler(text_getfocused);
textBoxCWlpU.Enter += new EventHandler(text_getfocused);
textBoxCWtU.Enter += new EventHandler(text_getfocused);
textBoxCWlpD.Enter += new EventHandler(text_getfocused);
textBoxCWtD.Enter += new EventHandler(text_getfocused);
textBoxalertt.Enter += new EventHandler(text_getfocused);
textBoxintervalt.Enter += new EventHandler(text_getfocused);
textBoxmhpU.Enter += new EventHandler(text_getfocused);
textBoxmhpD.Enter += new EventHandler(text_getfocused);
textBoxCWhpU.Enter += new EventHandler(text_getfocused);
textBoxCWhpD.Enter += new EventHandler(text_getfocused);
textBoxmptU.Enter += new EventHandler(text_getfocused);
textBoxmptD.Enter += new EventHandler(text_getfocused);
textBoxCWptU.Enter += new EventHandler(text_getfocused);
textBoxCWptD.Enter += new EventHandler(text_getfocused);
}
此處注意lastfocustextbox
在窗體導入時,一定要賦值一個默認的TextBox
,否則在未有一個TextBox
獲取焦點的情況下,用戶點擊按鍵,導致操作null,拋出異常,甚至直接使UI異常關閉。
// 聲明
private System.Windows.Forms.TextBox lastfocustextbox;
// 賦初始值
lastfocustextbox = textBoxintervalt;
// 獲取最后一次獲取焦點的Textbox
void text_getfocused(object sender, EventArgs e)
{
TextBox focuedbox = (TextBox)sender;
lastfocustextbox = focuedbox;
}
- 至此,按鍵的功能就可以實現了,但
Lable
畢竟不是按鍵,沒有Button
的效果,所以我們可以繼續的為lable
注冊鼠標按下和彈起事件,在該事件內改變lable
的邊框,顏色,甚至是圖片,使其有按鍵按下和彈起的效果,特別可以選一些按鍵按下和彈起的圖片,那樣效果會相當不錯。同樣,在窗體Load
事件注冊事件
private void lazerctrl_Load(object sender, EventArgs e)
{
// 注冊鍵盤按鍵鼠標按下事件
keyb1.MouseDown += new MouseEventHandler(mybutton_down);
keyb2.MouseDown += new MouseEventHandler(mybutton_down);
keyb3.MouseDown += new MouseEventHandler(mybutton_down);
keyb4.MouseDown += new MouseEventHandler(mybutton_down);
keyb5.MouseDown += new MouseEventHandler(mybutton_down);
keyb6.MouseDown += new MouseEventHandler(mybutton_down);
keyb7.MouseDown += new MouseEventHandler(mybutton_down);
keyb8.MouseDown += new MouseEventHandler(mybutton_down);
keyb9.MouseDown += new MouseEventHandler(mybutton_down);
keyb0.MouseDown += new MouseEventHandler(mybutton_down);
keybback.MouseDown += new MouseEventHandler(mybutton_down);
keybclear.MouseDown += new MouseEventHandler(mybutton_down);
// 注冊鍵盤按鍵鼠標彈起事件
keyb1.MouseUp += new MouseEventHandler(mybutton_Up);
keyb2.MouseUp += new MouseEventHandler(mybutton_Up);
keyb3.MouseUp += new MouseEventHandler(mybutton_Up);
keyb4.MouseUp += new MouseEventHandler(mybutton_Up);
keyb5.MouseUp += new MouseEventHandler(mybutton_Up);
keyb6.MouseUp += new MouseEventHandler(mybutton_Up);
keyb7.MouseUp += new MouseEventHandler(mybutton_Up);
keyb8.MouseUp += new MouseEventHandler(mybutton_Up);
keyb9.MouseUp += new MouseEventHandler(mybutton_Up);
keyb0.MouseUp += new MouseEventHandler(mybutton_Up);
keybback.MouseUp += new MouseEventHandler(mybutton_Up);
keybclear.MouseUp += new MouseEventHandler(mybutton_Up);
}
// 執行按鍵鼠標按下操作
void mybutton_down(object sender, EventArgs e)
{
Label clickbtn = (Label)sender;
clickbtn.BackColor = System.Drawing.SystemColors.ActiveCaption;
clickbtn.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
}
// 執行按鍵鼠標彈起操作
void mybutton_Up(object sender, EventArgs e)
{
Label clickbtn = (Label)sender;
clickbtn.BackColor = System.Drawing.Color.Aqua;
clickbtn.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
}
至此,記錄完畢。
參考鏈接
- 參考了很多,記不起來了,這么實現的靈感就來自於各種搜查的各類信息
記錄時間:2017-6-11
記錄地點:江蘇淮安