楊超
摘要:利用微軟Visual Studio 6.0的工具軟件SPY++找出要操作的運行軟件窗口的圖形樹,最終找出要操作的控件ID,再使用VC++ 6.0建立了一個軟件向該控件發(fā)送消息和模擬要操作控件的事件,最終實現(xiàn)現(xiàn)有軟件功能擴(kuò)充。
關(guān)鍵詞:進(jìn)程;線程;句柄;SPY++
中圖分類號:TP312 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9599 (2013) 01-0189-02
進(jìn)程間通信的主要目的是實現(xiàn)同一計算機(jī)系統(tǒng)內(nèi)部的相互協(xié)作的進(jìn)程之間的數(shù)據(jù)共享與信息交換,由于這些進(jìn)程處于同一軟件和硬件環(huán)境下,利用操作系統(tǒng)提供的編程接口,用戶可以方便地在程序中實現(xiàn)這種通信。
進(jìn)程是裝入內(nèi)存并準(zhǔn)備執(zhí)行的程序,每個進(jìn)程都有自己的虛擬地址空間,由代碼、數(shù)據(jù)以及它可利用的系統(tǒng)資源組成。多進(jìn)程/多線程是Windows操作系統(tǒng)的一個基本特征。Microsoft Win32應(yīng)用編程接口(API)提供了大量支持應(yīng)用程序間數(shù)據(jù)共享和交換的機(jī)制,這些機(jī)制行使的活動稱為進(jìn)程間通信( IPC),通信的目的是在不同進(jìn)程間進(jìn)行數(shù)據(jù)共享和數(shù)據(jù)交換。
如何進(jìn)行進(jìn)程間通信為現(xiàn)有軟件的功能進(jìn)行擴(kuò)充,已成為應(yīng)用開發(fā)中的一個常見問題,下面本文將通過Windows進(jìn)程通信的API來對一個視頻格式軟件——視頻轉(zhuǎn)換大師的多個視頻文件轉(zhuǎn)換的批處理功能進(jìn)行了擴(kuò)充。
1 相關(guān)的技術(shù)
1.1 Spy++功能
Spy++是一個基于Win32的實用工具,它提供系統(tǒng)的進(jìn)程、線程、窗口和窗口消息的圖形視圖。使用 Spy++ 可以執(zhí)行下列操作: 顯示系統(tǒng)對象(包括進(jìn)程、線程和窗口)之間關(guān)系的圖形樹;搜索指定的窗口、線程、進(jìn)程或消息;查看選定的窗口、線程、進(jìn)程或消息的屬性;直接從視圖中選擇窗口、線程、進(jìn)程或消息;通過鼠標(biāo)定位,使用查找程序工具選擇窗口;使用復(fù)雜的消息日志選擇參數(shù)設(shè)置消息選項。 提示使用 Spy++ 時,在許多實例中都可以單擊鼠標(biāo)右鍵顯示常用命令的彈出式菜單。
1.2 有關(guān)Windows API的使用
1.2.1 SendMessage
函數(shù)將指定的消息發(fā)送到指定窗口,由窗口調(diào)用程序,直至窗口程序處理完消息再返回。
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
參數(shù):
hWnd:其窗口程序?qū)⒔邮障⒌拇翱诘木浔?。如果此參?shù)為HWND_BROADCAST,則消息將被發(fā)送到系統(tǒng)中所有頂層窗口。
Msg:指定被發(fā)送的消息。
wParam:指定附加的消息特定信息。
IParam:指定附加的消息特定信息。
返回值:返回值指定消息處理的結(jié)果,依賴于所發(fā)送的消息。
1.2.2 findwindow
HWND FindWindow( LPCSTR lpClassName, LPCSTR lpWindowName );
參數(shù):
lpClassName:指向一個以NULL結(jié)尾的、用來指定類名的字符串或一個可以確定類名字符串的原子。這個原子(一個16bit的值),必須被放置在lpClassName的低位字節(jié)中,lpClassName的高位字節(jié)置零。如果該參數(shù)為NULL時,將會尋找任何與lpWindowName參數(shù)匹配的窗口。
lpWindowName:指向一個以NULL結(jié)尾的、用來指定窗口名(即窗口標(biāo)題)的字符串;如果此參數(shù)為NULL,則匹配所有窗口名。
返回值:
如函數(shù)執(zhí)行成功,則返回相應(yīng)的窗口句柄;執(zhí)行失敗,則返回 NULL 。
1.2.3 CreateThread
函數(shù)原型如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 線程安全屬性
DWORD dwStackSize, // 堆棧大小
LPTHREAD_START_ROUTINE lpStartAddress, // 線程函數(shù)
LPVOID lpParameter, // 線程參數(shù)
DWORD dwCreationFlags, // 線程創(chuàng)建屬性
LPDWORD lpThreadId // 線程ID
);
參數(shù):
lpThreadAttributes:指向SECURITY_ATTRIBUTES型態(tài)的結(jié)構(gòu)的指針。在Windows NT中,NULL使用默認(rèn)安全性,不可以被子線程繼承。
dwStackSize:設(shè)置初始棧的大小,以字節(jié)為單位,如果為0,那么默認(rèn)將使用與調(diào)用該函數(shù)的線程相同的??臻g大小。
lpStartAddress:指向線程函數(shù)的指針,即函數(shù)名稱。
lpParameter:向線程函數(shù)傳遞的參數(shù),是一個指向結(jié)構(gòu)的指針,不需傳遞參數(shù)時,為NULL。
dwCreationFlags:線程標(biāo)志。
lpThreadId:保存新線程的id。
返回值:
函數(shù)成功,返回線程句柄;函數(shù)失敗,返回NULL。
2 軟件實現(xiàn)
2.1 查看指定窗口句柄
運行視頻轉(zhuǎn)換大師軟件,將程序運行到要進(jìn)行的操作界面,然后運行VC++ 6.0中spy++工具軟件,打開spy++窗口中的樹,找到要操作的窗口結(jié)點,點擊旁邊的加號打開窗口樹,選擇相應(yīng)控件句柄進(jìn)行高亮顯示,對要操作控件右鍵點擊屬性,打開屬性窗口。
本次操作將獲取得到文件打開對話框的文件名輸入框的控件ID和打開按鈕的控件ID,現(xiàn)有視頻轉(zhuǎn)換軟件窗口內(nèi)的列表框的ID、文件名輸入框ID和批處理按鈕的ID。
2.2 通過API實現(xiàn)進(jìn)程間通信
通過上面步驟獲取的控件ID號,在程序中使用GetDlgItem方法將控件ID轉(zhuǎn)換為當(dāng)前運行軟件窗口的控件句柄,有了這個句柄就可以通過Message操縱控件,模擬控件的事件,調(diào)用相應(yīng)的事件過程。
2.2.1 加載一個可多選的文件對話框
此過程包含兩個方面的操作,建立一個文件打開對話框?qū)ο?,并以模態(tài)方式打開。打開后,新建一個伺服線程去通過判斷打開對話框的打開按鈕是否存在來取得文件選擇框的內(nèi)容。實現(xiàn)調(diào)用打開對話框的核心內(nèi)容如下:
3 結(jié)束語
跨進(jìn)程通信的方式還有許多, 這些方式中有的需要同一臺電腦,比如文件映射、共享內(nèi)存、郵件槽、剪貼板、動態(tài)數(shù)據(jù)交換、對象連接與嵌入、動態(tài)連接庫、WM_COPYDATA,有的則是要在不同電腦的遠(yuǎn)程通信有管道、遠(yuǎn)程過程調(diào)用、NetBios函數(shù)、Sockets,本文所實現(xiàn)的操作方式屬于前一種方式。
通過上述操作和程序編寫最后達(dá)到視頻轉(zhuǎn)換大師軟件批處理功能的擴(kuò)充,在實際操作中進(jìn)行過最多一次傳送過兩百多個文件,共計轉(zhuǎn)換過四千多個視頻文件操作,并最終將這些文件成功轉(zhuǎn)換。但是在調(diào)試中發(fā)現(xiàn)了一個小問題,即模擬批處理操作按鈕點擊事件時,需模擬兩次,否則就會有文件遺失,不能發(fā)送到指定窗口,兩次模擬后可正確無誤發(fā)送通信。
參考文獻(xiàn):
[1]Windows核心編程(第5版).北京:清華大學(xué)出版社,2008,9:46,128,626.
[2]Spy++的使用方法及下載 [EB/OL].
計算機(jī)光盤軟件與應(yīng)用2013年1期