Re: [問題] process.start 外部程式 視窗焦點

看板C_Sharp (C#)作者 (TeemingVoid)時間12年前 (2013/07/29 00:30), 編輯推噓3(3019)
留言22則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《yeahhey (神秘人)》之銘言: : 大家好 : 小弟最近在用process.StartInfo來啟動外部程式 : 功能上想要達到 : buttom_click後,可以依序把多個外部程式啟動完(利用來處理資料的外部程式) : (例如:先A,A結束後再B,B結束在C...) : 這些執行序的視窗,目前程式都設定縮到最小 : 現在問題是 : ... 一開始其實看不懂你在寫什麼 :p (抱歉),後來才發現原來是指 A 程式結束後, 接下來要啟動 B 程式時,最前景視窗會失去視窗焦點(focus)。 請這樣試試看合不合你的需要: 1. 新建一個 Windows Form 專案,名稱(例如)叫: StartOneByOne 2. 在 Form1 擺一個 Button,Button1 滑鼠點兩下,準備寫 Click 事件。 3. using 以下 namespace: using System.Diagnostics; using System.Runtime.InteropServices; 4. 在 Click 事件前,貼入下列 Windows API 宣告: [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow); enum ShowWindowCommands : int { /// <summary> /// Hides the window and activates another window. /// </summary> Hide = 0, /// <summary> /// Activates and displays a window. If the window is minimized or /// maximized, the system restores it to its original size and position. /// An application should specify this flag when displaying the window /// for the first time. /// </summary> Normal = 1, /// <summary> /// Activates the window and displays it as a minimized window. /// </summary> ShowMinimized = 2, /// <summary> /// Maximizes the specified window. /// </summary> Maximize = 3, // is this the right value? /// <summary> /// Activates the window and displays it as a maximized window. /// </summary> ShowMaximized = 3, /// <summary> /// Displays a window in its most recent size and position. This value /// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except /// the window is not activated. /// </summary> ShowNoActivate = 4, /// <summary> /// Activates the window and displays it in its current size and /// position. /// </summary> Show = 5, /// <summary> /// Minimizes the specified window and activates the next top-level /// window in the Z order. /// </summary> Minimize = 6, /// <summary> /// Displays the window as a minimized window. This value is similar to /// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the /// window is not activated. /// </summary> ShowMinNoActive = 7, /// <summary> /// Displays the window in its current size and position. This value is /// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the /// window is not activated. /// </summary> ShowNA = 8, /// <summary> /// Activates and displays the window. If the window is minimized or /// maximized, the system restores it to its original size and position. /// An application should specify this flag when restoring a minimized /// window. /// </summary> Restore = 9, /// <summary> /// Sets the show state based on the SW_* value specified in the /// STARTUPINFO structure passed to the CreateProcess function by the /// program that started the application. /// </summary> ShowDefault = 10, /// <summary> /// <b>Windows 2000/XP:</b> Minimizes a window, even if the thread /// that owns the window is not responding. This flag should only be /// used when minimizing windows from a different thread. /// </summary> ForceMinimize = 11 } 5. 按鈕的 Click 事件處理函式則類似這樣: private void button1_Click(object sender, EventArgs e) { // testLab.exe 是我另外寫的測試程式,它五秒後會自動結束 string[] Programs = new string[] { @"c:\temp\testLab.exe", @"notepad.exe" }; foreach (string sProgram in Programs) { ProcessStartInfo psi = new ProcessStartInfo(sProgram); // 一開始是極小化 psi.WindowStyle = ProcessWindowStyle.Minimized; Process p = Process.Start(psi); // 等待程式確實 run 起來... while (p.MainWindowHandle == IntPtr.Zero) { System.Threading.Thread.Sleep(100); p.Refresh(); } // 測試後,發現主視窗也要極小化。 ShowWindow(this.Handle, ShowWindowCommands.Minimize); // 隱藏工作視窗,這樣 focus 自然釋出 ShowWindow(p.MainWindowHandle, ShowWindowCommands.Hide); // 重新將工作視窗設為極小化 ShowWindow(p.MainWindowHandle, ShowWindowCommands.Minimize); // p.WaitForExit(); while (!p.HasExited) { System.Threading.Thread.Sleep(100); Application.DoEvents(); } } } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.170.128.145

07/29 00:47, , 1F
先感謝你!!我有個問題是 他這樣會有焦點變化嗎?
07/29 00:47, 1F

07/29 00:48, , 2F
start後的瞬間 焦點還是會被啟動的程式奪去 在還回?
07/29 00:48, 2F

07/29 00:50, , 3F
我原本想找看看有沒有函示可以直接設定不要搶走焦點= =
07/29 00:50, 3F

07/29 00:52, , 4F
但最後也是找到你這邊提到的ShowWindowCommands!
07/29 00:52, 4F

07/29 01:00, , 5F
一旦呼叫 Process.Start(),focus 就會被新視窗搶走,
07/29 01:00, 5F

07/29 01:00, , 6F
會問有沒有焦點變化 主要是擔心某個使用中全螢幕的視窗
07/29 01:00, 6F

07/29 01:01, , 7F
ShowWindow(..., Hide); 的作用在於隱藏新的視窗,
07/29 01:01, 7F

07/29 01:01, , 8F
會因為focus改變而縮小或是瞬間縮小又切回來
07/29 01:01, 8F

07/29 01:02, , 9F
這樣 focus 自然釋出。
07/29 01:02, 9F

07/29 01:03, , 10F
因為Process.Start()會搶focus,我現在改用CreateProcess
07/29 01:03, 10F

07/29 01:04, , 11F
外部程式的作法除了process,另外查到shellExecute
07/29 01:04, 11F

07/29 01:04, , 12F
跟CreateProcess~~ shellExecute跟CreateProcess可以直接
07/29 01:04, 12F

07/29 01:05, , 13F
我猜你這樣的結果可能一樣,視窗焦點還是會被搶走 :)
07/29 01:05, 13F

07/29 01:05, , 14F
設定ShowWindowCommands(與啟動同一行指令下設定)
07/29 01:05, 14F

07/29 01:06, , 15F
你這樣一講我也覺得 那兩種內部運作應該也跟你的一樣= =
07/29 01:06, 15F

07/29 01:07, , 16F
我開個youtube測測看會不會跳掉好了= =
07/29 01:07, 16F

07/29 01:07, , 17F
以前我曾用過 Sendkeys.Send("+{Tab}"); // Alt + Tab
07/29 01:07, 17F

07/29 01:08, , 18F
但是效果並不好...
07/29 01:08, 18F

07/29 01:10, , 19F
youtube全螢幕看起來沒影響..kmp全螢幕會突然跳出
07/29 01:10, 19F

07/29 01:10, , 20F
隱藏視窗自然釋出焦點,比較自然,你再試試囉!晚安!^^
07/29 01:10, 20F

07/29 01:11, , 21F
跳出最下排的程式縮圖= =..所以內部運作應該跟寫法你一樣!
07/29 01:11, 21F

07/29 01:11, , 22F
嗯嗯感謝你~~
07/29 01:11, 22F
文章代碼(AID): #1HzKSnxt (C_Sharp)
文章代碼(AID): #1HzKSnxt (C_Sharp)