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 - 改变窗口的位置与状态 - 万一 - 博客园

沒有留言:
張貼留言