2009-01-14 11 views
16

मेरे पास एक ऐसा एप्लिकेशन है जिसमें एक समय में स्वयं का एक उदाहरण खुल सकता है। इसे लागू करने के लिए, मैं इस कोड का उपयोग करता हूं:मैं एक विदेशी विंडो कैसे केंद्रित करूं?

 System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcesses(); 
     System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess(); 
     foreach (System.Diagnostics.Process p in myProcesses) 
     { 
      if (p.ProcessName == me.ProcessName) 
       if (p.Id != me.Id) 
       { 
        //if already running, abort this copy. 
        return; 
       } 
     } 
     //launch the application. 
     //... 

यह ठीक काम करता है। मैं इसे पहले से चल रही प्रति के रूप पर ध्यान केंद्रित करने में सक्षम होना चाहूंगा। यही है, लौटने से पहले, मैं इस आवेदन का दूसरा उदाहरण अग्रभूमि में लाना चाहता हूं।

कैसे मैं ऐसा क्यों है?

पुन: SetForeGroundWindow:

SetForeGroundWindow, काम करता है एक बिंदु के लिए:

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

    //... 
       if (p.Id != me.Id) 
       { 
        //if already running, focus it, and then abort this copy. 
        SetForegroundWindow(p.MainWindowHandle); 
        return; 
       } 
    //... 

इस अग्रभूमि करने के लिए खिड़की लाना पड़ता अगर यह कम से कम नहीं है। बहुत बढ़िया। यदि विंडो कम हो गई है, हालांकि, यह कम हो गई है।

इसे कम से कम करने की आवश्यकता है। SwitchToThisWindow के माध्यम से

समाधान (वर्क्स!):

[System.Runtime.InteropServices.DllImport("user32.dll")] 
    public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); 

    [STAThread] 
    static void Main() 
    { 
     System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess(); 
     System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcessesByName(me.ProcessName); 
     foreach (System.Diagnostics.Process p in myProcesses) 
     { 
      if (p.Id != me.Id) 
      { 
       SwitchToThisWindow(p.MainWindowHandle, true); 
       return; 
      } 
     } 
     //now go ahead and start our application ;-) 
+1

जांच करें, कहीं खिड़की IsIconic, यदि ऐसा है तो ShowWindow http://msdn.microsoft.com/en-us/library/ms633527(VS.85).aspx http फोन: // MSDN। microsoft.com/en-us/library/ms633548(VS.85)।एएसपीएक्स – cmsjr

उत्तर

10

मुझे एक ही समस्या थी और SwitchToThisWindow() मेरे लिए सबसे अच्छा काम किया। एकमात्र सीमा यह है कि आपके पास XP SP1 स्थापित होना चाहिए। मैंने SetForegroundWindow, ShowWindow के साथ खेला, और दोनों को खिड़की को देखने में समस्याएं थीं।

+1

ध्यान दें, हालांकि, लिंक किया गया एमएसडीएन पृष्ठ कहता है "[यह फ़ंक्शन सामान्य उपयोग के लिए नहीं है। इसे विंडोज के बाद के संस्करणों में बदला या अनुपलब्ध किया जा सकता है।]" –

0

आप प्रक्रिया वस्तु की MainWindowHandle संपत्ति हड़पने कर सकते हैं का उपयोग करें और यह एक WM_USER भेजना चाहते हैं जाएगा संदेश जिसे आप "कुछ अन्य उदाहरण" के रूप में व्याख्या करना चाहते हैं "के रूप में व्याख्या कर सकते हैं।

+0

ऐसा कर सकता है, यद्यपि बदसूरत लगता है। SetForegroundWindow पैन आउट नहीं होने पर यह एक अच्छा विकल्प हो सकता है। –

2

पूरा साइड नोट ...

इसके बजाय आप सभी सिस्टम पर चलने प्रक्रियाओं पर पाशन के

Process.GetProcessesByName(me.ProcessName) 

उपयोग कर सकते हैं ...

अद्यतन

PInvoke इस तरह के सामान के लिए नियम ...

3

ओपी के समान, मैंने पाया कि खिड़की कम होने पर SetForegroundWindow अकेले पर्याप्त नहीं था। चूंकि मैं SwitchToThisWindow का उपयोग नहीं करना चाहता था, इसलिए मैंने ShowWindow का चयन किया जिसके बाद SetForegroundWindow चुना गया।

मेरे लिए अच्छा काम करता है!

private const SW_SHOWNORMAL = 1 

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ 
Private Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As integer) As Boolean 
End Function 

<DllImport("user32.dll", SetLastError:=True)> _ 
Private Function SetForegroundWindow(ByVal hwnd As IntPtr) As Boolean 
End Function 

Sub SetForeground() 
    Dim processes As Process() = Process.GetProcessesByName("myprocess") 

    For Each p as Process in processes 
     ShowWindow(p.MainWindowHandle, SW_SHOWNORMAL) 
     SetForegroundWindow(p.MainWindowHandle) 
    Next 
End Sub 
2

सी # टॉम जुर्गेन्स के उत्तर के बराबर। मेरे लिए एक आकर्षण की तरह काम करता है।

private const int SW_SHOWNORMAL = 1; 

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow); 


    [DllImport("user32.dll", SetLastError = true)] 
    private static extern bool SetForegroundWindow(IntPtr hwnd); 

    public void SetForeground() 
    { 
     Process[] processes = Process.GetProcessesByName("process name"); 

     foreach (Process p in processes) { 
      ShowWindow(p.MainWindowHandle, SW_SHOWNORMAL); 
      SetForegroundWindow(p.MainWindowHandle); 
     } 
    } 
+0

हम उपरोक्त को सरल कैसे लॉन्च करने के लिए सरल बना सकते हैं वह पहले से चल रहा है? – DeerSpotter

संबंधित मुद्दे

 संबंधित मुद्दे