最近公司有一個 項目需要實現類似於金山詞霸,有道詞典等的屏幕取詞功能,准確來說是划詞功能,網上搜了各種屏幕取詞無外乎就兩種:
A、金山詞霸組件法
B、Nhw32.dll法
百度搜到的重復內容真的太多了,自己也google,也沒找到比較好的方法,然后只能根據需求硬着頭皮自己實現,廢話不多說了,先看我實現的原理:
前提條件:文字要能被選擇,比如按鈕上的文字不能被選擇;
原理:定義全局的鼠標鈎子,在選擇文字結束之后向該窗體發送ctrl+c的命令,然后直接從剪切板中獲取;
原理很簡單,實現起來也不是很復雜,只是中間有很多坑的地方:
1:如何知道鼠標選擇了文字
2:選擇完文字向窗體發送ctrl+c的命令
問題1:鼠標選詞這個動作其實執行了三步:
1.左鍵按下(mousedown)
2.鼠標移動(mousemove)
3.左鍵抬起(mouseup)
鈎子的實現網上有很多方法,各位看官可自行百度,也可在文后下載源碼。
這三步能夠知道鼠標選擇了文字,在mouseup的時候去執行后續的操作,當然還有一些相同的鼠標操作並不是選擇文字,例如拖動一個窗體,就算這個動作執行完了可能並沒有在該窗體復制到文字,影響也並不是很大,如果以后想到更好的解決方法再來填坑,各位看官繼續往下看。
問題2:ctrl+c的的命令發送其實有很多中方法,原理都很簡單,應該都能看得懂啦
最簡單的應該就是
SendKeys.SendWait("^c");
SendKeys.Flush();
還有一種
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static public extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
private void SendCtrlC(IntPtr hWnd)
{
uint KEYEVENTF_KEYUP = 2;
byte VK_CONTROL = 0x11;
SetForegroundWindow(hWnd);
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(0x43, 0, 0, 0); //Send the C key (43 is "C")
keybd_event(0x43, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 'Left Control Up
}
剪切板獲取文字,這塊建議大家用循環去取一下剪切板中的值,經驗所得
IDataObject iData = Clipboard.GetDataObject(); if (null != iData) { if (iData.GetDataPresent(DataFormats.Text)) //檢查是否存在文本 { for (int i = 0; i < 6; i++) { Thread.Sleep(500); string res = (String)iData.GetData(DataFormats.Text); if (!string.IsNullOrWhiteSpace(res)) { return res; } } } }
實現效果:
歡迎關注微信公眾號獲取源碼
(關注公眾號回復:屏幕取詞,獲取下載鏈接)
安卓:日本版douyin+美國版抖音(破解版不鎖區)
關注微信公眾號回復“douyin”獲取下載鏈接,每個帖子都有福利哦