2010-04-14 4 views
31

हम केवल एक ही समय में हमारे ऐप के एक उदाहरण को चलाना चाहते हैं। तो शुरूआत में यह देखने लगता है कि ऐप चल रहा है या नहीं, और यदि यह है, तो यह मुख्य विंडो पर SetForegroundWindow पर कॉल करता है।एक और प्रक्रियाएं लाएं विंडो में अग्रभूमि पर जब ShowInTaskbar = false

यह सब अच्छा है और अच्छी तरह से ... अधिकांश भाग के लिए ..

जब हमारे एप्लिकेशन शुरू होता है यह एक स्पलैश स्क्रीन और एक लॉग ऑन रूप में दिखाई देगा। इन दोनों रूपों में ShowInTaskBar = false है।

इस कारण, यदि आप लॉगऑन फॉर्म दिखाते समय ऐप की एक और प्रतिलिपि शुरू करने का प्रयास करते हैं, तो लॉगऑन फॉर्म को पर लाया नहीं गया है!

खासकर जब उपयोगकर्ता टास्कबार में कुछ भी नहीं देख सकता है, तो वे सभी जानते हैं कि ऐप डफ है और शुरू नहीं हो सकता है। कोई संकेत नहीं है कि एक और उदाहरण चल रहा है।

क्या इस समस्या के आसपास कोई रास्ता है?

+0

प्रश्न: इस का समाधान नहीं लॉग ऑन फार्म के मालिक संपत्ति की स्थापना करता है या करता है इसका कोई प्रभाव नहीं है? – Asher

उत्तर

41

अच्छा, कोड यहां है। भले ही ShowInTaskBarfalse है, तो आप इसे सामने ला सकते हैं।

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] 
    public static extern IntPtr FindWindow(String lpClassName, String lpWindowName); 

    [DllImport("USER32.DLL")] 
    public static extern bool SetForegroundWindow(IntPtr hWnd); 

    public static void bringToFront(string title) { 
     // Get a handle to the Calculator application. 
     IntPtr handle = FindWindow(null, title); 

     // Verify that Calculator is a running process. 
     if (handle == IntPtr.Zero) { 
      return; 
     } 

     // Make Calculator the foreground application 
     SetForegroundWindow(handle); 
    } 

नोट: यदि आप ऐसा करना चाहिए FindWindow नाम से फार्म की क्लास और नहीं का उपयोग कर के रूप में स्प्लैश स्क्रीन रूपों कभी कभी खिताब या यहाँ तक कि controlbox जरूरत नहीं है। गहरी खुदाई करने के लिए जासूस ++ का प्रयोग करें।

स्पलैश पर FindWindow का उपयोग करें। मुझे लगता है कि आप यही करना चाहते हैं - मुख्य रूप से लोड करते समय स्प्लैश स्क्रीन को सामने लाएं।

+0

मैं एक सिस्टम कर रहा था। डायग्नोस्टिक्स.प्रोसेस.गेटप्रोसेसेसबिननाम कॉल प्रक्रिया को प्राप्त करने के लिए कॉल करें और फिर प्रक्रिया पर SetForegroundWindow को कॉल करें। मेनविंडो हैंडल। ShowInTaskbar के बिना, कोई MainWindowHandle नहीं था। FindWindow इस के आसपास काम करने का एक अच्छा तरीका है। धन्यवाद! –

+0

ऐसा करने के कई तरीके अभी तक केवल यही था जो मेरे लिए काम करता था! – Lee

0
FindWindow(null, title); 

क्वेरी से मेल खाने वाली पहली विंडो मिल जाएगी। यदि कोई अन्य विंडो एक ही शीर्षक का उपयोग करती है तो इससे अप्रत्याशित व्यवहार हो सकता है।

हालांकि ऐसा होने की संभावना दुर्लभ या असंभव प्रतीत हो सकती है (एकल उदाहरण एप्लिकेशन) यह आसानी से हो सकता है। उदाहरण के लिए विंडोज एक्सप्लोरर चयनित निर्देशिका के नाम का उपयोग विंडो शीर्षक (हालांकि अदृश्य) के रूप में करता है। अब यदि विंडो शीर्षक एक सामान्य शब्द है या एप्लिकेशन निर्देशिका के नाम से मेल खाता है तो यह एक मुद्दा हो सकता है।

16

मुझे लगता है कि यह बेहतर समाधान है, क्योंकि कम से कम राज्य से अपनी पुनर्स्थापित:

public static class WindowHelper 
{ 
    public static void BringProcessToFront(Process process) 
    { 
     IntPtr handle = process.MainWindowHandle; 
     if (IsIconic(handle)) 
     { 
      ShowWindow(handle, SW_RESTORE); 
     } 

     SetForegroundWindow(handle); 
    } 

    const int SW_RESTORE = 9; 

    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr handle); 
    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool ShowWindow(IntPtr handle, int nCmdShow); 
    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool IsIconic(IntPtr handle); 
} 

सरल कॉल:

WindowHelper.BringProcessToFront(process); 
+1

इस उत्तर को ऊपर उठाने के बाद से यह एक न्यूनतम राज्य से भी पुनर्स्थापित करता है। – oppassum

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