C# 列出 windows 目前開啟的視窗(Process),將選擇的視窗(Process)設為置頂,固定在最上層。
程式碼:
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WinTopMost { public partial class Form1 : Form { [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags); private const int HWND_TOPMOST = -1; private const int HWND_NOTOPMOST = -2; private const int SWP_NOMOVE = 0x0002; private const int SWP_NOSIZE = 0x0001; [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowLong(IntPtr hWnd, int nIndex); const int GWL_EXSTYLE = -20; const int WS_EX_TOPMOST = 0x0008; private ArrayList ProcessDataArrList; public Form1() { InitializeComponent(); LoadProcesses(); } //取得Process private void LoadProcesses() { //this.listBox1.Items.Clear(); Process[] allProcesses = Process.GetProcesses(); this.ProcessDataArrList = new ArrayList(); foreach (Process process in allProcesses) { if (this.chkWinTitleNoEmpty.Checked && "" == process.MainWindowTitle) { //略過MainWindowTitle為空 continue; } bool isTop = IsWindowTopMost(process.MainWindowHandle); if (this.chkOnlyTopWin.Checked && !isTop) { //略過非置頂 continue; } string isTopStr = isTop ? "Top" : "X "; string name = isTopStr + " # " + process.MainWindowTitle + " # " + process.Id + " # " + process.ProcessName; this.ProcessDataArrList.Add(new ProcessData(process, name)); } this.listBox1.DataSource = ProcessDataArrList; this.listBox1.ValueMember = "MyKey"; this.listBox1.DisplayMember = "MyName"; } //視窗是否置頂 private bool IsWindowTopMost(IntPtr hWnd) { int exStyle = GetWindowLong(hWnd, GWL_EXSTYLE); return (exStyle & WS_EX_TOPMOST) == WS_EX_TOPMOST; } //置頂 private void btnTopMost_Click(object sender, EventArgs e) { if (this.listBox1.SelectedIndex != -1) { ProcessData ProcessData = this.listBox1.SelectedItem as ProcessData; SetWindowPos(ProcessData.MyKey.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); LoadProcesses(); } } //取消置頂 private void btnNoTopMost_Click(object sender, EventArgs e) { if (this.listBox1.SelectedIndex != -1) { ProcessData ProcessData = this.listBox1.SelectedItem as ProcessData; SetWindowPos(ProcessData.MyKey.MainWindowHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); LoadProcesses(); } } //更新列表 private void btnRefreshList_Click(object sender, EventArgs e) { LoadProcesses(); } //MainWindowTitle不為空 private void chkWinTitleNoEmpty_CheckedChanged(object sender, EventArgs e) { LoadProcesses(); } //只列出置頂視窗 private void chkOnlyTopWin_CheckedChanged(object sender, EventArgs e) { LoadProcesses(); } //連結網址 private void linkLabelxyz_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { string target = "https://xyz.cinc.biz"; try { //System.Diagnostics.Process.Start(target);//系統找不到指定的檔案 //https://stackoverflow.com/questions/21835891/process-starturl-fails System.Diagnostics.Process.Start(new ProcessStartInfo(target) { UseShellExecute = true }); } catch (System.ComponentModel.Win32Exception noBrowser) { if (noBrowser.ErrorCode == -2147467259) MessageBox.Show(noBrowser.Message); } catch (System.Exception other) { MessageBox.Show(other.Message); } } } public class ProcessData { private Process pKey; private string pName; public ProcessData(Process process, string name) { this.pKey = process; this.pName = name; } public Process MyKey { get { return pKey; } } public string MyName { get { return pName; } } } }
執行畫面:
檔案下載:
https://drive.google.com/uc?export=download&id=11-f-e5sxz_yYdu-csaKu3CuUUzuItS--
SHA256:
ddebfe2fae4009667b2401d746f8113d57bb799f751c8056df2eec208c5e03ab
參考:
- https://docs.microsoft.com/zh-tw/dotnet/api/system.diagnostics.process.getprocesses?view=net-5.0
Process.GetProcesses 方法 (System.Diagnostics) - https://stackoverflow.com/questions/36952600/determine-if-a-window-is-topmost-or-not
c# - Determine if a window is topmost or not - Stack Overflow - https://stackoverflow.com/a/61035650
c# - Process.Start(url) fails - Stack Overflow - https://docs.microsoft.com/zh-tw/troubleshoot/dotnet/csharp/start-internet-browser
使用 Visual c # 方法來啟動瀏覽器 - C# - https://www.codeproject.com/Tips/793032/Set-window-OnTop-in-running-programs-from-Csharp
Set window OnTop in running programs from C# - CodeProject - https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos
SetWindowPos function (winuser.h) - Win32 apps - https://docs.microsoft.com/zh-tw/dotnet/api/system.windows.forms.listcontrol.displaymember?view=net-5.0
ListControl.DisplayMember 屬性 (System.Windows.Forms) - https://blog.walterlv.com/post/use-shell-execute-in-process-start-info.html
C#/.NET 中启动进程时所使用的 UseShellExecute 设置为 true 和 false 分别代表什么意思? - walterlv - https://www.twblogs.net/a/5d106b58bd9eee1ede049407
C#託管代碼和非託管代碼 - https://earthcat99.pixnet.net/blog/post/36811169
DLLImport 使用方式 @ 神喵的筆記簿 :: 痞客邦 :: - https://docs.microsoft.com/zh-tw/dotnet/standard/native-interop/best-practices
原生互通性最佳做法 - .NET (DllImport 屬性設定) - https://docs.microsoft.com/zh-tw/dotnet/api/system.runtime.interopservices.dllimportattribute?view=net-5.0
DllImportAttribute 類別 (System.Runtime.InteropServices) - https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshal?view=net-5.0
Marshal 类 (System.Runtime.InteropServices) - https://www.cnblogs.com/del/archive/2008/02/12/1067358.html
WinAPI: SetWindowPos - 改变窗口的位置与状态 - 万一 - 博客园
沒有留言:
張貼留言