protected override void WinEventCallback(WinEventConstant eventType, IntPtr handle, int objectId, int childId) { // Only process events related to FG capture if (eventType != WinEventConstant.EVENT_SYSTEM_FOREGROUND && eventType != WinEventConstant.EVENT_SYSTEM_MINIMIZEEND) { return; } // Only process events with valid parameters if (handle == null || objectId != 0) { return; } // Get process ID _ = NativeMethods.GetWindowThreadProcessId(handle, out uint windowThreadProcId); // Ignore these windows var windowStyle = NativeMethods.GetWindowStyleEx(handle); if ((windowStyle & WindowStylesEx.WS_EX_NOACTIVATE) == WindowStylesEx.WS_EX_NOACTIVATE) { return; } // Ignore ghost window when target is unresponsive // Ghost windows take foreground but target window doesn't trigger EVENT_SYSTEM_FOREGROUND // when responsive again. var className = NativeMethods.GetClassName(handle); var currentTitle = NativeMethods.GetWindowText(handle); if (className == "Ghost" && _lastTitle == currentTitle) { return; } // Get process path string processName = NativeMethods.GetFullProcessName((int)windowThreadProcId); // Send event ForegroundWindowChanged?.Invoke(this, new ForegroundWindowChangedEventArgs { Handle = handle, WindowThreadProcId = windowThreadProcId, ProcessPath = processName }); // Store title _lastTitle = currentTitle; }
protected override void WinEventCallback(WinEventConstant eventType, IntPtr handle, int objectId, int childId) { if (handle == _targetHandle && objectId == 0) { if (eventType == WinEventConstant.EVENT_OBJECT_DESTROY) { // Target window was closed WindowClosed?.Invoke(this, EventArgs.Empty); } else if (eventType == WinEventConstant.EVENT_OBJECT_LOCATIONCHANGE) { // Target window size has changed SendWindowDimensions(handle); } else if (eventType == WinEventConstant.EVENT_OBJECT_NAMECHANGE) { // Target window title has changed SendWindowTitle(handle); } } }