2012-01-16 6 views
6

que abrir un bloc de notas de mi programa usando Process.Start() pero la nueva libreta abierta cubre la pantalla. Pero sí quiero que mi aplicación mantenga su foco.¿Cómo establecer el foco de regreso a la forma después de abrir un proceso (Bloc de notas)?

que de manera similar (usando el mismo Process.Start) abrir MS Excel y Word pero para conseguir centrarse de nuevo a mi forma todo lo que necesito para escribir es:

this.Focus(); 

Pero Quirk con el Bloc de notas: Abro el bloc de notas (y todos los otros procesos como este)

Process process = new Process(); 
process.StartInfo.UseShellExecute = true; 
process.EnableRaisingEvents = true; 
process.StartInfo.FileName = @"abc.log"; 
process.Start(); 

Ahora el bloc de notas toma el foco.

he probado todas estas:

  1. this.Activate(), this.Focus(), hace falta mencionar

  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. Otra solución más largas obtuvo de here.

Todo lo cual sigue centrado en el bloc de notas. ¿Por qué es tan difícil simplemente concentrarse en una ventana, esa también la ventana de la aplicación?

EDIT: En el mejor puedo abrir el bloc de notas reduce al mínimo, pero aún no le daría el foco a la forma después de probar todos los códigos anteriores. El bloc de notas se abre al mínimo, pero el foco seguirá en el bloc de notas (algo que a veces vemos en Windows XP) y la forma estará fuera de foco.

+0

¿Está bien empezar la ventana en un estado minimizado? – NoviceProgrammer

+0

Sí, está bien, pero no funcionaría aún. Lo actualizaré en mi pregunta – nawfal

+0

¿Has probado esto? http://stackoverflow.com/questions/2121911/starting-a-process-without-stealing-focus-c – NoviceProgrammer

Respuesta

9

Probé casi todo en internet (así que estoy seguro de ello :)). En el mejor de los casos, podría obtener mi formulario sobre todas las demás formas, pero sin foco (siguiendo el método de @Hans Passant). Pasando por bloques de códigos pesados, de alguna manera sentí que esto no sería fácil. Así que siempre usé SetForegroundWindow() con trozos de otro código. Nunca pensé que solo SetForegroundWindow() haría el truco.

Esto funcionó.

[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); 
} 

A veces este método los rendimientos en un enfoque en la forma dominante (en los casos en que mi forma deseada es una forma modal niño de su formulario primario); en tales casos, sólo tiene que añadir this.Focus() a la última línea ..

Incluso esto funcionó:

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

solución proporcionada por here

2

que tenían el mismo problema, que finalmente terminó con llamar mediante programación 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: Se debe utilizar en lugar process.MainWindowHandle supuesto

+0

Gracias. Te lo haré saber mañana ... Definitivamente eso es diferente, pero me preocupa que esta solución creara un problema en algún momento. ¿Alguna vez has tenido un problema con este enfoque? – nawfal

+0

esto no está funcionando bien .. – nawfal

1

Windows impide aplicaciones de empujar a su ventana en la cara del usuario, está viendo esto en el trabajo. Las reglas exactas cuando una aplicación puede robar el foco están documentadas en los documentos de MSDN para AllowSetForegroundWindow().

Una puerta trasera alrededor de esta restricción es la función AttachThreadInput(). Este código funcionó bien, tomé un atajo para encontrar el ID del hilo para el hilo que posee la ventana en primer plano. Lo suficientemente bueno para el Bloc de notas, posiblemente no para otras aplicaciones. No ten en cuenta que Raymond Chen hace no aprueban este tipo de truco.

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

Gracias. Pero tengo dudas de que si BringToFront realmente funciona aquí. ¿No es solo una medida para hacer que el control sea visible por encima de otro control? ¿No es eso. Activar es una mejor opción aquí? – nawfal

+0

También, ¿quién es Raymond Chen? Para aprobar esto? : o – nawfal

+0

Form.BringToFront() llama a SetForegroundWindow(), que se ve fácilmente al intentar codificar. Raymond Chen es un programador de Microsoft con un blog popular. Las publicaciones también responden aquí, no quiero enojarlo. http://blogs.msdn.com/b/oldnewthing/ –

-1

Prueba esto:

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

¿Cómo responde esto la pregunta? – nawfal

Cuestiones relacionadas