




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、 在編寫工具程序以及系統(tǒng)管理程序的時候。常常需要獲取某個進程的主窗口以及創(chuàng)建此進程的程序名。獲取主窗口的目的是向窗口發(fā)送各種消息。獲取啟動進程的程序名可以控制對進程的操作。但是有些進程往往有多個主窗口。你要的是哪一個主窗口呢?如果你用過Outlook程序,你就會發(fā)現(xiàn)它有多個主窗口,一個窗口列出收件箱和其它文件夾。如果你打開e-mail,便會有另外一個窗口顯示信息。它們都是沒有父窗口(或者說宿主窗口)的主窗口。運行一下Spy程序,你甚至?xí)l(fā)現(xiàn)它們的窗口類名都相同:rctrl_renwnd32。資源管理器(Explorer.exe)也有不止一個主窗口。如圖一所示,資源管理器
2、有兩個主窗口。一般來講,想要獲取主窗口,憑窗口的式樣或類名,你沒有什么辦法知道哪一個窗口是真正意義上的主窗口。首先我們討論如何從多個窗口中獲取主窗口?其實很容易。利用兩個API函數(shù)便可以實現(xiàn)。這兩個API是 EnumWindows 和 GetWindowThreadProcessId。如果你對這兩個函數(shù)不熟悉,不要怕,本文提供了一個C+類來對這兩個API進行封裝。這個類叫 CMainWindowIterator,用它可以枚舉某個進程(已知進程ID)的所有主窗口。這正是我們想要的東西。其使用方法如下:DWORD pid = / 已知某個進程的IDCMainWindowIterator itw(p
3、id);for (HWND hwnd = itw.First(); hwnd; hwnd=itw.Next() / do something 就這么簡單,CMainWindowIterator派生于一個更通用的類:CWindowIterator,CWindowIterator負(fù)責(zé)將:EnumWindows函數(shù)打包以隱藏回調(diào)細(xì)節(jié)。它有一個虛擬函數(shù)OnWindow,你可以在派生類中重寫這個函數(shù),從而可以用任何方式來枚舉窗口。CMainWindowIterator就是重寫了OnWindow函數(shù),讓它只獲取屬于某個給定進程的主窗口: / (在構(gòu)造函數(shù)中設(shè)置m_pi
4、d)BOOL CMainWindowIterator:OnWindow(HWND hwnd) if (GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE) DWORD pidwin; GetWindowThreadProcessId(hwnd, &pidwin); if (pidwin=m_pid) return TRUE; return FALSE;這兩個類的定義如下:(對應(yīng)的文件是 EnumProc.h 和 EnumProc.cpp) / 這個類主要是封裝:EnumWindows,列舉頂層窗口/class CWindowIterator p
5、rotected:HWND*m_hwnds;/ 隸屬于某個進程PID窗口句柄數(shù)組DWORD m_nAlloc;/ 數(shù)組大小DWORD m_count;/ 找到的窗口句柄數(shù)DWORD m_current;/ 當(dāng)前的窗口句柄static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lp);/ 虛擬枚舉函數(shù)virtual BOOL OnEnumProc(HWND hwnd);/ 在派生中改寫此函數(shù)來過濾不同種類的窗口virtual BOOL OnWindow(HWND hwnd) return TRUE;public:CWindowIterator(DWORD
6、nAlloc=1024);CWindowIterator();DWORD GetCount() return m_count; HWND First();HWND Next() return m_hwnds && m_current <m_count ? m_hwndsm_current+ : NULL;/ 列舉某個進程的頂層窗口/class CMainWindowIterator : public CWindowIterator protected:DWORD m_pid;/ 進程IDvirtual BOOL OnWindow(HWND hwnd);public:CMa
7、inWindowIterator(DWORD pid, DWORD nAlloc=1024);CMainWindowIterator();圖一是用上述C+類編寫的一個控制臺程序lp.exe的輸出畫面。最后兩欄分別是對應(yīng)進程的“窗口句柄”和“類名/窗口標(biāo)題”。其命令行開關(guān)“/ct”表示列出窗口類名(c)和窗口標(biāo)題(t)。圖一 一般來講,如果隸屬于某個進程的窗口沒有可見的父窗口,那么這個窗口就可以認(rèn)為是此進程的主窗口。對WS_VISIBLE的檢查很重要,因為有些應(yīng)用創(chuàng)建多個不可見的頂層窗口。關(guān)于CMainWindowIterator類的使用細(xì)節(jié)請參見本文的例子源
8、代碼。 接下來我們來討論如何獲取創(chuàng)建進程的程序文件名。有人用各種方法嘗試過,比如:GetModuleFileName,GetModuleInstance 和 GetModuleHandle,好像都不行。為什么呢?其實,方法是沒錯,但調(diào)用這些函數(shù)得到的只是當(dāng)前正在運行的這個進程已經(jīng)加載的模塊名(modules),不能用于獲取其它進程所加載的模塊。因此,必須想別的辦法,首先要考慮兩種情況,一種是如果你寫的程序在Windows NT,Windows 2000,Windows XP環(huán)境運行,則可以使用PSAPI,這是一個Windows操作系統(tǒng)中比較新的DLL,利用其中輸出的API函數(shù)可以獲取進程和模塊
9、的詳細(xì)信息。另一種是如果你寫的程序在Windows 9x或者Windows Me中運行,則必須借助于ToolHelp,限于本文的篇幅,我在這里不介紹如何使用ToolHelp,如果你感興趣的話可以參考,MSDN的技術(shù)支持文章Q175030,題目為“如何在Win32中枚舉應(yīng)用程序”。 PSAPI中有一個函數(shù)是GetModuleFileNameEx。它通過某個進程和模塊句柄作為參數(shù)來獲得模塊名。那么對于某個進程來說,你怎么知道哪個模塊是啟動進程的執(zhí)行文件呢呢?PSAPI中的另一個函數(shù)EnumProcessModules將某個進程中所有模塊的模塊句柄填充到一個數(shù)組中
10、。這個數(shù)組的第一個元素便是主模塊的句柄,所以你用下面的代碼來得到第一個HMODULE: DWORD count;HMODULE hm1;EnumProcessModules(hProcess, hm, 1, &count); 然后調(diào)用GetModuleFileNameEx。實際上從前面的圖一中可以看到,在lp.exe程序中我們已經(jīng)實現(xiàn)了羅列進程及其對應(yīng)的模塊名。程序的實現(xiàn)細(xì)節(jié)中還用到了PSAPI輸出的API函數(shù)EnumProcesses來枚舉所有運行進程,為了對具體的細(xì)節(jié)進行封裝,我如法炮制編寫了與CWindowIterator 和CMainWindowIterator類似的兩個C+類
11、:CProcessIterator 和 CProcessModuleIterator ,它們分別對EnumProcesses 和EnumProcessModules API函數(shù)進行了封裝。有了這兩個打包類,一切都變得如此簡單。 CProcessIterator itp;for (DWORD pid=itp.First(); pid; pid=itp.Next() / 處理每一個進程下面是獲取創(chuàng)建進程的EXE文件名的方法: CProcessModuleIterator itm(pid);HMODULE hModule = itm.First(); / .EXETCHAR modname_MAX_
12、PATH;GetModuleBaseName(itm.GetProcessHandle(), hModule, modname, _MAX_PATH); 因為lp顯示出來的并不是一個含全路徑的模塊文件名,所以我用另外一個PSAPI函數(shù)GetModuleBaseName來代替GetModuleFileNameEx從而獲取全路徑名。此外,由于CProcessModuleIterator自己會打開進程枚舉模塊,所以不必調(diào)用OpenProcess。用CProcessModuleIterator:GetProcessHandle可以得到已打開進程的句柄。lp程序還用C
13、MainWindowIterator來顯示每個特定進程的所有主窗口。下面是CProcessIterator 和 CProcessModuleIterator的定義: / 進程列舉類 - 列舉出系統(tǒng)中的所有進程,但總是跳過第一個PID=0的進程,即空閑進程(IDLE)/class CProcessIterator protected:DWORD*m_pids;/ 包含進程IDs的數(shù)祖DWORDm_count;/ 數(shù)組大小DWORDm_current;/ 當(dāng)前數(shù)組項public:CProcessIterator();CProcessIterator();DWORD GetCount() retur
14、n m_count; DWORD First();DWORD Next() return m_pids && m_current <m_count ? m_pidsm_current+ : 0;/ 列舉某個進程的模塊,第一個模塊就是創(chuàng)建此進程的主exe程序/class CProcessModuleIterator protected:HANDLEm_hProcess;/ 進程句柄HMODULE*m_hModules;/ 模塊句柄數(shù)組DWORDm_count;/ 數(shù)組大小DWORDm_current;/ 當(dāng)前模塊的句柄public:CProcessModuleIterator(DWO
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 有限合伙企業(yè)轉(zhuǎn)讓合同模板
- 土建員工合同范例
- 社交電商用戶行為與消費決策關(guān)聯(lián)性-深度研究
- 地方角鋼銷售合同范本
- 圍欄拆除合同范本
- 虛擬賽事營銷策略-深度研究
- 土方格柵合同范本
- 洗滌劑產(chǎn)業(yè)鏈上下游協(xié)同-深度研究
- 合同履行保證合同范本
- 2025年協(xié)同策劃創(chuàng)建有限責(zé)任公司的合同樣本官方
- 師德師風(fēng)培訓(xùn)筆記
- 養(yǎng)老護理練習(xí)題庫(含答案)
- 醫(yī)療廢物相關(guān)法律法規(guī)培訓(xùn)課件
- 特種設(shè)備生產(chǎn)和充裝單位許可規(guī)則
- 女生自尊自愛知識講座
- 2025年兒童青少年近視防控白皮書
- 小學(xué)生春季傳染病預(yù)防
- deepseek在智慧城市建設(shè)中的應(yīng)用前景
- 2024黑龍江公務(wù)員考試【A類、B類、省直、筆試】四套真題及答案
- 2025年九江職業(yè)大學(xué)高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- 第七章 力 達標(biāo)測試卷(含答案)2024-2025學(xué)年度人教版物理八年級下冊
評論
0/150
提交評論