MJ天上飞 2004-3-26 12:12
<open> windows 怎样通过一个进程ID(或句柄)获得它的窗口句柄
RT,这两天搞得我头大. [img]http://bbs.tongji.net/images/smiles/stupid_smile.gif[/img]
MJ天上飞 2004-3-26 12:27
Re:<open> windows 怎样通过一个进程ID(或句柄)获得它的窗口句柄
主要是不要用两个循环,程序不好看也低效.
omale 2004-3-26 16:25
Re:<open> windows 怎样通过一个进程ID(或句柄)获得它的窗口句柄
下面是一个sample,希望能对你有帮助。
一个进程可以拥有很多主窗口,也可以不拥有主窗口,所以这样的函数是不存在的,所幸的是,相反的函数是有的。所以我们可以调用EnumWindows来判断所有的窗口是否属于这个进程。
typedef struct tagWNDINFO
{
DWORD dwProcessId;
HWND hWnd;
} WNDINFO, *LPWNDINFO;
BOOL CALLBACK YourEnumProc(HWND hWnd,LPARAM lParam)
{
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
LPWNDINFO pInfo = (LPWNDINFO)lParam;
if(dwProcessId == pInfo->dwProcessId)
{
pInfo->hWnd = hWnd;
return FALSE;
}
return TRUE;
}
HWND GetProcessMainWnd(DWORD dwProcessId)
{
WNDINFO wi;
wi.dwProcessId = dwProcessId;
wi.hWnd = NULL;
EnumWindows(YourEnumProc,(LPARAM)&wi);
return wi.hWnd;
}
如果这个进程没有窗口,函数返回NULL
OwnWaterloo 2008-10-7 23:05
.Net 中有这样的功能 …
直接贴代码了 ……
[quote]
using System;
using System.Collections.Generic;
using System.Text;
using System.[color=red]Diagnostics[/color];
using System.Runtime.InteropServices;
namespace GetMainWnd
{
class Program
{
[DllImport("user32.dll", EntryPoint = "GetWindowText")]
static extern Int32 GetWindowText(IntPtr handle, StringBuilder sb, Int32 c);
static void Main(string[] args)
{
for (;;)
{
try {
Console.Write("input PID: ");
string s = Console.ReadLine();
if ("exit" == s)
break;
int id = int.Parse(s);
Process p = Process.[color=red]GetProcessById[/color](id);
p.WaitForInputIdle();
IntPtr handle = (IntPtr) p.[color=red]MainWindowHandle[/color].ToInt32();
StringBuilder sb = new StringBuilder(80);
GetWindowText(handle, sb, 80);
Console.WriteLine("PID=" + id + "\nHandle=" + handle
+ "\nTitle=\"" + sb + "\"");
}
catch (Exception e) {
Console.WriteLine("exception: " + e);
}
}
}
}
}
[/quote]
不管GetProcessById 是线性还是常数时间(有可能内部还是做了Enum然后比较ID)
比较不解的是 MainWindowHandle 这个属性……
什么样的窗口才能被认作一个进程的主窗口?
MFC中到是有一个m_pMainWnd;
但是从WinAPI来说呢?
第1个注册的?
第1个创建的?
处理 WM_DESTROY 时 PostQuitMessage的?
主线程的?
PS:
Process还有一个属性叫 MainWindowTitle 可以直接得到Title …… 可以不用那么麻烦使用PInvoke ……