2008-10-16 17 views
23

मैं Vista के लिए एक alt-tab प्रतिस्थापन बना रहा हूं लेकिन मुझे सभी सक्रिय प्रोग्राम सूचीबद्ध करने में कुछ समस्याएं हैं।alt-tab की तरह विंडोज़

मैं विंडोज की सूची प्राप्त करने के लिए EnumWindows का उपयोग कर रहा हूं, लेकिन यह सूची बहुत बड़ी है। इसमें लगभग 400 आइटम होते हैं जब मेरे पास केवल 10 खिड़कियां खुलती हैं। ऐसा लगता है कि हर एक नियंत्रण और कई अन्य सामानों के लिए एक झुकाव है।

इसलिए मुझे इस सूची को किसी भी तरह फ़िल्टर करना होगा, लेकिन मैं इसे बिल्कुल ठीक करने के लिए प्रबंधित नहीं कर सकता जैसे कि alt-tab करता है।

यह वह कोड है जिसका उपयोग मैं अभी सूची को फ़िल्टर करने के लिए करता हूं। यह बहुत अच्छी तरह से काम करता है, लेकिन मुझे विजुअल स्टूडियो में अलग-अलग टूल-विंडोज जैसी कुछ अवांछित खिड़कियां मिलती हैं और मुझे आईट्यून्स और वॉरक्राफ्ट 3 जैसी विंडोज़ भी याद आती है।

private bool ShouldWindowBeDisplayed(IntPtr window) 
{ 
    uint windowStyles = Win32.GetWindowLong(window, GWL.GWL_STYLE); 

    if (((uint)WindowStyles.WS_VISIBLE & windowStyles) != (uint)WindowStyles.WS_VISIBLE || 
     ((uint)WindowExStyles.WS_EX_APPWINDOW & windowStyles) != (uint)WindowExStyles.WS_EX_APPWINDOW) 
    { 
     return true; 
    } 
    return false; 
} 

उत्तर

23

रेमंड चेन यह एक समय पहले (http://blogs.msdn.com/oldnewthing/archive/2007/10/08/5351207.aspx) ने उत्तर दिया:

यह वास्तव में बहुत आसान है, हालांकि शायद ही कुछ भी आप अपने दम पर अनुमान करने में सक्षम होगी। नोट: इस एल्गोरिदम का विवरण एक कार्यान्वयन विवरण है। यह किसी भी समय बदल सकता है, इसलिए इस पर भरोसा न करें। वास्तव में, यह पहले से ही फ्लिप और फ्लिप 3 डी के साथ बदल गया है; मैं बस क्लासिक Alt + Tab विंडो के बारे में बात कर रहा हूं।

प्रत्येक दृश्यमान विंडो के लिए, स्वामी श्रृंखला तक चलें जब तक आप रूट स्वामी नहीं पाते। फिर दृश्यमान पिछली सक्रिय पॉपअप श्रृंखला को वापस चलाएं जब तक आपको एक दृश्यमान विंडो नहीं मिल जाती। यदि आप पर वापस आ गए हैं, जहां आप प्रारंभ कर चुके हैं, तो Alt + Tab सूची में विंडो डालें। छद्म कोड में:

BOOL IsAltTabWindow(HWND hwnd) 
{ 
// Start at the root owner 
HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER); 

// See if we are the last active visible popup 
HWND hwndTry; 
while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) { 
    if (IsWindowVisible(hwndTry)) break; 
    hwndWalk = hwndTry; 
} 
return hwndWalk == hwnd; 
} 

अधिक जानकारी के लिए और कुछ कोने स्थितियों के लिए चेन के ब्लॉग प्रविष्टि के लिए लिंक का पालन करें।

+0

ध्यान दें कि यह कार्यान्वयन रेमंड के ब्लॉग पोस्ट में वर्णित 'WS_EX_TOOLWINDOW' और' WS_EX_APPWINDOW' विस्तारित शैलियों का सम्मान नहीं करता है। –

+3

यहां इस विधि के आधार पर एक और पूर्ण और मजबूत उदाहरण है https://github.com/christianrondeau/GoToWindow/blob/e41b822e7254fdc40a40fbbeec251e6ffc1959f8/GoToWindow.Api/WindowsListFactory.cs#L45 यह एक वैकल्पिक alt-tab उपयोगिता से है, जो दिखता है बिल्कुल नियमित alt-tab मेनू क्या करता है। – blade

11

धन्यवाद माइक बी रेमंड्स ब्लॉग के उदाहरण ने मुझे सही दिशा में इंगित किया।

वहाँ हालांकि कुछ अपवाद भी हैं कि किए जाने के लिए कर रहे हैं, विंडोज लाइव मैसेंजर खिड़कियों आदि के तहत छाया बनाने के लिए हैक्स की बहुत मिल गया: @

यहाँ मेरा पूरा कोड, एक दिन अब और Havn के लिए उपयोग किया गया है है वास्तविक alt टैब से कोई अंतर नहीं देखा है। कुछ अंतर्निहित कोड पोस्ट नहीं किया गया है लेकिन यह पता लगाने में कोई समस्या नहीं है कि यह क्या करता है। :)

private static bool KeepWindowHandleInAltTabList(IntPtr window) 
    { 
     if (window == Win32.GetShellWindow()) //Desktop 
      return false; 

     //http://stackoverflow.com/questions/210504/enumerate-windows-like-alt-tab-does 
     //http://blogs.msdn.com/oldnewthing/archive/2007/10/08/5351207.aspx 
     //1. For each visible window, walk up its owner chain until you find the root owner. 
     //2. Then walk back down the visible last active popup chain until you find a visible window. 
     //3. If you're back to where you're started, (look for exceptions) then put the window in the Alt+Tab list. 
     IntPtr root = Win32.GetAncestor(window, Win32.GaFlags.GA_ROOTOWNER); 

     if (GetLastVisibleActivePopUpOfWindow(root) == window) 
     { 
      WindowInformation wi = new WindowInformation(window); 

      if (wi.className == "Shell_TrayWnd" ||       //Windows taskbar 
       wi.className == "DV2ControlHost" ||       //Windows startmenu, if open 
       (wi.className == "Button" && wi.windowText == "Start") || //Windows startmenu-button. 
       wi.className == "MsgrIMEWindowClass" ||      //Live messenger's notifybox i think 
       wi.className == "SysShadow" ||        //Live messenger's shadow-hack 
       wi.className.StartsWith("WMP9MediaBarFlyout"))    //WMP's "now playing" taskbar-toolbar 
       return false; 

      return true; 
     } 
     return false; 
    } 

    private static IntPtr GetLastVisibleActivePopUpOfWindow(IntPtr window) 
    { 
     IntPtr lastPopUp = Win32.GetLastActivePopup(window); 
     if (Win32.IsWindowVisible(lastPopUp)) 
      return lastPopUp; 
     else if (lastPopUp == window) 
      return IntPtr.Zero; 
     else 
      return GetLastVisibleActivePopUpOfWindow(lastPopUp); 
    } 
+5

'विंडो सूचना' कहां से आती है? मैंने इसे कई तरीकों से गुगल किया है और कुछ भी उपयोगी नहीं है। क्या यह एक कस्टम प्रकार है? –

+0

आप इसका उपयोग कर सकते हैं: https://github.com/akfish/MwLib/blob/master/Native/WindowInfo.cs – joshcomley

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