/// <summary> /// Enumerate windows by calling the specified callback proc for each top-level /// window in the system. If a custom object is specified this object will /// also be passed to the callback proc (allows the callback proc to modify /// state, build a list, etc.) /// </summary> /// <param name="callbackProc">callback proc</param> /// <param name="customParam">custom data</param> public static void EnumerateChildWindows(IntPtr hWndParent, EnumerateChildWindowsDelegate callbackProc, bool visibleOnly, object customParam) { // create delegate that will be used for call to native EnumWindows function // (also create a GC handle to prevent the delegate from being garbage collected // during the call to EnumWindows!) EnumWindowsDelegate enumWindowsProc = new EnumWindowsDelegate(EnumWindowsProc); GCHandle hEnumWindowsProc = GCHandle.Alloc(enumWindowsProc); // Create the custom parameter that will be passed to EnumWindows and allocate // a GC handle for it so we can pass it as the LPARAM to the native EnumWindows EnumWindowsParam param = new EnumWindowsParam(callbackProc, visibleOnly, customParam); GCHandle hParam = GCHandle.Alloc(param); try { // enumerate windows User32.EnumChildWindows(hWndParent, enumWindowsProc, hParam); } finally { // free GC handles used for enumerating windows hEnumWindowsProc.Free(); hParam.Free(); } }
/// <summary> /// Callback for EnumWindows /// </summary> /// <param name="hWnd">Window handle</param> /// <param name="lParam">Custom lParam (not used)</param> /// <returns>true to continue enumerating, false to stop enumerating</returns> private static bool EnumWindowsProc(IntPtr hWnd, GCHandle lParam) { // convert the lParam back into the correct managed object EnumWindowsParam param = (EnumWindowsParam)lParam.Target; // apply visible filter (if requested) if (param.VisibleOnly && ((User32.GetWindowLong(hWnd, GWL.STYLE) & WS.VISIBLE) == 0)) { return(true); } // call the underlying delegate return(param.EnumDelegate(hWnd, param.CustomParam)); }