在編寫工具程序以及系統(tǒng)管理程序的時(shí)候常常需要獲取某_第1頁(yè)
在編寫工具程序以及系統(tǒng)管理程序的時(shí)候常常需要獲取某_第2頁(yè)
在編寫工具程序以及系統(tǒng)管理程序的時(shí)候常常需要獲取某_第3頁(yè)
在編寫工具程序以及系統(tǒng)管理程序的時(shí)候常常需要獲取某_第4頁(yè)
在編寫工具程序以及系統(tǒng)管理程序的時(shí)候常常需要獲取某_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、   在編寫工具程序以及系統(tǒng)管理程序的時(shí)候。常常需要獲取某個(gè)進(jìn)程的主窗口以及創(chuàng)建此進(jìn)程的程序名。獲取主窗口的目的是向窗口發(fā)送各種消息。獲取啟動(dòng)進(jìn)程的程序名可以控制對(duì)進(jìn)程的操作。但是有些進(jìn)程往往有多個(gè)主窗口。你要的是哪一個(gè)主窗口呢?如果你用過(guò)Outlook程序,你就會(huì)發(fā)現(xiàn)它有多個(gè)主窗口,一個(gè)窗口列出收件箱和其它文件夾。如果你打開(kāi)e-mail,便會(huì)有另外一個(gè)窗口顯示信息。它們都是沒(méi)有父窗口(或者說(shuō)宿主窗口)的主窗口。運(yùn)行一下Spy程序,你甚至?xí)l(fā)現(xiàn)它們的窗口類名都相同:rctrl_renwnd32。資源管理器(Explorer.exe)也有不止一個(gè)主窗口。如圖一所示,資源管理器

2、有兩個(gè)主窗口。一般來(lái)講,想要獲取主窗口,憑窗口的式樣或類名,你沒(méi)有什么辦法知道哪一個(gè)窗口是真正意義上的主窗口。首先我們討論如何從多個(gè)窗口中獲取主窗口?其實(shí)很容易。利用兩個(gè)API函數(shù)便可以實(shí)現(xiàn)。這兩個(gè)API是 EnumWindows 和 GetWindowThreadProcessId。如果你對(duì)這兩個(gè)函數(shù)不熟悉,不要怕,本文提供了一個(gè)C+類來(lái)對(duì)這兩個(gè)API進(jìn)行封裝。這個(gè)類叫 CMainWindowIterator,用它可以枚舉某個(gè)進(jìn)程(已知進(jìn)程ID)的所有主窗口。這正是我們想要的東西。其使用方法如下:DWORD pid = / 已知某個(gè)進(jìn)程的IDCMainWindowIterator itw(p

3、id);for (HWND hwnd = itw.First(); hwnd; hwnd=itw.Next() / do something     就這么簡(jiǎn)單,CMainWindowIterator派生于一個(gè)更通用的類:CWindowIterator,CWindowIterator負(fù)責(zé)將:EnumWindows函數(shù)打包以隱藏回調(diào)細(xì)節(jié)。它有一個(gè)虛擬函數(shù)OnWindow,你可以在派生類中重寫這個(gè)函數(shù),從而可以用任何方式來(lái)枚舉窗口。CMainWindowIterator就是重寫了OnWindow函數(shù),讓它只獲取屬于某個(gè)給定進(jìn)程的主窗口: / (在構(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;這兩個(gè)類的定義如下:(對(duì)應(yīng)的文件是 EnumProc.h 和 EnumProc.cpp) / 這個(gè)類主要是封裝:EnumWindows,列舉頂層窗口/class CWindowIterator p

5、rotected:HWND*m_hwnds;/ 隸屬于某個(gè)進(jìn)程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ù)來(lái)過(guò)濾不同種類的窗口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;/ 列舉某個(gè)進(jìn)程的頂層窗口/class CMainWindowIterator : public CWindowIterator protected:DWORD m_pid;/ 進(jìn)程IDvirtual BOOL OnWindow(HWND hwnd);public:CMa

7、inWindowIterator(DWORD pid, DWORD nAlloc=1024);CMainWindowIterator();圖一是用上述C+類編寫的一個(gè)控制臺(tái)程序lp.exe的輸出畫面。最后兩欄分別是對(duì)應(yīng)進(jìn)程的“窗口句柄”和“類名/窗口標(biāo)題”。其命令行開(kāi)關(guān)“/ct”表示列出窗口類名(c)和窗口標(biāo)題(t)。圖一    一般來(lái)講,如果隸屬于某個(gè)進(jìn)程的窗口沒(méi)有可見(jiàn)的父窗口,那么這個(gè)窗口就可以認(rèn)為是此進(jìn)程的主窗口。對(duì)WS_VISIBLE的檢查很重要,因?yàn)橛行?yīng)用創(chuàng)建多個(gè)不可見(jiàn)的頂層窗口。關(guān)于CMainWindowIterator類的使用細(xì)節(jié)請(qǐng)參見(jiàn)本文的例子源

8、代碼。 接下來(lái)我們來(lái)討論如何獲取創(chuàng)建進(jìn)程的程序文件名。有人用各種方法嘗試過(guò),比如:GetModuleFileName,GetModuleInstance 和 GetModuleHandle,好像都不行。為什么呢?其實(shí),方法是沒(méi)錯(cuò),但調(diào)用這些函數(shù)得到的只是當(dāng)前正在運(yùn)行的這個(gè)進(jìn)程已經(jīng)加載的模塊名(modules),不能用于獲取其它進(jìn)程所加載的模塊。因此,必須想別的辦法,首先要考慮兩種情況,一種是如果你寫的程序在Windows NT,Windows 2000,Windows XP環(huán)境運(yùn)行,則可以使用PSAPI,這是一個(gè)Windows操作系統(tǒng)中比較新的DLL,利用其中輸出的API函數(shù)可以獲取進(jìn)程和模塊

9、的詳細(xì)信息。另一種是如果你寫的程序在Windows 9x或者Windows Me中運(yùn)行,則必須借助于ToolHelp,限于本文的篇幅,我在這里不介紹如何使用ToolHelp,如果你感興趣的話可以參考,MSDN的技術(shù)支持文章Q175030,題目為“如何在Win32中枚舉應(yīng)用程序”。    PSAPI中有一個(gè)函數(shù)是GetModuleFileNameEx。它通過(guò)某個(gè)進(jìn)程和模塊句柄作為參數(shù)來(lái)獲得模塊名。那么對(duì)于某個(gè)進(jìn)程來(lái)說(shuō),你怎么知道哪個(gè)模塊是啟動(dòng)進(jìn)程的執(zhí)行文件呢呢?PSAPI中的另一個(gè)函數(shù)EnumProcessModules將某個(gè)進(jìn)程中所有模塊的模塊句柄填充到一個(gè)數(shù)組中

10、。這個(gè)數(shù)組的第一個(gè)元素便是主模塊的句柄,所以你用下面的代碼來(lái)得到第一個(gè)HMODULE: DWORD count;HMODULE hm1;EnumProcessModules(hProcess, hm, 1, &count); 然后調(diào)用GetModuleFileNameEx。實(shí)際上從前面的圖一中可以看到,在lp.exe程序中我們已經(jīng)實(shí)現(xiàn)了羅列進(jìn)程及其對(duì)應(yīng)的模塊名。程序的實(shí)現(xiàn)細(xì)節(jié)中還用到了PSAPI輸出的API函數(shù)EnumProcesses來(lái)枚舉所有運(yùn)行進(jìn)程,為了對(duì)具體的細(xì)節(jié)進(jìn)行封裝,我如法炮制編寫了與CWindowIterator 和CMainWindowIterator類似的兩個(gè)C+類

11、:CProcessIterator 和 CProcessModuleIterator ,它們分別對(duì)EnumProcesses 和EnumProcessModules API函數(shù)進(jìn)行了封裝。有了這兩個(gè)打包類,一切都變得如此簡(jiǎn)單。 CProcessIterator itp;for (DWORD pid=itp.First(); pid; pid=itp.Next() / 處理每一個(gè)進(jìn)程下面是獲取創(chuàng)建進(jìn)程的EXE文件名的方法: CProcessModuleIterator itm(pid);HMODULE hModule = itm.First(); / .EXETCHAR modname_MAX_

12、PATH;GetModuleBaseName(itm.GetProcessHandle(), hModule, modname, _MAX_PATH);    因?yàn)閘p顯示出來(lái)的并不是一個(gè)含全路徑的模塊文件名,所以我用另外一個(gè)PSAPI函數(shù)GetModuleBaseName來(lái)代替GetModuleFileNameEx從而獲取全路徑名。此外,由于CProcessModuleIterator自己會(huì)打開(kāi)進(jìn)程枚舉模塊,所以不必調(diào)用OpenProcess。用CProcessModuleIterator:GetProcessHandle可以得到已打開(kāi)進(jìn)程的句柄。lp程序還用C

13、MainWindowIterator來(lái)顯示每個(gè)特定進(jìn)程的所有主窗口。下面是CProcessIterator 和 CProcessModuleIterator的定義: / 進(jìn)程列舉類 - 列舉出系統(tǒng)中的所有進(jìn)程,但總是跳過(guò)第一個(gè)PID=0的進(jìn)程,即空閑進(jìn)程(IDLE)/class CProcessIterator protected:DWORD*m_pids;/ 包含進(jìn)程IDs的數(shù)祖DWORDm_count;/ 數(shù)組大小DWORDm_current;/ 當(dāng)前數(shù)組項(xiàng)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;/ 列舉某個(gè)進(jìn)程的模塊,第一個(gè)模塊就是創(chuàng)建此進(jìn)程的主exe程序/class CProcessModuleIterator protected:HANDLEm_hProcess;/ 進(jìn)程句柄HMODULE*m_hModules;/ 模塊句柄數(shù)組DWORDm_count;/ 數(shù)組大小DWORDm_current;/ 當(dāng)前模塊的句柄public:CProcessModuleIterator(DWO

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論