Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- * Developed by Adam Rakaska
- * http://csharpcodewhisperer.blogspot.com
- * http://arakaska.wix.com/intelligentsoftware
- *
- *
- * Made using SharpDevelop
- *
- *
- */
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Threading;
- using System.Windows.Forms;
- namespace StayOnTop
- {
- public sealed class NotificationIcon
- {
- // Changelog; stores a list of windows we made topmost,
- // so we can 'roll-back' the changes upon exit.
- //
- // ChangeLog<WindowTitle, IsTopmost>
- private Dictionary<string,bool> changeLog = new Dictionary<string, bool>();
- // Performance / use information. Shown in the about box.
- int numRedraws = 0;
- private NotifyIcon notifyIcon;
- public NotificationIcon()
- {
- // Initialize
- notifyIcon = new NotifyIcon();
- notifyIcon.ContextMenu = new ContextMenu();
- // Subscribe to events
- notifyIcon.ContextMenu.Popup += menuDrawMenu; // DoubleClick, MouseDown
- // Resources
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotificationIcon));
- notifyIcon.Icon = (Icon)resources.GetObject("$this.Icon");
- }
- // The icon has been clicked, the menu is about to be drawn
- private void menuDrawMenu(object sender, EventArgs e)
- {
- numRedraws++;
- notifyIcon.ContextMenu.MenuItems.Clear();
- notifyIcon.ContextMenu.MenuItems.AddRange(DynamicMenu());
- }
- // Generate a context menu that displays titles of windows
- private MenuItem[] DynamicMenu()
- {
- string[] titleArray = GetWindowTitles();
- List<MenuItem> menuList = new List<MenuItem>();
- foreach(string title in titleArray)
- {
- if(changeLog.ContainsKey(title))
- {
- if(changeLog[title])
- {
- menuList.Add(new MenuItem("* " + title, menuWinClick));
- }
- else
- {
- menuList.Add(new MenuItem(title, menuWinClick));
- }
- }
- else
- {
- menuList.Add(new MenuItem(title, menuWinClick));
- }
- }
- menuList.Add(new MenuItem("_____________"));
- menuList.Add(new MenuItem("About", menuAboutClick));
- menuList.Add(new MenuItem("Exit", menuExitClick));
- return menuList.ToArray();
- }
- private void menuWinClick(object sender, EventArgs e)
- {
- string title = sender.ToString();
- string[] winTitles = GetWindowTitles();
- foreach(string win in winTitles)
- {
- if(title.Contains(win))
- {
- title = win;
- }
- }
- if(changeLog.ContainsKey(title))
- {
- bool isTopmost = !changeLog[title];
- changeLog[title] = isTopmost;
- AssignTopmostWindow(title,isTopmost);
- }
- else
- {
- changeLog.Add(title,true);
- AssignTopmostWindow(title,true);
- }
- }
- private void menuExitClick(object sender, EventArgs e)
- {
- // Roll-back changes by
- // unsetting every topmost window
- foreach(KeyValuePair<string,bool> entry in changeLog)
- {
- if(entry.Value) // If topmost
- {
- AssignTopmostWindow(entry.Key,false);
- }
- }
- Application.Exit();
- }
- private void menuAboutClick(object sender, EventArgs e)
- {
- MessageBox.Show(string.Join(Environment.NewLine,
- "TopmostTray - Makes windows always on top",
- " by Adam Rakaska",
- " http://csharpcodewhisperer.blogspot.com",
- "",
- "Number of menu redraws: " + numRedraws.ToString()
- ),
- "About"
- );
- }
- string[] GetWindowTitles()
- {
- List<string> winList = new List<string>();
- Process[] procArray = Process.GetProcesses();
- foreach(Process proc in procArray)
- {
- if(!string.IsNullOrWhiteSpace(proc.MainWindowTitle))
- {
- winList.Add(proc.MainWindowTitle);
- }
- }
- return winList.ToArray();
- }
- void AssignTopmostWindow(string windowTitle,bool makeTopmost)
- {
- IntPtr hWnd = FindWindow((string)null,windowTitle);
- RECT rect = new RECT();
- GetWindowRect(new HandleRef(this,hWnd),out rect);
- SetWindowPos(hWnd,
- makeTopmost ? HWND_TOPMOST : HWND_NOTOPMOST,
- rect.X, rect.Y, rect.Width, rect.Height,
- SWP_SHOWWINDOW);
- }
- #region Main
- [STAThread]
- public static void Main(string[] args)
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- bool isFirstInstance;
- // Please use a unique name for the mutex to prevent conflicts with other programs
- using (Mutex mtx = new Mutex(true, "TopmostTray", out isFirstInstance))
- {
- if (isFirstInstance) {
- NotificationIcon notificationIcon = new NotificationIcon();
- notificationIcon.notifyIcon.Visible = true;
- Application.Run();
- notificationIcon.notifyIcon.Dispose();
- } else {
- // The application is already running
- // TODO: Display message box or change focus to existing application instance
- }
- } // releases the Mutex
- }
- #endregion
- #region WIN32
- static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
- static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
- static readonly IntPtr HWND_TOP = new IntPtr(0);
- static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
- const UInt32 SWP_NOSIZE = 0x0001;
- const UInt32 SWP_NOMOVE = 0x0002;
- const UInt32 SWP_NOZORDER = 0x0004;
- const UInt32 SWP_NOREDRAW = 0x0008;
- const UInt32 SWP_NOACTIVATE = 0x0010;
- const UInt32 SWP_FRAMECHANGED = 0x0020;
- const UInt32 SWP_SHOWWINDOW = 0x0040;
- const UInt32 SWP_HIDEWINDOW = 0x0080;
- const UInt32 SWP_NOCOPYBITS = 0x0100;
- const UInt32 SWP_NOOWNERZORDER = 0x0200;
- const UInt32 SWP_NOSENDCHANGING = 0x0400;
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int Left, Top, Right, Bottom;
- public RECT(int left, int top, int right, int bottom) { Left = left; Top = top; Right = right; Bottom = bottom; }
- public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }
- public int X { get { return Left; } set { Right -= (Left - value); Left = value; } }
- public int Y { get { return Top; } set { Bottom -= (Top - value); Top = value; } }
- public int Height { get { return Bottom - Top; } set { Bottom = value + Top; } }
- public int Width { get { return Right - Left; } set { Right = value + Left; } }
- public static implicit operator System.Drawing.Rectangle(RECT r) { return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height); }
- public static implicit operator RECT(System.Drawing.Rectangle r) { return new RECT(r); }
- }
- [DllImport("user32.dll", SetLastError = true)]
- private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool SetWindowPos( IntPtr hWnd, IntPtr hWndInsertAfter,
- int x, int y, int cx, int cy,
- uint uFlags
- );
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement