private static void SetInternal(IntPtr handle, User32.AccentState accentState, bool showBorders = false, uint tintOpacity = 0) { var accent = new User32.AccentPolicy { AccentState = accentState, AccentFlags = (showBorders) ? User32.AccentFlags.DrawAllBorders : User32.AccentFlags.None, GradientColor = (_defaultTintOpacity << 24) | (_defaultTintBackgroundColor & 0xFFFFFF) }; var accentStructSize = Marshal.SizeOf(accent); var accentPtr = Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent, accentPtr, false); var data = new User32.WindowCompositionAttribData(); data.Attribute = User32.WindowCompositionAttribute.WCA_ACCENT_POLICY; data.SizeOfData = accentStructSize; data.Data = accentPtr; var ret = User32.SetWindowCompositionAttribute(handle, ref data); AppTrace.LogWarningIfFailed(ret); Debug.Assert(ret == 0 || ret == 1); Marshal.FreeHGlobal(accentPtr); }
private static void EnsureWatcherThreadRunning() { bool needsNewThread; lock (_lock) { needsNewThread = !_threadRunning; if (needsNewThread) { _threadRunning = true; } } if (needsNewThread) { new Thread(() => { Thread.CurrentThread.IsBackground = true; bool quit = false; while (_threadRunning && !quit) { IntPtr[] handles; lock (_lock) { handles = s_watchers.Select(w => w.Value.processHandle).ToArray(); } var returnValue = Kernel32.WaitForMultipleObjects(handles.Length, handles, false, (int)TimeSpan.FromSeconds(5).TotalMilliseconds); switch (returnValue) { case Kernel32.WAIT_ABANDONED: case Kernel32.WAIT_FAILED: AppTrace.LogWarningIfFailed(returnValue); Debug.Assert(false); break; case Kernel32.WAIT_TIMEOUT: // Go again break; default: ProcessWatcherData data; lock (_lock) { var handle = handles[returnValue]; data = s_watchers.First(w => w.Value.processHandle == handle).Value; s_watchers.Remove(data.processId); _threadRunning = s_watchers.Count > 0; quit = !_threadRunning; } Trace.WriteLine($"ProcessWatcherService Quit: {data.processId}"); foreach (var act in data.quitActions) { act(data.processId); } Kernel32.CloseHandle(data.processHandle); break; } } }).Start(); } }