1. 程式人生 > >通過程序號ID獲得視窗的控制代碼

通過程序號ID獲得視窗的控制代碼


2012年-09月-05日

通過程序號的ID獲得視窗的控制代碼

    最近幾天,工作的需要,打算實現將別人編譯好的exe程式,通過自己的程式去呼叫,然後根據程式中得到的ID號,去得到此程序執行建立的視窗控制代碼,在網上搜了一段時間,得到了不少啟示,再結合自己的實際環境,整合出了以下三種方法,以下將針對每一種方法做出簡單的介紹同時給出關鍵程式碼,本人所採用的平臺為vc6.0,英文企業版。

     在介紹方法之前,首先需要介紹下,在自己的程式中執行編譯好的exe方法,網上搜搜會得到不少啟示,主要就是三個API函式(WinExec,ShellExecute ,CreateProcess,可以實現呼叫其他程式的要求,其中以WinExec最為簡單,ShellExecute比WinExec靈活一些,CreateProcess最為複雜。

)   本人在實際的開發環境中採用的是  CreateProcess 方法,至於該方法各引數的詳細說明與使用,請參考msdn上的講解。以下是我執行exe的程式碼。

    STARTUPINFO si;  //啟動程序引數
    PROCESS_INFORMATION pi;  //程序資訊結構
	
    
    LPSTR FileName=sProcessName.GetBuffer(0); //全路徑
    
    //結構清零
    ZeroMemory(&si,sizeof(si));  //此引數必須清零
    ZeroMemory(&pi,sizeof(pi));  //此引數必須清零
    si.dwFlags =STARTF_USESHOWWINDOW;//隱藏建立的視窗
    si.wShowWindow=SW_HIDE;//隱藏建立的視窗

    //建立程序
    BOOL flag=CreateProcess(
        FileName,  //建立的程序,
       NULL,
        NULL,
        NULL,
        false,
        0,
        NULL,
        NULL,
        &si,
        &pi);
    if(flag==0)
    {
        return;
    }
 		
    //等待程序,直到其退出。
    WaitForSingleObject(pi.hProcess,INFINITE);
	
    //關閉控制代碼
     BOOL flag1=CloseHandle(pi.hThread );
    BOOL flag2=CloseHandle(pi.hProcess );
    根據得到的pi結構,可以得到執行的exe的程序號。
第一種方法:

    利用FindWindow()api函式,此函式宣告為:

HWND FindWindow(
  LPCTSTR lpClassName,  // class name
  LPCTSTR lpWindowName  // window name
);

   使用該api前提,是需要知道建立視窗的類名或者視窗的標題,一般來說,視窗的類名師不容易得到,一般用的引數是視窗的標題。此函式返回值就是視窗的控制代碼。此方法比較簡單,這裡不再贅述。

第二種方法:

  利用EnumWindows與GetWindowThreadProcessId 這兩個API函式。具體實現的程式碼如下:

typedef struct EnumFunArg
{	
	HWND      hWnd;
	DWORD    dwProcessId;	
}EnumFunArg,*LPEnumFunArg;
BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
{
	
	EnumFunArg  *pArg = (LPEnumFunArg)lParam;	
	DWORD  processId;
	GetWindowThreadProcessId(hwnd, &processId);    
	if( processId == pArg->dwProcessId)	
	{	
		pArg->hWnd = hwnd;
		return TRUE;	
	}
	return FALSE;	
}HWND ReturnWnd(DWORD processID)
{
   HWND retWnd=NULL;  
   EnumFunArg wi;  
    wi.dwProcessId   =processID;  
    wi.hWnd   =  NULL;  
    EnumWindows(lpEnumFunc,(LPARAM)&wi);
   if(wi.hWnd){     retWnd=wi.hWnd;
   }   return retWnd;
}

將此部分程式碼新增到程式中,直接呼叫相關的函式,就能得到視窗的控制代碼。

第三種方法:

利用GUITHREADINFO以及GetGUIThreadInfo。具體的程式碼如下:

#include <winuser.h>
#include <winable.h>
#include <windows.h>
	HWND g_Hwnd=null;
  	GUITHREADINFO gui;
	WaitForInputIdle(pi.hProcess,INFINITE);
 	FillMemory(&gui,sizeof(GUITHREADINFO),0);
 	gui.cbSize=sizeof(GUITHREADINFO); 
	
	if (GetGUIThreadInfo(pi.dwThreadId,&gui))
	{
 		//DWORD errorcode=GetLastError();
		if (gui.hwndActive	){
			g_Hwnd= gui.hwndActive;                  
          	}

	}

第三種方法相對來講比較簡單一些,但編譯時一定要注意,三個標頭檔案,不能少。