通过进程号ID获得窗口的句柄 .

2012年-09月-05日

通过进程号的ID获得窗口的句柄

    最近几天,工作的需要,打算实现将别人编译好的exe程序,通过自己的程序去调用,然后根据程序中得到的ID号,去得到此进程运行创建的窗口句柄,在网上搜了一段时间,得到了不少启示,再结合自己的实际环境,整合出了以下三种方法,以下将针对每一种方法做出简单的介绍同时给出关键代码,本人所采用的平台为vc6.0,英文企业版。

     在介绍方法之前,首先需要介绍下,在自己的程序中运行编译好的exe方法,网上搜搜会得到不少启示,主要就是三个API函数(WinExec,ShellExecute ,CreateProcess,可以实现调用其他程序的要求,其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂。)   本人在实际的开发环境中采用的是  CreateProcess 方法,至于该方法各参数的详细说明与使用,请参考msdn上的讲解。以下是我运行exe的代码。

  1.   
</pre><p align="left"> </p><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><strong>[cpp]</strong> <a target=_blank class="ViewSource" title="view plain" href="http://blog.csdn.net/wawj522527/article/details/7946656#">view plain</a><a target=_blank class="CopyToClipboard" title="copy" href="http://blog.csdn.net/wawj522527/article/details/7946656#">copy</a><a target=_blank class="PrintSource" title="print" href="http://blog.csdn.net/wawj522527/article/details/7946656#">print</a><a target=_blank class="About" title="?" href="http://blog.csdn.net/wawj522527/article/details/7946656#">?</a></div></div><ol class="dp-cpp"><li class="alt"><span><span>STARTUPINFO si;  </span><span class="comment">//启动进程参数 </span><span>  </span></span></li><li><span>PROCESS_INFORMATION pi;  </span><span class="comment">//进程信息结构 </span><span>  </span></li><li class="alt"><span>  </span></li><li><span>  </span></li><li class="alt"><span></span><span class="datatypes">LPSTR</span><span> FileName=sProcessName.GetBuffer(0); </span><span class="comment">//全路径 </span><span>  </span></li><li><span>  </span></li><li class="alt"><span></span><span class="comment">//结构清零 </span><span>  </span></li><li><span>ZeroMemory(&si,</span><span class="keyword">sizeof</span><span>(si));  </span><span class="comment">//此参数必须清零 </span><span>  </span></li><li class="alt"><span>ZeroMemory(&pi,</span><span class="keyword">sizeof</span><span>(pi));  </span><span class="comment">//此参数必须清零 </span><span>  </span></li><li><span>si.dwFlags =STARTF_USESHOWWINDOW;</span><span class="comment">//隐藏创建的窗口 </span><span>  </span></li><li class="alt"><span>si.wShowWindow=SW_HIDE;</span><span class="comment">//隐藏创建的窗口 </span><span>  </span></li><li><span>  </span></li><li class="alt"><span></span><span class="comment">//创建进程 </span><span>  </span></li><li><span></span><span class="datatypes">BOOL</span><span> flag=CreateProcess(  </span></li><li class="alt"><span>    FileName,  </span><span class="comment">//创建的进程, </span><span>  </span></li><li><span>   NULL,  </span></li><li class="alt"><span>    NULL,  </span></li><li><span>    NULL,  </span></li><li class="alt"><span>    </span><span class="keyword">false</span><span>,  </span></li><li><span>    0,  </span></li><li class="alt"><span>    NULL,  </span></li><li><span>    NULL,  </span></li><li class="alt"><span>    &si,  </span></li><li><span>    &pi);  </span></li><li class="alt"><span></span><span class="keyword">if</span><span>(flag==0)  </span></li><li><span>{  </span></li><li class="alt"><span>    </span><span class="keyword">return</span><span>;  </span></li><li><span>}  </span></li><li class="alt"><span>  </span></li><li><span></span><span class="comment">//等待进程,直到其退出。 </span><span>  </span></li><li class="alt"><span>WaitForSingleObject(pi.hProcess,INFINITE);  </span></li><li><span>  </span></li><li class="alt"><span></span><span class="comment">//关闭句柄 </span><span>  </span></li><li><span> </span><span class="datatypes">BOOL</span><span> flag1=CloseHandle(pi.hThread );  </span></li><li class="alt"><span></span><span class="datatypes">BOOL</span><span> flag2=CloseHandle(pi.hProcess );  </span></li></ol></div><pre style="DISPLAY: none" class="cpp" name="code">    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 );


  1. 根据得到的pi结构,可以得到运行的exe的进程号。  
  2. 法:  
    根据得到的pi结构,可以得到运行的exe的进程号。
第一种方法:

    利用FindWindow()api函数,此函数声明为:

  

  1. HWND FindWindow(  
  2.   LPCTSTR lpClassName,  // class name  
  3.   LPCTSTR lpWindowName  // window name  
  4. );  
HWND FindWindow(
  LPCTSTR lpClassName,  // class name
  LPCTSTR lpWindowName  // window name
);

   使用该api前提,是需要知道创建窗口的类名或者窗口的标题,一般来说,窗口的类名师不容易得到,一般用的参数是窗口的标题。此函数返回值就是窗口的句柄。此方法比较简单,这里不再赘述。

第二种方法:

  利用EnumWindows与GetWindowThreadProcessId 这两个API函数。具体实现的代码如下:

  1. typedef struct EnumFunArg  
  2. {     
  3.     HWND      hWnd;  
  4.     DWORD    dwProcessId;     
  5. }EnumFunArg,*LPEnumFunArg;  
  6. BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)  
  7. {  
  8.       
  9.     EnumFunArg  *pArg = (LPEnumFunArg)lParam;     
  10.     DWORD  processId;  
  11.     GetWindowThreadProcessId(hwnd, &processId);      
  12.     if( processId == pArg->dwProcessId)    
  13.     {     
  14.         pArg->hWnd = hwnd;  
  15.         return TRUE;      
  16.     }  
  17.     return FALSE;     
  18. }HWND ReturnWnd(DWORD processID)  
  19. {  
  20.    HWND retWnd=NULL;    
  21.    EnumFunArg wi;    
  22.     wi.dwProcessId   =processID;    
  23.     wi.hWnd   =  NULL;    
  24.     EnumWindows(lpEnumFunc,(LPARAM)&wi);  
  25.    if(wi.hWnd){     retWnd=wi.hWnd;  
  26.    }   return retWnd;  
  27. }  
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。具体的代码如下:

  1. #include <winuser.h>   
  2. #include <winable.h>   
  3. #include <windows.h>   
  4.     HWND g_Hwnd=null;  
  5.     GUITHREADINFO gui;  
  6.     WaitForInputIdle(pi.hProcess,INFINITE);  
  7.     FillMemory(&gui,sizeof(GUITHREADINFO),0);  
  8.     gui.cbSize=sizeof(GUITHREADINFO);   
  9.       
  10.     if (GetGUIThreadInfo(pi.dwThreadId,&gui))  
  11.     {  
  12.         //DWORD errorcode=GetLastError();   
  13.         if (gui.hwndActive  ){  
  14.             g_Hwnd= gui.hwndActive;                    
  15.             }  
  16.   
  17.     }  
#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;                  
          	}

	}

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

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过进程ID获取窗口可以使用Windows API中的EnumWindows函数结合GetWindowThreadProcessId函数来实现。 EnumWindows函数是用于枚举所有顶级窗口的函数,它会将每个窗口的句传入一个回调函数中进行处理。而GetWindowThreadProcessId函数用于获取给定窗口进程ID。 首先,我们可以定义一个回调函数来处理EnumWindows函数传入的窗口。在回调函数中,我们需要利用GetWindowThreadProcessId函数来获取每个窗口进程ID,并将其与我们想要获取的目标进程ID进行比较。当匹配到目标进程ID时,我们可以将该窗口保存下来。 以下是一个简单的示例代码: ```c++ #include <iostream> #include <windows.h> DWORD targetProcessId; HWND targetWindowHandle = nullptr; BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { DWORD currentProcessId; GetWindowThreadProcessId(hwnd, &currentProcessId); if (currentProcessId == targetProcessId) { targetWindowHandle = hwnd; return FALSE; // 返回FALSE以停止枚举 } return TRUE; // 返回TRUE以继续枚举 } HWND GetWindowHandleByProcessId(DWORD processId) { targetProcessId = processId; EnumWindows(EnumWindowsProc, 0); return targetWindowHandle; } int main() { DWORD processId = 1234; // 目标进程ID HWND windowHandle = GetWindowHandleByProcessId(processId); if (windowHandle != nullptr) { std::cout << "窗口: " << windowHandle << std::endl; } else { std::cout << "未找到匹配的窗口" << std::endl; } return 0; } ``` 在示例代码中,我们定义了一个名为`GetWindowHandleByProcessId`的函数来实现通过进程ID获取窗口的功能。该函数接受一个参数`processId`,即目标进程ID。在函数内部,我们首先将目标进程ID保存起来,然后调用`EnumWindows`函数来枚举所有顶级窗口。在回调函数`EnumWindowsProc`中,我们使用`GetWindowThreadProcessId`函数获取当前窗口进程ID并与目标进程ID进行比较。如果匹配成功,则将当前窗口保存下来。最后,在`main`函数中,我们可以调用`GetWindowHandleByProcessId`函数来获取目标进程窗口,并输出结果。 需要注意的是,以上示例代码仅演示了通过进程ID获取单个窗口的方法。如果目标进程存在多个窗口,您可能需要进一步定义您的需求来确定具体需要获取哪个窗口的句

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值