2021年4月7日 星期三

Windows 視窗置頂

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




參考:



沒有留言:

張貼留言