Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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();
        }
Example #4
0
 private void UnregisterThumbnail(IntPtr thumbnailHandle)
 {
     try
     {
         WindowManagerNativeMethods.DwmUnregisterThumbnail(thumbnailHandle);
     }
     catch (ArgumentException)
     {
     }
 }
Example #5
0
        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);
        }
Example #6
0
        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;
        }
Example #7
0
        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();
        }
Example #8
0
        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);
        }