其實關鍵就只是利用C# SendKeys 的功能而已(這篇有寫過)
但如果要寫一個完整模擬鍵盤的APP,會有些比較複雜的功能。
一開始會打算先用字串陣列的方式,順序就依照鍵盤的設計去準備每個按鍵的圖案跟Keycode。
首先是鍵盤圖檔所有的檔名,包含大小寫轉換的圖案。
路徑的部分依照按下的狀態分為兩個資料夾來放(Keyup and Keydown),Keydown 是按下去時反白的圖案,圖檔格式為.png:
private String FileType = ".png";
private String FilePathKeyUp = "Image/KeyUp/keyup_";
private String FilePathKeyDown = "Image/KeyDown/keydown_";
private String[] CapsLetterFileName = {"q","w","e","r","t","y","u","i","o","p","delete","one","two","three",
"a","s","d","f","g","h","j","k","l","double_quote","enter","four","five","six",
"shift","z","x","c","v","b","n","m","semicolon","colon","exclamation_mark_screamer","shift2","seven","eight","nine",
"ctrl","alt","windows","spacebar","left","right","keyboard","zero","lperiod_full_stop"};
private String[] SmallLetterFileName = {"lq","lw","le","lr","lt","ly","lu","li","lo","lp","delete","one","two","three",
"la","ls","ld","lf","lg","lh","lj","lk","ll","lsingle_quote","enter","four","five","six",
"shift","lz","lx","lc","lv","lb","ln","lm","lcomma","lperiod_full_stop","lquestion_mark","shift2","seven","eight","nine",
"ctrl","alt","windows","spacebar","left","right","keyboard","zero","lperiod_full_stop"};
再來是Keycode的部分,對應到上面的陣列位置,分別準備大、小寫的陣列。
private String[] KeyCodeCapsLetter = {"Q","W","E","R","T","Y","U","I","O","P", "{backspace}","1","2","3",
"A","S","D","F","G","H","J","K","L","\"","{enter}","4","5","6",
"shift","Z","X","C","V","B","N","M",";",":","!","shift","7","8","9",
"^","%","^" + "{esc}"," ","{left}","{right}","keyboard","0","."};
private String[] KeyCodeSmallLetter = {"q","w","e","r","t","y","u","i","o","p", "{backspace}","1","2","3",
"a","s","d","f","g","h","j","k","l","'","{enter}","4","5","6",
"shift","z","x","c","v","b","n","m",",",".","?","shift","7","8","9",
"^","%","^" + "{esc}"," ","{left}","{right}","keyboard","0","."};
這樣之後程式碼寫輸入的部分,就可以用for 迴圈搭配if 判斷陣列位置這樣來寫:
for (int i = 0; i < key_amount; i++)
{
if (mImage.Name == CapsLetterFileName[i])
{
if (isCaps)
{
SendKeys.SendWait(KeyCodeCapsLetter[i]);
}
else
{
SendKeys.SendWait(KeyCodeSmallLetter[i]);
}
}
}
寫到這邊先來講一個問題,一般APP 出現在螢幕上的時候,視窗一定要Focus 才能用,但是要模擬鍵盤功能的話,是要針對APP 以外的其他視窗打字。
所以這邊的作法是先把APP 設定為Topmost (在xaml 中的Window 物件 > 屬性 > 一般 > Topmost)。
然後在cs 程式碼中宣告的地方import 需要的dll :
// import dll to control on Topmost
[DllImport("user32", SetLastError = true)]
private extern static int GetWindowLong(IntPtr hwnd, int nIndex);
[DllImport("user32", SetLastError = true)]
private extern static int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewValue);
在程式碼中建立一個函式 initTopmostControl() :
private void initTopmostControl()
{
WindowInteropHelper wih = new WindowInteropHelper(this);
int exstyle = GetWindowLong(wih.Handle, -20);
exstyle |= 0x08000000;
SetWindowLong(wih.Handle, -20, exstyle);
}
這邊也讓Keyboard APP 模擬真實的鍵盤,可以在右下角看到APP 的圖示,甚至可以點它來開啟/隱藏Keyboard。
可以參考之前寫過的NotifyIcon 寫法(參考這篇):
建立一個函式 initNotifyIcon():
// init NotifyIcon
private void initNotifyIcon()
{
notifyIcon = new NotifyIcon();
Stream iconStream = System.Windows.Application.GetResourceStream(new Uri(@"Image/icon2.ico", UriKind.Relative)).Stream;
notifyIcon.Icon = new System.Drawing.Icon(iconStream);
System.Windows.Forms.ContextMenu notifyIconMenu = new System.Windows.Forms.ContextMenu();
System.Windows.Forms.MenuItem notifyIconMenuItem = new System.Windows.Forms.MenuItem();
notifyIconMenuItem.Index = 0;
notifyIconMenuItem.Text = "Exit";
notifyIconMenuItem.Click += new EventHandler(notifyIconMenuItem_Click);
notifyIconMenu.MenuItems.Add(notifyIconMenuItem);
notifyIcon.ContextMenu = notifyIconMenu;
notifyIcon.Visible = true;
notifyIcon.Click += new EventHandler(TouckKeyboard_state);
}
這邊NotifyIcon 想要加入的功能是,在icon 上點右鍵選擇Exit 來關閉APP。
notifyIconMenuItem.Click += new EventHandler(notifyIconMenuItem_Click);
其中notifyIconMenuItem_Click就是寫直接關閉APP
private void notifyIconMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
另外,可以在右下角的icon 上,點左鍵來顯示/隱藏APP,
notifyIcon.Click += new EventHandler(TouckKeyboard_state);
其中TouckKeyboard_state 就是來控制Keyboard APP 視窗顯示的位置,判斷isShow 然後利用Top 值來設定式窗位置,所以程式碼還要加入:
// show or hide keyboard
private void TouckKeyboard_state(object sender, EventArgs e)
{
isShow = !isShow;
TouckKeyboard_position();
}
// show or hide keyboard position
private void TouckKeyboard_position()
{
if (!isShow)
{
while (this.Top < workArea.Height + 50)
{
this.Top++;
}
}
else
{
while (this.Top >= workArea.Height - this.Height + 1)
{
this.Top--;
}
}
}
workArea 的部分是建立一個Rect 來抓系統中,整個螢幕的範圍,可以透過它來設定視窗位置,或是做APP 等比例的縮放:
private Rect workArea; workArea = System.Windows.SystemParameters.WorkArea;
以上三個函式initTopmostControl()、initNotifyIcon()、TouckKeyboard_position() 建議寫在Window_Loaded() 裡面比較保險。
在xaml 中的Window 物件 > 屬性 > 事件 > Loaded 點開產生函式:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
initTopmostControl();
initNotifyIcon();
TouckKeyboard_position();
}
目前是寫針對APP 方面前提的一些基本的功能,接下來是比較重要的部分,就是每個按鍵的設定跟功能寫法。
在MainWindow() 先利用前面寫的workArea 來設定APP是窗的位置跟大小:
public MainWindow()
{
InitializeComponent();
// set keyboard window x,y,w,h by workArea
workArea = System.Windows.SystemParameters.WorkArea;
this.Left = 0;
this.Top = workArea.Height;
this.Width = workArea.Width;
this.Height = workArea.Height * 0.435;
}
這邊補上一個Layout 的參數來參考一下(參考圖檔來源的 spec.jpg):
建立一個函式initKeyImage() 來設定所有的按鍵圖案,包括圖檔、大小、位置:
private void initKeyImage()
{
key_amount = CapsLetterFileName.Length;
LetterFileName = new String[key_amount];
imageLetter = new Image[key_amount];
for (int i = 0; i < key_amount; i++)
{
// create key image
imageLetter[i] = new Image();
imageLetter[i].Name = CapsLetterFileName[i];
imageLetter[i].Source = new BitmapImage(new Uri(@FilePathKeyUp + CapsLetterFileName[i] + FileType, UriKind.Relative));
imageLetter[i].Stretch = Stretch.Fill;
imageLetter[i].MouseDown += new MouseButtonEventHandler(imageLetterMouseDown);
imageLetter[i].MouseUp += new MouseButtonEventHandler(imageLetterMouseUp);
imageLetter[i].MouseLeave += new System.Windows.Input.MouseEventHandler(imageLetterMouseLeave);
CanvasWindow.Children.Add(imageLetter[i]);
// set left of each key image
if (imageLetter[i].Name == "q" || imageLetter[i].Name == "shift" || imageLetter[i].Name == "ctrl")
{
Canvas.SetLeft(imageLetter[i], workArea.Width * 0.04);
}
else if (imageLetter[i].Name == "a")
{
Canvas.SetLeft(imageLetter[i], workArea.Width * 0.053);
}
else
{
Canvas.SetLeft(imageLetter[i], Canvas.GetLeft(imageLetter[i - 1]) + imageLetter[i - 1].Width + 10);
}
// set top of each key image
if (i >= 0 && i <= 13)
{
Canvas.SetTop(imageLetter[i], workArea.Width * 0.01);
}
else if (i >= 14 && i <= 27)
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 1));
}
else if (i >= 28 && i <= 42)
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 2));
}
else
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 3));
}
// set width of each key iamge
if (imageLetter[i].Name == "delete" || imageLetter[i].Name == "zero")
{
imageLetter[i].Width = workArea.Width * 0.111;
}
else if (imageLetter[i].Name == "enter")
{
imageLetter[i].Width = workArea.Width * 0.098;
}
else if (imageLetter[i].Name == "spacebar")
{
imageLetter[i].Width = workArea.Width * 0.345;
}
else
{
imageLetter[i].Width = workArea.Width * 0.053;
}
// set height of each key iamge
imageLetter[i].Height = workArea.Height * 0.091;
}
}
建立滑鼠按下事件函式,圖案會呈現反白的樣子:
private void imageLetterMouseDown(object sender, RoutedEventArgs e)
{
isDown = true;
Image mImage = (Image) sender;
// set key pressed
for (int i = 0; i < key_amount; i++)
{
if (mImage.Name == CapsLetterFileName[i])
{
key_pressed = i;
}
}
// set the keydown status and image
setKeyStatus("down");
// set long press
if (mImage.Name != "shift" && mImage.Name != "shift2")
{
SetLongPressTimer(true);
}
}
建立滑鼠移開事件函式,做類似 mouse up的功能,但不要做任何事情:
private void imageLetterMouseLeave(object sender, RoutedEventArgs e)
{
Image mImage = (Image)sender;
// set the keyup status and image
setKeyStatus("up");
SetLongPressTimer(false);
}
建立滑鼠放開事件函式,在這裡就要寫判斷按了哪一個按鍵,做出對應的Keycode 功能:
private void imageLetterMouseUp(object sender, RoutedEventArgs e)
{
Image mImage = (Image)sender;
// set the keyup status and image
setKeyStatus("up");
// send key function
if (isDown)
{
// shift function
if (mImage.Name == "shift" || mImage.Name == "shift2")
{
isCaps = !isCaps;
setLetterCaps(isCaps);
}
// keyboard show function
else if (mImage.Name == "keyboard")
{
isShow = !isShow;
TouckKeyboard_position();
}
// letter function
else
{
for (int i = 0; i < key_amount; i++)
{
if (mImage.Name == CapsLetterFileName[i])
{
if (isCaps)
{
SendKeys.SendWait(KeyCodeCapsLetter[i]);
}
else
{
SendKeys.SendWait(KeyCodeSmallLetter[i]);
}
}
}
}
SetLongPressTimer(false);
}
}
在以上滑鼠事件中,down 跟up 事件裡有狀態切換的函式setKeyStatus(),跟計時器的函式SetLongPressTimer()。
在setKeyStatus() 裡面做的就是鍵盤沒按/按下的狀態切換,按下會反白,寫一個setKeyImage()函式來切換不同狀態的圖案。
// set key status
private void setKeyStatus(String status)
{
if(status == "down")
{
setKeyImage(imageLetter[key_pressed], FilePathKeyDown + LetterFileName[key_pressed] + FileType);
}
else if (status == "up")
{
setKeyImage(imageLetter[key_pressed], FilePathKeyUp + LetterFileName[key_pressed] + FileType);
}
}
// set key image source
private void setKeyImage(Image image, String filepath)
{
image.Source = new BitmapImage(new Uri(@filepath, UriKind.Relative));
}
另外就是函式SetLongPressTimer() 來控制長按用的計時器LongPressTimer 開啟/結束:
private void SetLongPressTimer(bool isStart)
{
if (isStart)
{
LongPressTimer.Start();
}
else
{
LongPressTimer.Stop();
pressed_count = 0;
isDown = false;
}
}
當按下shift 時會切換大小寫模式,所以要建立一個函式setLetterCaps() 來切換大小寫模式:
private void setLetterCaps(bool isCaps)
{
for (int i = 0; i < key_amount; i++)
{
if (isCaps)
{
LetterFileName[i] = CapsLetterFileName[i];
}
else
{
LetterFileName[i] = SmallLetterFileName[i];
}
setKeyImage(imageLetter[i], FilePathKeyUp + LetterFileName[i] + FileType);
}
}
MainWindow() 加入initKeyImage() 跟 setLetterCaps(true),另外也加入長按功能:
private bool isCaps = true;
private DispatcherTimer LongPressTimer;
public MainWindow()
{
InitializeComponent();
// set keyboard window x,y,w,h by workArea
workArea = System.Windows.SystemParameters.WorkArea;
this.Left = 0;
this.Top = workArea.Height;
this.Width = workArea.Width;
this.Height = workArea.Height * 0.435;
// set long press timer
LongPressTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.01) };
LongPressTimer.Tick += LongPressTimerTick;
initKeyImage();
setLetterCaps(isCaps);
}
在程式碼中加入計時器函式 LongPressTimerTick(),當長按時會一直輸入:
private void LongPressTimerTick(object sender, EventArgs e)
{
pressed_count ++;
if (pressed_count > 15)
{
if (isCaps)
{
SendKeys.SendWait(KeyCodeCapsLetter[key_pressed]);
}
else
{
SendKeys.SendWait(KeyCodeSmallLetter[key_pressed]);
}
}
}
APP 執行的時候,可以從工具列的右下角看程式有沒有打開。
最後附上全部完整的程式碼:
MainWindow.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Threading;
using System.Windows.Input;
namespace TouchKeyboard
{
public partial class MainWindow : Window
{
private bool isShow = true, isCaps = true, isDown = false;
private int key_amount, key_pressed, pressed_count = 0;
private String FileType = ".png";
private String FilePathKeyUp = "Image/KeyUp/keyup_";
private String FilePathKeyDown = "Image/KeyDown/keydown_";
private String[] CapsLetterFileName = {"q","w","e","r","t","y","u","i","o","p","delete","one","two","three",
"a","s","d","f","g","h","j","k","l","double_quote","enter","four","five","six",
"shift","z","x","c","v","b","n","m","semicolon","colon","exclamation_mark_screamer","shift2","seven","eight","nine",
"ctrl","alt","windows","spacebar","left","right","keyboard","zero","lperiod_full_stop"};
private String[] SmallLetterFileName = {"lq","lw","le","lr","lt","ly","lu","li","lo","lp","delete","one","two","three",
"la","ls","ld","lf","lg","lh","lj","lk","ll","lsingle_quote","enter","four","five","six",
"shift","lz","lx","lc","lv","lb","ln","lm","lcomma","lperiod_full_stop","lquestion_mark","shift2","seven","eight","nine",
"ctrl","alt","windows","spacebar","left","right","keyboard","zero","lperiod_full_stop"};
private String[] KeyCodeCapsLetter = {"Q","W","E","R","T","Y","U","I","O","P", "{backspace}","1","2","3",
"A","S","D","F","G","H","J","K","L","\"","{enter}","4","5","6",
"shift","Z","X","C","V","B","N","M",";",":","!","shift","7","8","9",
"^","%","^" + "{esc}"," ","{left}","{right}","keyboard","0","."};
private String[] KeyCodeSmallLetter = {"q","w","e","r","t","y","u","i","o","p", "{backspace}","1","2","3",
"a","s","d","f","g","h","j","k","l","'","{enter}","4","5","6",
"shift","z","x","c","v","b","n","m",",",".","?","shift","7","8","9",
"^","%","^" + "{esc}"," ","{left}","{right}","keyboard","0","."};
private String[] LetterFileName;
private Image[] imageLetter;
private Rect workArea;
private NotifyIcon notifyIcon;
private DispatcherTimer LongPressTimer;
// import dll to control on Topmost
[DllImport("user32", SetLastError = true)]
private extern static int GetWindowLong(IntPtr hwnd, int nIndex);
[DllImport("user32", SetLastError = true)]
private extern static int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewValue);
public MainWindow()
{
InitializeComponent();
// set keyboard window x,y,w,h by workArea
workArea = System.Windows.SystemParameters.WorkArea;
this.Left = 0;
this.Top = workArea.Height;
this.Width = workArea.Width;
this.Height = workArea.Height * 0.435;
// set long press timer
LongPressTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.01) };
LongPressTimer.Tick += LongPressTimerTick;
initKeyImage();
setLetterCaps(isCaps);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
initTopmostControl();
initNotifyIcon();
TouckKeyboard_position();
}
// control on Topmost
private void initTopmostControl()
{
WindowInteropHelper wih = new WindowInteropHelper(this);
int exstyle = GetWindowLong(wih.Handle, -20);
exstyle |= 0x08000000;
SetWindowLong(wih.Handle, -20, exstyle);
}
// init NotifyIcon
private void initNotifyIcon()
{
notifyIcon = new NotifyIcon();
Stream iconStream = System.Windows.Application.GetResourceStream(new Uri(@"Image/icon2.ico", UriKind.Relative)).Stream;
notifyIcon.Icon = new System.Drawing.Icon(iconStream);
System.Windows.Forms.ContextMenu notifyIconMenu = new System.Windows.Forms.ContextMenu();
System.Windows.Forms.MenuItem notifyIconMenuItem = new System.Windows.Forms.MenuItem();
notifyIconMenuItem.Index = 0;
notifyIconMenuItem.Text = "Exit";
notifyIconMenuItem.Click += new EventHandler(notifyIconMenuItem_Click);
notifyIconMenu.MenuItems.Add(notifyIconMenuItem);
notifyIcon.ContextMenu = notifyIconMenu;
notifyIcon.Visible = true;
notifyIcon.Click += new EventHandler(TouckKeyboard_state);
}
// init key image object
private void initKeyImage()
{
key_amount = CapsLetterFileName.Length;
LetterFileName = new String[key_amount];
imageLetter = new Image[key_amount];
for (int i = 0; i < key_amount; i++)
{
// create key image
imageLetter[i] = new Image();
imageLetter[i].Name = CapsLetterFileName[i];
imageLetter[i].Source = new BitmapImage(new Uri(@FilePathKeyUp + CapsLetterFileName[i] + FileType, UriKind.Relative));
imageLetter[i].Stretch = Stretch.Fill;
imageLetter[i].MouseDown += new MouseButtonEventHandler(imageLetterMouseDown);
imageLetter[i].MouseUp += new MouseButtonEventHandler(imageLetterMouseUp);
imageLetter[i].MouseLeave += new System.Windows.Input.MouseEventHandler(imageLetterMouseLeave);
CanvasWindow.Children.Add(imageLetter[i]);
// set left of each key image
if (imageLetter[i].Name == "q" || imageLetter[i].Name == "shift" || imageLetter[i].Name == "ctrl")
{
Canvas.SetLeft(imageLetter[i], workArea.Width * 0.04);
}
else if (imageLetter[i].Name == "a")
{
Canvas.SetLeft(imageLetter[i], workArea.Width * 0.053);
}
else
{
Canvas.SetLeft(imageLetter[i], Canvas.GetLeft(imageLetter[i - 1]) + imageLetter[i - 1].Width + 10);
}
// set top of each key image
if (i >= 0 && i <= 13)
{
Canvas.SetTop(imageLetter[i], workArea.Width * 0.01);
}
else if (i >= 14 && i <= 27)
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 1));
}
else if (i >= 28 && i <= 42)
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 2));
}
else
{
Canvas.SetTop(imageLetter[i], (workArea.Width * 0.01 + (workArea.Height * 0.091 + workArea.Width * 0.004) * 3));
}
// set width of each key iamge
if (imageLetter[i].Name == "delete" || imageLetter[i].Name == "zero")
{
imageLetter[i].Width = workArea.Width * 0.111;
}
else if (imageLetter[i].Name == "enter")
{
imageLetter[i].Width = workArea.Width * 0.098;
}
else if (imageLetter[i].Name == "spacebar")
{
imageLetter[i].Width = workArea.Width * 0.345;
}
else
{
imageLetter[i].Width = workArea.Width * 0.053;
}
// set height of each key iamge
imageLetter[i].Height = workArea.Height * 0.091;
}
}
private void imageLetterMouseDown(object sender, RoutedEventArgs e)
{
isDown = true;
Image mImage = (Image) sender;
// set key pressed
for (int i = 0; i < key_amount; i++)
{
if (mImage.Name == CapsLetterFileName[i])
{
key_pressed = i;
}
}
// set the keydown status and image
setKeyStatus("down");
// set long press
if (mImage.Name != "shift" && mImage.Name != "shift2")
{
SetLongPressTimer(true);
}
}
private void imageLetterMouseLeave(object sender, RoutedEventArgs e)
{
Image mImage = (Image)sender;
// set the keyup status and image
setKeyStatus("up");
SetLongPressTimer(false);
}
private void imageLetterMouseUp(object sender, RoutedEventArgs e)
{
Image mImage = (Image)sender;
// set the keyup status and image
setKeyStatus("up");
// send key function
if (isDown)
{
// shift function
if (mImage.Name == "shift" || mImage.Name == "shift2")
{
isCaps = !isCaps;
setLetterCaps(isCaps);
}
// keyboard show function
else if (mImage.Name == "keyboard")
{
isShow = !isShow;
TouckKeyboard_position();
}
// letter function
else
{
for (int i = 0; i < key_amount; i++)
{
if (mImage.Name == CapsLetterFileName[i])
{
if (isCaps)
{
SendKeys.SendWait(KeyCodeCapsLetter[i]);
}
else
{
SendKeys.SendWait(KeyCodeSmallLetter[i]);
}
}
}
}
SetLongPressTimer(false);
}
}
// set all letter caps or little
private void setLetterCaps(bool isCaps)
{
for (int i = 0; i < key_amount; i++)
{
if (isCaps)
{
LetterFileName[i] = CapsLetterFileName[i];
}
else
{
LetterFileName[i] = SmallLetterFileName[i];
}
setKeyImage(imageLetter[i], FilePathKeyUp + LetterFileName[i] + FileType);
}
}
// set key status
private void setKeyStatus(String status)
{
if(status == "down")
{
setKeyImage(imageLetter[key_pressed], FilePathKeyDown + LetterFileName[key_pressed] + FileType);
}
else if (status == "up")
{
setKeyImage(imageLetter[key_pressed], FilePathKeyUp + LetterFileName[key_pressed] + FileType);
}
}
// set key image source
private void setKeyImage(Image image, String filepath)
{
image.Source = new BitmapImage(new Uri(@filepath, UriKind.Relative));
}
// show or hide keyboard
private void TouckKeyboard_state(object sender, EventArgs e)
{
isShow = !isShow;
TouckKeyboard_position();
}
// show or hide keyboard position
private void TouckKeyboard_position()
{
if (!isShow)
{
while (this.Top < workArea.Height + 50)
{
this.Top++;
}
}
else
{
while (this.Top >= workArea.Height - this.Height + 1)
{
this.Top--;
}
}
}
private void SetLongPressTimer(bool isStart)
{
if (isStart)
{
LongPressTimer.Start();
}
else
{
LongPressTimer.Stop();
pressed_count = 0;
isDown = false;
}
}
private void LongPressTimerTick(object sender, EventArgs e)
{
pressed_count ++;
if (pressed_count > 15)
{
if (isCaps)
{
SendKeys.SendWait(KeyCodeCapsLetter[key_pressed]);
}
else
{
SendKeys.SendWait(KeyCodeSmallLetter[key_pressed]);
}
}
}
private void notifyIconMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void Window_Closed(object sender, EventArgs e)
{
notifyIcon.Dispose();
}
}
}
xaml:
<Window x:Class="TouchKeyboard.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TouchKeyboard"
mc:Ignorable="d"
Title="MainWindow" Topmost="True" Loaded="Window_Loaded" Left="0" Top="0" Height="296" Width="1280" WindowStyle="None" Visibility="Visible" AllowsTransparency="True" Closed="Window_Closed" ResizeMode="NoResize" Focusable="False" ShowInTaskbar="False" Background="Black">
<Grid>
<Canvas x:Name="CanvasWindow">
</Canvas>
</Grid>
</Window>
END


沒有留言:
張貼留言