為什么我的文本粘貼自帶斷行?(復(fù)制粘貼之后有空行)
883
2025-03-31
都云時代了,前段時間,因為公司突然來了一大批IC卡讀卡器要制作,而且只有1個星期時間進(jìn)行制作,某部門的苦苦哀求下答應(yīng)幫他們做一個IC卡讀卡器的輔助工具。
這個讀卡器原廠的附帶的制作工具,操作步驟居然有12步(寒)!并且既有WinXP的exe端(只能WinXP,不支持Win7……),又有Web端。其實難點(diǎn)在于WinXP的exe端,要模擬菜單點(diǎn)擊、鍵盤輸入、鼠標(biāo)點(diǎn)擊。而Web端嘛,再不行就直接用python bs4嘛(不過最后也用C#成功弄了爬蟲)。記錄一下整個開發(fā)調(diào)試過程。
首先理解一個概念:句柄
句柄是Windows用來標(biāo)志應(yīng)用程序中建立的或是使用的唯一整數(shù)(相當(dāng)于唯一的ID),Windows大量使用了句柄來標(biāo)識對象,即一個4字節(jié)(64位程序中為8字節(jié))長的數(shù)值,來標(biāo)識應(yīng)用程序中的不同對象和同類中的不同的實例,諸如,一個窗口,按鈕,圖標(biāo),滾動條,輸出設(shè)備,控件或者文件等。應(yīng)用程序能夠通過句柄訪問相應(yīng)的對象的信息,但是句柄不是指針,程序不能利用句柄來直接閱讀文件中的信息。
獲取句柄通常采用2個Win32 API函數(shù):
FindWindow(
lpClassName,??????? {窗口的類名}
lpWindowName: PChar {窗口的標(biāo)題}
): HWND;????????????? {返回窗口的句柄; 失敗返回 0}
//FindWindowEx 比 FindWindow 多出兩個句柄參數(shù):
FindWindowEx(
Parent: HWND;???? {要查找子窗口的父窗口句柄}
Child: HWND;????? {子窗口句柄}
ClassName: PChar; {}
WindowName: PChar {}
): HWND;
{
如果 Parent 是 0, 則函數(shù)以桌面窗口為父窗口, 查找桌面窗口的所有子窗口;
如果? 是 HWND_MESSAGE, 函數(shù)僅查找所有消息窗口;
子窗口必須是 Parent 窗口的直接子窗口;
如果 Child 是 0, 查找從 Parent 的第一個子窗口開始;
如果 Parent 和 Child 同時是 0, 則函數(shù)查找所有的頂層窗口及消息窗口.
}
1.查找主窗口的句柄:
IntPtr?mainHandle?=?FindWindow(null,?"UKeyManage"); if?(mainHandle?!=?IntPtr.Zero) { 下續(xù)對菜單進(jìn)行點(diǎn)擊操作 }
2.對菜單進(jìn)行點(diǎn)擊操作
IntPtr?menu?=?GetMenu(mainHandle); Console.WriteLine("menu"?+?menu); int?subMenuCount?=?0; for?(int?s?=?0;?s?65535;?s++) { ????IntPtr?subMenu?=?GetSubMenu(menu,?s); ????if?(subMenu?!=?IntPtr.Zero) ????{ ????????subMenuCount++; //用戶證書在第2個菜單(證書管理)下 ????????if?(subMenuCount?2)?{?continue;?} ????????Console.WriteLine("subMenu"?+?subMenu); ????????int?itemCount?=?0; ????????for?(int?i?=?0;?i?65535;?i++) ????????{ ????????????IntPtr?item?=?GetMenuItemID(subMenu,?i); ????????????if?(item?!=?IntPtr.Zero?&&?(int)item?!=?-1) ????????????{ ????????????????itemCount++; //證書管理下面的第2個就是導(dǎo)出用戶證書 ????????????????if?(itemCount?==?2) ????????????????{ ????????????????????//導(dǎo)出用戶證書 ????????????????????Console.WriteLine("item"?+?item); //發(fā)送點(diǎn)擊菜單命令 ????????????????????PostMessage(mainHandle,?WM_COMMAND,?item,?0); ????????????????????break; ????????????????} ????????????} ????????} ????????break; ????} }
3.模擬鍵盤輸入操作
//彈出來的對話框先取窗口句柄 IntPtr?initWinHandle?=?FindWindow(null,?"UsrPinDlg"); Console.WriteLine("UsrPinDlg"?+?initWinHandle); //先設(shè)置最前端 SetForegroundWindow(initWinHandle); Thread.Sleep(500); SendKeys.SendWait("********");//密碼 Thread.Sleep(500); //查找Button的句柄 IntPtr?initOkHandle?=?FindWindowEx(initWinHandle,?0,?"Button",?null); Console.WriteLine("b:"?+?initOkHandle); //點(diǎn)擊Button SendMessage(initOkHandle,?BM_CLICK,?IntPtr.Zero,?IntPtr.Zero);
4.獲取ListBox的信息
//回到主界面,查看ListBox的消息 IntPtr?mainHandle2?=?FindWindow(null,?"UKeyManage"); Console.WriteLine("mainHandle2"?+?mainHandle2); IntPtr?listBoxHandle?=?FindWindowEx(mainHandle2,?0,?"ListBox",?null); Console.WriteLine("listBoxHandle"?+?listBoxHandle); IntPtr?lbHandle?=?SendMessage(listBoxHandle,?LB_GETCOUNT,?IntPtr.Zero,?IntPtr.Zero); Console.WriteLine("lbHandle"?+?lbHandle); List
其它菜單操作類似,在此不進(jìn)行闡述。
接下來是Web端
1.瀏覽到主頁
webBrowser1.Navigate("https://xxxxxxxxx/xxxx");
2.通過HtmlElementCollection解釋并模擬點(diǎn)擊
//查找,在input下的j_id_id23:j_id_id381 HtmlElementCollection?link?=?this.webBrowser1.Document.GetElementsByTagName("input").GetElementsByName("j_id_id23:j_id_id381"); for?(int?i?=?0;?i?
技術(shù)難點(diǎn)都搞定了,就弄出第1版成品。
由于第1版只有2天的開發(fā)時間,其實后續(xù)可以利用DevCon對設(shè)備進(jìn)行禁用/啟用,這樣可以一次性插好幾個讀卡器,然后自動實現(xiàn)批量(將全部禁用,做那一個時就開那個)。
Win32API初嘗到此結(jié)束。其實AI的實際產(chǎn)品經(jīng)常要與硬件打交道(像攝像頭、語音輸入之類),作為一位主管不僅僅是懂得算法、調(diào)參,還得懂得整個產(chǎn)品涉及的技術(shù)進(jìn)行把控,關(guān)鍵時刻自己要出手。
爬蟲
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。