2012-01-16 8 views
6

Process.Start()を使用して私のプログラムからメモ帳を開きますが、新しい開かれたメモ帳が画面をカバーしています。しかし、私は自分のアプリケーションの焦点を維持したい。プロセス(メモ帳)を開いた後にフォームにフォーカスを戻す方法は?

同様にI(同じProcess.Startを使用して)、MS ExcelとWordを開くが、戻って私のフォームにフォーカスを取得するためには、私が書くために必要なのは次のとおりです。メモ帳で

this.Focus(); 

しかし癖:私はメモ帳を開きます(とこのような他のすべてのプロセス)

今メモ帳に焦点を当てています。

私はこれらを試してみました:

  1. this.Activate()this.Focus()、別のより長いソリューションはhereからもらった

  2. [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] 
    public static extern IntPtr SetFocus(HandleRef hWnd); 
    
    { 
        IntPtr hWnd = myProcess.Handle; 
        SetFocus(new HandleRef(null, hWnd)); 
    } 
    
  3. [DllImport("User32")] 
    private static extern int SetForegroundWindow(IntPtr hwnd); 
    
    [DllImportAttribute("User32.DLL")] 
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 
    private const int SW_SHOW = 5; 
    private const int SW_MINIMIZE = 6; 
    private const int SW_RESTORE = 9; 
    
    { 
        ShowWindow(Process.GetCurrentProcess().MainWindowHandle, SW_RESTORE); 
        SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); 
    } 
    
  4. をは言うまでもないです。

まだメモ帳に焦点を当てています。ウィンドウに焦点を当てるだけでは、なぜそれほど難しいのですか?アプリケーション自体のウィンドウですか?

編集:私はメモ帳を最小限に開くことができますが、上記のコードをすべて試してもフォームにフォーカスを当てることはできません。メモ帳は最小化されて開きますが、フォーカスはメモ帳(Windows XPで時々表示されるもの)とフォームに集中しています。

+0

はそれがOKを開始します最小化された状態のウィンドウ? – NoviceProgrammer

+0

はい、問題はありませんが、それでも動作しません。私は私の質問でそれを更新します – nawfal

+0

これを試しましたか? http://stackoverflow.com/questions/2121911/starting-a-process-without-stealing-focus-c – NoviceProgrammer

答えて

9

私はインターネット上のほとんどすべてを試しました(それについては確かに:))。せいぜい私のフォームは他のすべてのフォームの上に置くことができましたが、フォーカスはありませんでした(@Hans Passantの方法)。すべてのコードの重いブロックで行くと、私は何とかこれは簡単ではないと感じました。だから私はいつも他のコードの塊でSetForegroundWindow()を使用しました。ちょうどSetForegroundWindow()がトリックをするとは思わなかった。

これは機能しました。

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool SetForegroundWindow(IntPtr hWnd); 

private void button1_Click(object sender, EventArgs e) 
{ 
    Process process = new Process(); 
    process.StartInfo.FileName = @...\abc.log"; 
    process.Start(); 

    process.WaitForInputIdle(); //this is the key!! 

    SetForegroundWindow(this.Handle); 
} 

回で(私の希望フォームは、親フォームのモーダル子フォームである場合)、親フォーム上のフォーカスで、この方法の収量。このような場合には、ただでさえ、これは働いていた。..

最後の行にthis.Focus()を追加します。here

2

私は同じ問題を抱えていた、私は最終的には、プログラムでAlt + Tabキーを呼んで巻き上げ:

[DllImport("user32.dll")] 
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam); 

private void alttab() 
{ 
    uint WM_SYSCOMMAND = 0x0112; 
    int SC_PREVWINDOW = 0xF050;    

    PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_PREVWINDOW, 0); 
} 

// EDIT:

+0

ありがとう。明日あなたに教えてくれるでしょう。それは間違いなく別の考えですが、私はこの回避策がいつか問題を引き起こすのではないかと心配しています。このアプローチに問題があったことはありますか? – nawfal

+0

これはうまくいきません。 – nawfal

1

Windowsが自分を無理に勧めからアプリケーションを防ぎ勿論あなたは代わりにprocess.MainWindowHandleを使用する必要がありますユーザーの顔にウィンドウを表示すると、これは作業中に表示されます。アプリケーションがフォーカスを奪う可能性のある正確なルールは、AllowSetForegroundWindow()のMSDNドキュメントに記載されています。

この制限の前後にあるバックドアは、AttachThreadInput()関数です。このコードはうまくいきました。フォアグラウンドウィンドウを所有しているスレッドのスレッドIDを見つけるためのショートカットを作成しました。メモ帳には十分です。おそらく他のアプリでは使用できません。 Raymond Chenがではないことに注意してください。はこの種のハッキングを承認しています。

private void button1_Click(object sender, EventArgs e) { 
     var prc = Process.Start("notepad.exe"); 
     prc.WaitForInputIdle(); 
     int tid = GetCurrentThreadId(); 
     int tidTo = prc.Threads[0].Id; 
     if (!AttachThreadInput(tid, tidTo, true)) throw new Win32Exception(); 
     this.BringToFront(); 
     AttachThreadInput(tid, tidTo, false); 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    private static extern bool AttachThreadInput(int tid, int tidTo, bool attach); 
    [DllImport("kernel32.dll")] 
    private static extern int GetCurrentThreadId(); 
+0

ありがとうございます。しかし、私はBringToFrontが実際にここで働くのであれば疑いがあります。コントロールを別のコントロールの上に表示させるのは単なる手段ではありませんか?それはそうではありません。活动はここでより良い選択ですか? – nawfal

+0

また、レイモンド・チェンは誰ですか?これを承認するには? :o – nawfal

+0

Form.BringToFront()はSetForegroundWindow()を呼び出し、コード化しようとするだけで簡単に見えます。 Raymond Chenは、人気のあるブログを持つMicrosoftのプログラマーです。私は彼を怒らせたくありません。 http://blogs.msdn.com/b/oldnewthing/ –

-1

によって提供さ

Microsoft.VisualBasic.Interaction.Shell(@"notepad.exe D:\abc.log", 
             Microsoft.VisualBasic.AppWinStyle.NormalNoFocus); 

ソリューションを、これを試してみてください:

public partial class MainForm : Form 
{ 
    private ShowForm showForm; 

    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    private void showButton_Click(object sender, EventArgs e) 
    { 
     this.showForm = new ShowForm(); 
     this.showForm.FormClosed += showForm_FormClosed; 
     this.showForm.Show(this); 
    } 

    private void showForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     this.Focus(); 
    } 
} 
+0

これはどのように答えているのですか? – nawfal

関連する問題