A THINKING FRUIT
概要
どこにあるのかわからない! 目的のウィンドウを手前に表示するプログラムです。
本コードは Windows エクスプローラのウィンドウをリストに登録し、リスト上のウィンドウ名をダブルクリックされるとウィンドウを手前に表示する。
C#(.NET Framework 4.8.1)
class MainForm : Form { public MainForm() { InitializeComponent(); // 必要なコントロール // ・リストビュー: lsWndInfo // ・カラムヘッダー ×2(リストビュー用) // あると便利なコントロール // ・チェックボックス: checkTopMost lsWndInfo.ShowGroups = true; lsWndInfo.View = View.Details; lsWndInfo.MouseDoubleClick += LsWndInfo_MouseDoubleClick; checkTopMost.Text = "最前面"; checkTopMost.CheckedChanged += checkTopMost_CheckedChanged; var vg = new ListViewGroup("Explorer"); vg.Name = "Explorer"; lsWndInfo.Groups.Add(vg); CallEnumWindow(); } private void LsWndInfo_MouseDoubleClick(object sender, MouseEventArgs e) { var vi = lsWndInfo.GetItemAt(e.X, e.Y); var wi = (CWndInfo)vi.Tag; // スレッド実行することでリストビューの描画を止めずに済む。 Task.Run(() => { RequestWindowTopMost(wi.m_hWnd); }); } private void checkTopMost_CheckedChanged(object sender, EventArgs e) { this.TopMost = !this.TopMost; } static void RequestWindowTopMost(IntPtr hWnd) { #if x86 #else IntPtr nExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); #endif long uiExStyle1 = nExStyle.ToInt64(); long uiExStyle2 = WS_EX_TOPMOST; if ((uiExStyle1 & uiExStyle2) != 0) { return; } UInt32 uFlag = 0 | SWP_NOMOVE | SWP_NOSIZE ; SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, uFlag); System.Threading.Thread.Sleep(400); SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, uFlag | SWP_SHOWWINDOW); } delegate Int32 LPENUMWINDOWPROC(IntPtr hWnd, IntPtr lParam); delegate CParamEnumWnd GETENUMWNDPARAMPROC(); private void CallEnumWindow() { var fnProc = new LPENUMWINDOWPROC( EnumWindowProc ); IntPtr hProc = Marshal.GetFunctionPointerForDelegate<LPENUMWINDOWPROC>(fnProc); CParamEnumWnd param = new CParamEnumWnd(); param.m_lsWndInfo = lsWndInfo; GETENUMWNDPARAMPROC fnProc2 = ()=> { return param; }; IntPtr hProc2 = Marshal.GetFunctionPointerForDelegate<GETENUMWNDPARAMPROC>(fnProc2); param.Setup(); EnumWindows(hProc, hProc2); param.Cleanup(); } private static Int32 EnumWindowProc(IntPtr hWnd, IntPtr lParam) { var fnGetParam = Marshal.GetDelegateForFunctionPointer<GETENUMWNDPARAMPROC>(lParam); CParamEnumWnd param = fnGetParam(); int nCharLength; nCharLength = GetClassName(hWnd, param.bstrClass.p, param.bstrClass.length); String str = param.bstrClass.v.Substring(0, nCharLength); if (str != "CabinetWClass") { return 1; } nCharLength = GetWindowText(hWnd, param.bstrTitle.p, param.bstrTitle.length); CWndInfo wi = new CWndInfo(); wi.m_hWnd = hWnd; wi.m_strTitle = param.bstrTitle.v.Substring(0, nCharLength); // リストへアイテムを追加 ListViewItem vi = new ListViewItem(); vi.Text = Path.GetFileName(wi.m_strTitle); vi.Tag = wi; vi.Group = param.m_lsWndInfo.Groups[0]; ListViewSubItem vsi = new ListViewSubItem(); vsi.Text = Path.GetDirectoryName(wi.m_strTitle); vi.SubItems.Add(vsi); param.m_lsWndInfo.Items.Add(vi); return 1; } class CWndInfo { public IntPtr m_hWnd; public string m_strTitle; } class CBstr { IntPtr m_hStr; int m_nCharLength; public void Setup( String strInitValue ) { m_hStr = Marshal.StringToBSTR(strInitValue); m_nCharLength = strInitValue.Length; } public void Cleanup() { if (m_hStr != IntPtr.Zero) { Marshal.FreeBSTR(m_hStr); m_hStr = IntPtr.Zero; } } public String v { get { return Marshal.PtrToStringBSTR(m_hStr); } } public IntPtr p { get { return m_hStr; } } public int length { get { return m_nCharLength; } } } class CParamEnumWnd { CBstr m_bstrTitle = new CBstr(); CBstr m_bstrClass = new CBstr(); public ListView m_lsWndInfo; public void Setup() { String strBuffer = new String('\0', 1024); m_bstrTitle.Setup(strBuffer); m_bstrClass.Setup(strBuffer); } public void Cleanup() { m_bstrTitle.Cleanup(); m_bstrClass.Cleanup(); } public CBstr bstrTitle { get { return m_bstrTitle; } } public CBstr bstrClass { get { return m_bstrClass; } } } [DllImport("User32.dll", CharSet = CharSet.Unicode)] public extern static Int32 GetWindowText(IntPtr hWnd, IntPtr hTitleStr, Int32 nLength); [DllImport("User32.dll", CharSet=CharSet.Unicode)] public extern static Int32 GetClassName(IntPtr hWnd, IntPtr hClassStr, Int32 nLength); [DllImport("User32.dll")] public extern static Int32 EnumWindows(IntPtr hEnumWindowProc, IntPtr lParam); [DllImport("User32.dll")] public extern static Int32 SetWindowPos(IntPtr hWnd, IntPtr hInsertWnd, Int32 x, Int32 y, Int32 w, Int32 h, UInt32 uFlag); public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); public const uint SWP_NOMOVE = 0x0002; public const uint SWP_NOSIZE = 0x0001; public const uint SWP_SHOWWINDOW = 0x0040; #if x86 #else [DllImport("User32.dll")] public extern static IntPtr GetWindowLongPtr(IntPtr hWnd, Int32 n); #endif public const uint WS_EX_TOPMOST = 0x00000008; public const Int32 GWL_EXSTYLE = -20; }