From b84a1add5822e440c272eab517c81bdcfc848292 Mon Sep 17 00:00:00 2001 From: Jerrylum Date: Sat, 16 May 2020 17:03:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=B0=88=E6=A1=88=E6=AA=94?= =?UTF-8?q?=E6=A1=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TopMost.sln | 25 +++++ TopMost/App.config | 6 ++ TopMost/OptionsForm.Designer.cs | 108 +++++++++++++++++++ TopMost/OptionsForm.cs | 51 +++++++++ TopMost/OptionsForm.resx | 126 +++++++++++++++++++++++ TopMost/Program.cs | 84 +++++++++++++++ TopMost/Properties/AssemblyInfo.cs | 36 +++++++ TopMost/Properties/Resources.Designer.cs | 63 ++++++++++++ TopMost/Properties/Resources.resx | 117 +++++++++++++++++++++ TopMost/Properties/Settings.Designer.cs | 26 +++++ TopMost/Properties/Settings.settings | 7 ++ TopMost/TopMost.csproj | 84 +++++++++++++++ 12 files changed, 733 insertions(+) create mode 100644 TopMost.sln create mode 100644 TopMost/App.config create mode 100644 TopMost/OptionsForm.Designer.cs create mode 100644 TopMost/OptionsForm.cs create mode 100644 TopMost/OptionsForm.resx create mode 100644 TopMost/Program.cs create mode 100644 TopMost/Properties/AssemblyInfo.cs create mode 100644 TopMost/Properties/Resources.Designer.cs create mode 100644 TopMost/Properties/Resources.resx create mode 100644 TopMost/Properties/Settings.Designer.cs create mode 100644 TopMost/Properties/Settings.settings create mode 100644 TopMost/TopMost.csproj diff --git a/TopMost.sln b/TopMost.sln new file mode 100644 index 0000000..1e324bf --- /dev/null +++ b/TopMost.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29911.84 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopMost", "TopMost\TopMost.csproj", "{EDB3FFEE-22DC-43DA-A833-D4B712681BD0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EDB3FFEE-22DC-43DA-A833-D4B712681BD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDB3FFEE-22DC-43DA-A833-D4B712681BD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDB3FFEE-22DC-43DA-A833-D4B712681BD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDB3FFEE-22DC-43DA-A833-D4B712681BD0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A581DBC5-6510-4124-AB74-F6174D39AD60} + EndGlobalSection +EndGlobal diff --git a/TopMost/App.config b/TopMost/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/TopMost/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TopMost/OptionsForm.Designer.cs b/TopMost/OptionsForm.Designer.cs new file mode 100644 index 0000000..cc48525 --- /dev/null +++ b/TopMost/OptionsForm.Designer.cs @@ -0,0 +1,108 @@ +namespace TopMost2 +{ + partial class OptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.NotifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); + this.NotifyIconMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ResetAllStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.NotifyIconMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // NotifyIcon1 + // + this.NotifyIcon1.ContextMenuStrip = this.NotifyIconMenuStrip1; + this.NotifyIcon1.Text = "TopMost2"; + this.NotifyIcon1.Visible = true; + this.NotifyIcon1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon1_MouseDoubleClick); + // + // NotifyIconMenuStrip1 + // + this.NotifyIconMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.exitToolStripMenuItem, + this.optionsToolStripMenuItem, + this.clearAllToolStripMenuItem, + this.ResetAllStripMenuItem}); + this.NotifyIconMenuStrip1.Name = "NotifyIconMenuStrip1"; + this.NotifyIconMenuStrip1.Size = new System.Drawing.Size(181, 114); + this.NotifyIconMenuStrip1.TabStop = true; + this.NotifyIconMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.NotifyIconMenuStrip1_Opening); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.optionsToolStripMenuItem.Text = "Options"; + // + // ResetAllStripMenuItem + // + this.ResetAllStripMenuItem.Name = "ResetAllStripMenuItem"; + this.ResetAllStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.ResetAllStripMenuItem.Text = "Reset All"; + this.ResetAllStripMenuItem.Click += new System.EventHandler(this.ResetAllStripMenuItem_Click); + // + // clearAllToolStripMenuItem + // + this.clearAllToolStripMenuItem.Name = "clearAllToolStripMenuItem"; + this.clearAllToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.clearAllToolStripMenuItem.Text = "Clear All"; + // + // OptionsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Name = "OptionsForm"; + this.Text = "OptionsForm"; + this.NotifyIconMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.NotifyIcon NotifyIcon1; + private System.Windows.Forms.ContextMenuStrip NotifyIconMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem ResetAllStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearAllToolStripMenuItem; + } +} \ No newline at end of file diff --git a/TopMost/OptionsForm.cs b/TopMost/OptionsForm.cs new file mode 100644 index 0000000..81cb830 --- /dev/null +++ b/TopMost/OptionsForm.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using TopMost; + +namespace TopMost2 +{ + public partial class OptionsForm : Form + { + + public OptionsForm() + { + InitializeComponent(); + NotifyIcon1.Icon = SystemIcons.Application; + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + NotifyIcon1.Icon = null; // remove the icon + Application.Exit(); + } + + private void NotifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) + { + // current Hwnd is the task bar, we dont need that + Console.WriteLine(Program.GetWindowTitle(Program.lastHwnd)); + Program.SetTopMost(); + } + + private void NotifyIconMenuStrip1_Opening(object sender, CancelEventArgs e) + { + Console.WriteLine("me"); + + + } + + private void ToolStripMenuItem_Click(object sender, EventArgs e) + { + + } + + private void ResetAllStripMenuItem_Click(object sender, EventArgs e) + { + + } + } +} diff --git a/TopMost/OptionsForm.resx b/TopMost/OptionsForm.resx new file mode 100644 index 0000000..a520343 --- /dev/null +++ b/TopMost/OptionsForm.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 132, 17 + + \ No newline at end of file diff --git a/TopMost/Program.cs b/TopMost/Program.cs new file mode 100644 index 0000000..0ff7e7d --- /dev/null +++ b/TopMost/Program.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using TopMost2; + +namespace TopMost +{ + static class Program + { + [DllImport("user32.dll")] + static extern IntPtr GetForegroundWindow(); + [DllImport("user32.dll")] + static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern int GetWindowTextLength(IntPtr hWnd); + [DllImport("user32.dll")] + static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + [DllImport("user32.dll")] + static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags); + [DllImport("user32.dll", SetLastError = true)] + static extern UInt32 GetWindowLong(IntPtr hWnd, IntPtr nIndex); + + static readonly IntPtr GWL_EXSTYLE = new IntPtr(-20); + static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + static readonly UInt32 WS_EX_TOPMOST = 0x0008; + static readonly UInt32 SWP_NOSIZE = 0x0001; + static readonly UInt32 SWP_NOMOVE = 0x0002; + static readonly UInt32 SWP_SHOWWINDOW = 0x0040; + static readonly UInt32 WINEVENT_OUTOFCONTEXT = 0; + static readonly UInt32 EVENT_SYSTEM_FOREGROUND = 3; + + + public static WinEventDelegate dele = null; + public static IntPtr lastHwnd; + public static IntPtr cureentHwnd; + + public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); + + + public static string GetWindowTitle(IntPtr handle) + { + var length = GetWindowTextLength(handle); + var title = new StringBuilder(length); + GetWindowText(handle, title, length); + return title.ToString(); + } + + public static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) + { + lastHwnd = cureentHwnd; + cureentHwnd = hwnd; + } + + public static void SetTopMost() + { + bool now_topmost = (GetWindowLong(lastHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; + + Program.SetWindowPos(lastHwnd, now_topmost ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + + [STAThread] + static void Main() + { + + dele = new WinEventDelegate(WinEventProc); + IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT); + + cureentHwnd = GetForegroundWindow(); + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + + new OptionsForm(); // Dont use `Application.Run(...);`. We want to hide the form + + Application.Run(); + } + } +} diff --git a/TopMost/Properties/AssemblyInfo.cs b/TopMost/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..675e7c1 --- /dev/null +++ b/TopMost/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 組件的一般資訊是由下列的屬性集控制。 +// 變更這些屬性的值即可修改組件的相關 +// 資訊。 +[assembly: AssemblyTitle("TopMost")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TopMost")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 將 ComVisible 設為 false 可對 COM 元件隱藏 +// 組件中的類型。若必須從 COM 存取此組件中的類型, +// 的類型,請在該類型上將 ComVisible 屬性設定為 true。 +[assembly: ComVisible(false)] + +// 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID +[assembly: Guid("edb3ffee-22dc-43da-a833-d4b712681bd0")] + +// 組件的版本資訊由下列四個值所組成: +// +// 主要版本 +// 次要版本 +// 組建編號 +// 修訂編號 +// +// 您可以指定所有的值,也可以使用 '*' 將組建和修訂編號 +// 設為預設,如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TopMost/Properties/Resources.Designer.cs b/TopMost/Properties/Resources.Designer.cs new file mode 100644 index 0000000..89d7a34 --- /dev/null +++ b/TopMost/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 這段程式碼是由工具產生的。 +// 執行階段版本:4.0.30319.42000 +// +// 對這個檔案所做的變更可能會造成錯誤的行為,而且如果重新產生程式碼, +// 變更將會遺失。 +// +//------------------------------------------------------------------------------ + +namespace TopMost2.Properties { + using System; + + + /// + /// 用於查詢當地語系化字串等的強類型資源類別。 + /// + // 這個類別是自動產生的,是利用 StronglyTypedResourceBuilder + // 類別透過 ResGen 或 Visual Studio 這類工具。 + // 若要加入或移除成員,請編輯您的 .ResX 檔,然後重新執行 ResGen + // (利用 /str 選項),或重建您的 VS 專案。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 傳回這個類別使用的快取的 ResourceManager 執行個體。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TopMost2.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 覆寫目前執行緒的 CurrentUICulture 屬性,對象是所有 + /// 使用這個強類型資源類別的資源查閱。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/TopMost/Properties/Resources.resx b/TopMost/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/TopMost/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TopMost/Properties/Settings.Designer.cs b/TopMost/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9c46683 --- /dev/null +++ b/TopMost/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 這段程式碼是由工具產生的。 +// 執行階段版本:4.0.30319.42000 +// +// 對這個檔案所做的變更可能會造成錯誤的行為,而且如果重新產生程式碼, +// 變更將會遺失。 +// +//------------------------------------------------------------------------------ + +namespace TopMost2.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/TopMost/Properties/Settings.settings b/TopMost/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/TopMost/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/TopMost/TopMost.csproj b/TopMost/TopMost.csproj new file mode 100644 index 0000000..8fc11a2 --- /dev/null +++ b/TopMost/TopMost.csproj @@ -0,0 +1,84 @@ + + + + + Debug + AnyCPU + {EDB3FFEE-22DC-43DA-A833-D4B712681BD0} + WinExe + TopMost2 + TopMost2 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Form + + + OptionsForm.cs + + + + + OptionsForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file