private void UpdateClientLayouts() { Process[] clientProcesses = ThumbnailManager.GetClientProcesses(); foreach (Process process in clientProcesses) { RECT rect; WindowManagerNativeMethods.GetWindowRect(process.MainWindowHandle, out rect); int left = Math.Abs(rect.Left); int right = Math.Abs(rect.Right); int clientWidth = Math.Abs(left - right); int top = Math.Abs(rect.Top); int bottom = Math.Abs(rect.Bottom); int clientHeight = Math.Abs(top - bottom); ClientLayout clientLayout = new ClientLayout(); clientLayout.X = rect.Left; clientLayout.Y = rect.Top; clientLayout.Width = clientWidth; clientLayout.Height = clientHeight; this._configuration.SetClientLayout(process.MainWindowTitle, clientLayout); } }
private void ThumbnailActivated(IntPtr id) { IThumbnailView view; if (this._thumbnailViews.TryGetValue(id, out view)) { this._activeClientHandle = view.Id; this._activeClientTitle = view.Title; } WindowManagerNativeMethods.SetForegroundWindow(id); int style = WindowManagerNativeMethods.GetWindowLong(id, WindowManagerNativeMethods.GWL_STYLE); // If the window was minimized then its thumbnail should be reset if ((style & WindowManagerNativeMethods.WS_MINIMIZE) == WindowManagerNativeMethods.WS_MINIMIZE) { WindowManagerNativeMethods.ShowWindowAsync(id, WindowManagerNativeMethods.SW_SHOWNORMAL); } if (this._configuration.EnableClientLayoutTracking) { this.UpdateClientLayouts(); } this.RefreshThumbnails(); view?.Refresh(true); }
private void RefreshThumbnails() { IntPtr foregroundWindowHandle = WindowManagerNativeMethods.GetForegroundWindow(); Boolean hideAllThumbnails = (this._configuration.HideThumbnailsOnLostFocus && this.IsNonClientWindowActive(foregroundWindowHandle)) || !WindowManagerNativeMethods.DwmIsCompositionEnabled(); this.DisableViewEvents(); // Hide, show, resize and move foreach (KeyValuePair <IntPtr, IThumbnailView> entry in this._thumbnailViews) { IThumbnailView view = entry.Value; if (hideAllThumbnails || !view.IsEnabled) { if (view.IsActive) { view.Hide(); } continue; } if (this._configuration.HideActiveClientThumbnail && (view.Id == this._activeClientHandle)) { if (view.IsActive) { view.Hide(); } continue; } // No need to update Thumbnails while one of them is highlighted if (!this._isHoverEffectActive) { // Do not even move thumbnails with default caption if (view.Title != ThumbnailManager.DefaultClientTitle) { view.ThumbnailLocation = this._configuration.GetThumbnailLocation(view.Title, this._activeClientTitle, view.ThumbnailLocation); } view.SetOpacity(this._configuration.ThumbnailOpacity); view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop); } view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays; view.SetHighlight(this._configuration.EnableActiveClientHighlight && (view.Id == this._activeClientHandle), this._configuration.ActiveClientHighlightColor, this._configuration.ActiveClientHighlightThickness); if (!view.IsActive) { view.Show(); } else { view.Refresh(false); } } this.EnableViewEvents(); }
private void UnregisterThumbnail(IntPtr thumbnailHandle) { try { WindowManagerNativeMethods.DwmUnregisterThumbnail(thumbnailHandle); } catch (ArgumentException) { } }
private void ApplyClientLayout(IntPtr clientHandle, string clientTitle) { ClientLayout clientLayout = this._configuration.GetClientLayout(clientTitle); if (clientLayout == null) { return; } WindowManagerNativeMethods.MoveWindow(clientHandle, clientLayout.X, clientLayout.Y, clientLayout.Width, clientLayout.Height, true); }
private void RegisterThumbnail() { this._thumbnailHandle = WindowManagerNativeMethods.DwmRegisterThumbnail(this.Handle, this.Id); this._thumbnail = new DWM_THUMBNAIL_PROPERTIES(); this._thumbnail.dwFlags = DWM_TNP_CONSTANTS.DWM_TNP_VISIBLE + DWM_TNP_CONSTANTS.DWM_TNP_OPACITY + DWM_TNP_CONSTANTS.DWM_TNP_RECTDESTINATION + DWM_TNP_CONSTANTS.DWM_TNP_SOURCECLIENTAREAONLY; this._thumbnail.opacity = 255; this._thumbnail.fVisible = true; this._thumbnail.fSourceClientAreaOnly = true; this._isThumbnailSetUp = true; }
public void Refresh(bool forceRefresh) { // To prevent flickering the old broken thumbnail is removed AFTER the new shiny one is created IntPtr obsoleteThumbnailHanlde = forceRefresh ? this._thumbnailHandle : IntPtr.Zero; if ((this._isThumbnailSetUp == false) || forceRefresh) { this.RegisterThumbnail(); } bool sizeChanged = this._isSizeChanged || forceRefresh; bool locationChanged = this._isPositionChanged || forceRefresh; if (sizeChanged) { // This approach would work only for square-shaped thumbnail window // To get PROPER results we have to do some crazy math //int delta = this._isHighlightEnabled ? this._highlightWidth : 0; //this._thumbnail.rcDestination = new RECT(0 + delta, 0 + delta, this.ClientSize.Width - delta, this.ClientSize.Height - delta); if (this._isHighlightEnabled) { int baseWidth = this.ClientSize.Width; int baseHeight = this.ClientSize.Height; double baseAspectRatio = ((double)baseWidth) / baseHeight; int actualHeight = baseHeight - 2 * this._highlightWidth; double desiredWidth = actualHeight * baseAspectRatio; int actualWidth = (int)Math.Round(desiredWidth, MidpointRounding.AwayFromZero); int highlightWidthLeft = (baseWidth - actualWidth) / 2; int highlightWidthRight = baseWidth - actualWidth - highlightWidthLeft; this._thumbnail.rcDestination = new RECT(0 + highlightWidthLeft, 0 + this._highlightWidth, baseWidth - highlightWidthRight, baseHeight - this._highlightWidth); } else { //No highlighting enables, so no odd math required this._thumbnail.rcDestination = new RECT(0, 0, this.ClientSize.Width, this.ClientSize.Height); } try { WindowManagerNativeMethods.DwmUpdateThumbnailProperties(this._thumbnailHandle, this._thumbnail); } catch (ArgumentException) { //This exception will be thrown if the EVE client disappears while this method is running } this._isSizeChanged = false; } if (obsoleteThumbnailHanlde != IntPtr.Zero) { this.UnregisterThumbnail(obsoleteThumbnailHanlde); } this._overlay.EnableOverlayLabel(this.IsOverlayEnabled); if (!this._isOverlayVisible) { // One-time action to show the Overlay before it is set up // Otherwise its position won't be set this._overlay.Show(); this._isOverlayVisible = true; } else { if (!(sizeChanged || locationChanged)) { // No need to adjust in the overlay location if it is already visible and properly set return; } } Size overlaySize = this.ClientSize; Point overlayLocation = this.Location; int borderWidth = (this.Size.Width - this.ClientSize.Width) / 2; overlayLocation.X += borderWidth; overlayLocation.Y += (this.Size.Height - this.ClientSize.Height) - borderWidth; this._isPositionChanged = false; this._overlay.Size = overlaySize; this._overlay.Location = overlayLocation; this._overlay.Refresh(); }
private void UpdateThumbnailsList() { Process[] clientProcesses = ThumbnailManager.GetClientProcesses(); List <IntPtr> processHandles = new List <IntPtr>(clientProcesses.Length); IntPtr foregroundWindowHandle = WindowManagerNativeMethods.GetForegroundWindow(); List <IThumbnailView> viewsAdded = new List <IThumbnailView>(); List <IThumbnailView> viewsUpdated = new List <IThumbnailView>(); List <IThumbnailView> viewsRemoved = new List <IThumbnailView>(); foreach (Process process in clientProcesses) { IntPtr processHandle = process.MainWindowHandle; string processTitle = process.MainWindowTitle; processHandles.Add(processHandle); IThumbnailView view; this._thumbnailViews.TryGetValue(processHandle, out view); if ((view == null) && (processTitle != "")) { view = this._thumbnailViewFactory.Create(processHandle, processTitle, this._configuration.ThumbnailSize); view.IsEnabled = true; view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays; view.SetFrames(this._configuration.ShowThumbnailFrames); // Max/Min size limitations should be set AFTER the frames are disabled // Otherwise thumbnail window will be unnecessary resized view.SetSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize); view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop); view.ThumbnailLocation = this._configuration.GetThumbnailLocation(processTitle, this._activeClientTitle, view.ThumbnailLocation); this._thumbnailViews.Add(processHandle, view); view.ThumbnailResized = this.ThumbnailViewResized; view.ThumbnailMoved = this.ThumbnailViewMoved; view.ThumbnailFocused = this.ThumbnailViewFocused; view.ThumbnailLostFocus = this.ThumbnailViewLostFocus; view.ThumbnailActivated = this.ThumbnailActivated; view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle)); this.ApplyClientLayout(processHandle, processTitle); viewsAdded.Add(view); } else if ((view != null) && (processTitle != view.Title)) // update thumbnail title { view.Title = processTitle; view.RegisterHotkey(this._configuration.GetClientHotkey(processTitle)); this.ApplyClientLayout(processHandle, processTitle); viewsUpdated.Add(view); } if (process.MainWindowHandle == foregroundWindowHandle) { this._activeClientHandle = process.MainWindowHandle; this._activeClientTitle = process.MainWindowTitle; } } // Cleanup IList <IntPtr> obsoleteThumbnails = new List <IntPtr>(); foreach (IntPtr processHandle in this._thumbnailViews.Keys) { if (!processHandles.Contains(processHandle)) { obsoleteThumbnails.Add(processHandle); } } foreach (IntPtr processHandle in obsoleteThumbnails) { IThumbnailView view = this._thumbnailViews[processHandle]; this._thumbnailViews.Remove(processHandle); view.UnregisterHotkey(); view.ThumbnailResized = null; view.ThumbnailMoved = null; view.ThumbnailFocused = null; view.ThumbnailLostFocus = null; view.ThumbnailActivated = null; view.Close(); viewsRemoved.Add(view); } this.ThumbnailsAdded?.Invoke(viewsAdded); this.ThumbnailsUpdated?.Invoke(viewsUpdated); this.ThumbnailsRemoved?.Invoke(viewsRemoved); }