2011-02-01 5 views
5

Sto cercando di portare una finestra in primo piano. Sto usando questo codice. Ma non funziona. Qualcuno potrebbe aiutarmi?Come portare una finestra in primo piano usando C#?

ShowWindowAsync(wnd.hWnd, SW_SHOW); 

SetForegroundWindow(wnd.hWnd); 
// Code from Karl E. Peterson, www.mvps.org/vb/sample.htm 
// Converted to Delphi by Ray Lischner 
// Published in The Delphi Magazine 55, page 16 
// Converted to C# by Kevin Gale 
IntPtr foregroundWindow = GetForegroundWindow(); 
IntPtr Dummy = IntPtr.Zero; 

uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy); 
uint thisThreadId = GetWindowThreadProcessId(wnd.hWnd, Dummy); 

if (AttachThreadInput(thisThreadId, foregroundThreadId, true)) 
{ 
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack 
    SetForegroundWindow(wnd.hWnd); 
    AttachThreadInput(thisThreadId, foregroundThreadId, false); 
} 

if (GetForegroundWindow() != wnd.hWnd) 
{ 
    // Code by Daniel P. Stasinski 
    // Converted to C# by Kevin Gale 
    IntPtr Timeout = IntPtr.Zero; 
    SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0); 
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE); 
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack 
    SetForegroundWindow(wnd.hWnd); 
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE); 
} 

Codice Explained

Fare una finestra la finestra in primo piano richiede più di una semplice chiamare l'API SetForegroundWindow. È necessario per prima cosa determinare il thread in primo piano e collegarlo alla finestra utilizzando AttachThreadInput, quindi chiamare SetForegroundWindow. In questo modo possono condividere gli stati di input.

Prima chiamo GetForegroundWindow a ottenere l'handle della finestra di primo piano corrente. Quindi alcune chiamate a GetWindowThreadProcessId recuperano i thread associati alla finestra di primo piano corrente e la finestra I desidera portare in primo piano. Se questi thread sono uguali una semplice chiamata a SetForegroundWindow è tutto che è necessario. In caso contrario, il thread in primo piano è collegato alla finestra che sto portando in primo piano e scollegato da quella che era la finestra in primo piano in primo piano. L'API AttachThreadInput gestisce questo.

Contenuto prelevato da here Grazie.

+2

Codice malvagio, con la votazione di chiusura. –

+0

Non riesco a capire il codice. Ma penso che l'argomento non sarebbe chiuso. Sono in attesa di possibili soluzioni –

+0

@Nikil, mayb basta mantenere il titolo e rimuovere (dimenticare) quel codice? –

risposta

1

È necessario utilizzare SetForegroundWindow. Inoltre può essere interessante per voi C# Force Form Focus

0

sarò breve: Form.BringToFront()

+0

Questo è per i moduli nella propria applicazione, non tutte le applicazioni in esecuzione –

11

Ho usato questo metodo prima:

[DllImport("user32.dll")] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    Process[] processes = Process.GetProcessesByName("processname"); 
    SetForegroundWindow(processes[0].MainWindowHandle); 

Maggiori informazioni: http://pinvoke.net/default.aspx/user32.SetForegroundWindow

+0

È inoltre necessario portare il ripristino del modulo se è ridotto a icona. –

0

A partire da Windows 7 queste caratteristiche non si comportano abbastanza bene. Se c'è un'applicazione come Excel davanti all'applicazione che si desidera portare in primo piano, Windows 7 blocca questo e fa lampeggiare la finestra. È possibile impostare un'impostazione di timeout del Registro di sistema ForegroundLockTimeout = 0 in HKEY_CURRENT_USER \ Control Panel \ Desktop ma questi sono noti come rubare lo stato attivo. Per impostare il comportamento di come XP "dovrebbe" comportarsi e si comporterà in Windows 7 per impostazione predefinita, è possibile creare/impostare il valore su 0x00030D40 (200000 ms). Mi piacerebbe sapere qual è la soluzione preferita per applicazioni Windows affidabili. per esempio. Se ho fiducia applicazione B a prendere fuoco quando raddoppio lo scatto qualcosa in applicazione A, e qualche altra applicazione è oscurando la finestra di applicazione B.

6

Questo codice ripristina e impostare lo stato attivo a una finestra:

[DllImport("User32.dll")] 
    static extern int SetForegroundWindow(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam); 
    static Int32 WM_SYSCOMMAND = 0x0112; 
    static Int32 SC_RESTORE = 0xF120; 

e usarlo in questo modo:

var proc = Process.GetProcessesByName("YourProgram").FirstOrDefault(); 

    if (proc != null) 
    { 
     var pointer = proc.MainWindowHandle; 

     SetForegroundWindow(pointer); 
     SendMessage(pointer, WM_SYSCOMMAND, SC_RESTORE, 0); 
    } 
2

Affinché SetForegroundWindow a lavorare in modo coerente, si deve meet a few criteria.Il primo è il processo che dovrebbe eseguire il comando deve essere in primo piano. Solo il processo in foreground può rendere un altro processo in primo piano. Per rendere il processo in primo piano prima, devi portare la finestra principale in primo piano, se non lo è. Lo riduci prima e poi SetForegroundWindow per renderlo in primo piano. Ora trova il processo di destinazione e portare in primo piano

I passi sono

I've got an example, anche se è un caso d'uso leggermente diverso.