通過調用Win32 API實現。

public class HewenqiUser32



{

private static Hashtable processWnd = null;

public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);

static HewenqiUser32()


{

if (processWnd == null)


{

processWnd = new Hashtable();

}

}

[DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]

public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);

[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]

public static extern IntPtr GetParent(IntPtr hWnd);

[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]

public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);

[DllImport("user32.dll", EntryPoint = "IsWindow")]

public static extern bool IsWindow(IntPtr hWnd);

[DllImport("kernel32.dll", EntryPoint = "SetLastError")]

public static extern void SetLastError(uint dwErrCode);

public static IntPtr GetCurrentWindowHandle()


{

IntPtr ptrWnd = IntPtr.Zero;

uint uiPid = (uint)Process.GetCurrentProcess().Id; // 當前進程 ID

object objWnd = processWnd[uiPid];

if (objWnd != null)


{

ptrWnd = (IntPtr)objWnd;

if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 從緩存中獲取句柄


{

return ptrWnd;

}

else


{

ptrWnd = IntPtr.Zero;

}

}

bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);

// 枚舉窗口返回 false 並且沒有錯誤號時表明獲取成功

if (!bResult && Marshal.GetLastWin32Error() == 0)


{

objWnd = processWnd[uiPid];

if (objWnd != null)


{

ptrWnd = (IntPtr)objWnd;

}

}

return ptrWnd;

}

private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)


{

uint uiPid = 0;

if (GetParent(hwnd) == IntPtr.Zero)


{

GetWindowThreadProcessId(hwnd, ref uiPid);

if (uiPid == lParam) // 找到進程對應的主窗口句柄


{

processWnd[uiPid] = hwnd; // 把句柄緩存起來

SetLastError(0); // 設置無錯誤

return false; // 返回 false 以終止枚舉窗口

}

}

return true;

}

}
調用HewenqiUser32.GetCurrentWindowHandle()即可返回當前進程的主窗口句柄,如果獲取失敗則返回IntPtr.Zero。
--EOF--
2008年10月7日補充:微軟實現的獲取進程主窗口句柄代碼


Code

public class MyProcess



{

private bool haveMainWindow = false;

private IntPtr mainWindowHandle = IntPtr.Zero;

private int processId = 0;

private delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);

public IntPtr GetMainWindowHandle(int processId)


{

if (!this.haveMainWindow)


{

this.mainWindowHandle = IntPtr.Zero;

this.processId = processId;

EnumThreadWindowsCallback callback = new EnumThreadWindowsCallback(this.EnumWindowsCallback);

EnumWindows(callback, IntPtr.Zero);

GC.KeepAlive(callback);

this.haveMainWindow = true;

}

return this.mainWindowHandle;

}

private bool EnumWindowsCallback(IntPtr handle, IntPtr extraParameter)


{

int num;

GetWindowThreadProcessId(new HandleRef(this, handle), out num);

if ((num == this.processId) && this.IsMainWindow(handle))


{

this.mainWindowHandle = handle;

return false;

}

return true;

}

private bool IsMainWindow(IntPtr handle)


{

return (!(GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero) && IsWindowVisible(new HandleRef(this, handle)));

}

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]

public static extern IntPtr GetWindow(HandleRef hWnd, int uCmd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern bool IsWindowVisible(HandleRef hWnd);

}