2010-02-23 12 views
15

वर्तमान में स्विट के साथ, मैं कभी-कभी एक कार्यक्रम चाहता हूं कि मनमाने ढंग से अग्रभूमि (जैसे अलार्म घड़ी की तरह) आ जाए।आप जावा स्विट प्रोग्राम को "अग्रभूमि में ले जाने" के लिए कैसे मजबूर करते हैं?

आमतौर पर निम्नलिखित काम करता है (JRuby):

@shell.setMinimized(false) 
@shell.forceActive 

यह सामने से खोल अगर यह कम से कम किया गया था लाता है।

किसी भी समय एक नया खोल बनाना भी सामने (नया खोल) लाता है।

अभी तक इतना अच्छा है, हालांकि, यदि खोल कम नहीं है, तो उपरोक्त कोड टास्कबार में ऐप के आइकन को चमकता है (ब्लिंक) करता है। वास्तव में पहली बार जब आप इसे चलाते हैं, तो यह इसे सामने लाता है। उसके बाद, यह टास्कबार में बस झपकी देता है। वह खिड़कियां है लिनक्स पर यह केवल टास्कबार (उबंटू डिफ़ॉल्ट) में झपकी लग रहा है।

क्या कोई एप को सामने आने के लिए एप प्राप्त करने के क्रॉस प्लेटफ़ॉर्म तरीके के बारे में जानता है?

ऐसा लगता है कि बल का कोई इन्सेंटिव सेट एक्टिव सेटमैनिमाइज्ड (झूठा) सेट फोकस फोर्स फोकस और सेट विज़िबल इस चीज़ को पूरा कर सकता है।

मुझे यकीन है कि यह संभव है (कम से कम विंडोज़ में), जैसा कि ई टेक्स्ट एडिटर करता है। खैर, यह swt नहीं है, लेकिन कम से कम कुछ अन्य ऐप्स have been known to do it

मुझे लगता है कि यह शायद swt bug 192036 है?

बहुत धन्यवाद।

संबंधित:

+0

ऐसा लगता है कि आपने जो भी एसटीटी बग ** से जुड़ा हुआ है, ठीक है ** आपकी समस्या का वर्णन करता है, और ऐसा लगता है कि वे इसे ठीक करने में सक्षम नहीं होंगे। –

+0

मुझे लगता है कि वास्तव में विंडोज़ के लिए समस्या है - अच्छी पकड़। अब के लिए काम करना सबसे पहले एक खोल को कम करना है, फिर इसे कम करें (या कुछ देशी कोड [एफएफआई या जेनी के माध्यम से] को मजबूर करने के लिए इसका उपयोग करें)। लिनक्स में मुझे पूरा यकीन नहीं है कि समस्या क्या है (केवल टास्क ट्रे में ब्लिंक)। यह * swt.jar के नए संस्करणों में तय किया जा सकता है> = 3.5 https://bugs.eclipse.org/bugs/show_bug.cgi?id = 244597 – rogerdpack

उत्तर

5

http://github.com/rdp/redcar/commit/d7dfeb8e77f13e5596b11df3027da236f23c83f0

दिखाता है कि कैसे मैं इसे खिड़कियों में किया था, वैसे भी (ffi का उपयोग)।

उपयोगी चाल के एक जोड़े को हो "हो सकता है"

BringToFront.SetForegroundWindow के बाद एक 'नींद 0.1' जोड़ने (चाहता था) कॉल (उम्मीद यह एक नहीं वास्तव में आवश्यक है)।

के बाद एक shell.set_active जोड़ें, आपने विंडो को अग्रभूमि में लाया है। कुछ कारणों से बल एक्टिव सेटएक्टिव को कॉल नहीं करता है।

एनबी जो सेट एक्टिव एक user32.dll BringWindowToTop कॉल करता है, और थ्रेड इनपुट को अलग करने से पहले इसे करने की आवश्यकता होती है।

भी ध्यान रखें कि ऐसा लगता है अगर आप सही क्रम आप सभी पर धागा इनपुट हैक उपयोग करने की आवश्यकता नहीं हो सकता है (?)

http://betterlogic.com/roger/?p=2950

(पर कैसे कई अच्छा संकेत होता है में कॉल कर सकते हैं करने के लिए वास्तव में इस सही लिनक्स पर

करते हैं), forceActive काम करता है - लेकिन केवल जब तक आप एक और कुछ खिड़कियों को स्थानांतरित ,, तो यह कि उसके बाद कार्य पट्टी (केवल) पर ब्लिंक। अनुमानित बग अनुमान लगा रहा है। [1]

भी संबंधित हैं:

How to bring a window to the front?

http://github.com/jarmo/win32screenshot/blob/master/lib/win32/screenshot/bitmap_maker.rb#L110 "set_foreground" जिसके साथ दोनों एक्सपी और विंडोज 7

[1] Need to bring application to foreground on Windows और https://bugs.eclipse.org/bugs/show_bug.cgi?id=303710

4

यह काम करने के लिए लगता है वास्तव में विंडोज की एक विशेषता है, जिसे ट्वीक यूआई पावर खिलौना (कम से कम विंडोज एक्सपी के लिए) के माध्यम से सक्षम किया जा सकता है। सक्षम होने पर ओ/एस जानबूझकर खिड़की को "फोकस चोरी" रोकने के लिए केंद्रित विंडो होने के लिए मजबूर कर देता है। इस प्रकार, फोकस को पकड़ने की कार्रवाई को टास्कबार आइकन को चमकाने के लिए बदला जाता है - चूंकि ओ/एस जानबूझकर उपयोगकर्ता के अनुरोध पर कार्रवाई को परिवर्तित कर रहा है, इसके बारे में आप कुछ भी नहीं कर सकते हैं (और यह एक अच्छी बात है)।

यह (संभवतः) किया गया था क्योंकि तो कई अनुप्रयोगों ने लेट-टू-फ्रंट एपीआई और व्यवहार दोनों नाराज उपयोगकर्ताओं से व्यवहार किया और उन्हें गलत एप्लिकेशन में इनपुट करने का कारण बना दिया।

+0

यदि आप बल के लिए Google हैं, तो बेहतर या बदतर के लिए आप एक कार्य देखेंगे (मुझे लगता है कि यह इसके लिए फ़ॉरंट विधि के लिए उपयोग नहीं करता है, जिसमें से swt प्रकट नहीं होता है)। मैं मानता हूं कि बल सक्रिय रूप से प्रयोग किया जाना चाहिए :) – rogerdpack

+1

उह, हां, अभी भी बहुत सारे ऐप्स हैं जो पृष्ठभूमि से पॉप अप करते हैं, इनपुट चोरी करते हैं जबकि आप किसी और चीज में व्यस्त होते हैं। मैंने इससे पहले डेटा हानि का अनुभव किया है। पृष्ठभूमि ऐप पॉप करता है "क्या आप ब्लाह को मिटाना चाहते हैं?" जबकि मैं कुछ और टाइप कर रहा हूं जिसमें "हां" के लिए चयनकर्ता शामिल होता है। अरे। –

2
private static void onTop(Shell shell) { 
     int s = -1; 
     Shell[] shells = display.getShells(); 
     for (int i = 0; i < shells.length; ++i) { 
      if (!shells[i].equals(shell)) { 
       shells[i].setEnabled(false); 
       shells[i].update(); 
      } else { 
       s = i; 
      } 
     } 
     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) 
       display.sleep(); 
     } 
     for (int i = 0; i < shells.length; ++i) { 
      if (i != s) { 
       shells[i].setEnabled(true); 
       shells[i].update(); 
      } 
     } 
    } 
4

यह विंडोज 7 और Ubuntu पर मेरे लिए काम किया:

private void bringToFront(final Shell shell) { 
    shell.getDisplay().asyncExec(new Runnable() { 
     public void run() { 
      shell.forceActive(); 
     } 
    }); 
} 
2

Bug 192036 - Shell.forceActive doesn't raise a window above all other windows

@rogerdpack's query on Eclipse bug tracker निम्नलिखित dirty workaround साथ उत्तर दिया गया कर हम क्या जरूरत है।

public void forceActive(Shell shell) { 
    int hFrom = OS.GetForegroundWindow(); 

    if (hFrom <= 0) { 
     OS.SetForegroundWindow(shell.handle); 
     return; 
    } 

    if (shell.handle == hFrom) { 
     return; 
    } 

    int pid = OS.GetWindowThreadProcessId(hFrom, null); 
    int _threadid = OS.GetWindowThreadProcessId(shell.handle, null); 

    if (_threadid == pid) { 
     OS.SetForegroundWindow(shell.handle); 
     return; 
    } 

    if (pid > 0) { 
     if (!OS.AttachThreadInput(_threadid, pid, true)) { 
     return; 
     } 
     OS.SetForegroundWindow(shell.handle); 
     OS.AttachThreadInput(_threadid, pid, false); 
    } 

    OS.BringWindowToTop(shell.handle); 
    OS.UpdateWindow(shell.handle); 
    OS.SetActiveWindow(shell.handle); 
    } 
1

आपके द्वारा शुरू में किए गए कार्यों के साथ काम करने का एक तरीका है। shell की पिछली स्थिति को पुनर्स्थापित करने के लिए आपको वास्तव में shell.setMinimized(false) पर कॉल करने और पर कॉल करने की आवश्यकता है। हालांकि, यह केवल तभी काम करता है जब shell कम से कम स्थिति में वास्तव में था। तो यहां मेरा अंतिम समाधान है, जो कृत्रिम रूप से shell को कम करता है अगर इसे पहले से कम नहीं किया गया था। यदि न्यूनतमकरण किया जाना है तो लागत एक त्वरित एनीमेशन है।

shell.getDisplay().syncExec(new Runnable() { 

    @Override 
    public void run() { 
     if (!shell.getMinimized()) 
     { 
      shell.setMinimized(true); 
     } 
     shell.setMinimized(false); 
     shell.setActive(); 
    } 
}); 
संबंधित मुद्दे

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