通过进程号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;                            	} 	}

第三种方法相对来讲比较简单一些,但编译时一定要注意,三个头文件,不能少。

点这里可以跳转到人工智能网站

发表评论