2010-05-16 9 views
31

से गुजरने की अनुमति देता है। मैं WPF को छोड़कर एडोब लाइटरूम (http://www.youtube.com/watch?v=87hNd3vaENE) में लाइट्स आउट/रोशनी मंद सुविधा के समान प्रभाव बनाने की कोशिश कर रहा हूं।WPF में अर्ध पारदर्शी विंडो कैसे बनाएं, जो माउस ईवेंट को

मैंने जो भी प्रयास किया वह मेरी मौजूदा विंडो के ऊपर एक और विंडो बनाने के लिए था, इसे पारदर्शी बनाएं और उस पर अर्द्ध पारदर्शी पथ ज्यामिति डालें। लेकिन मैं चाहता हूं कि माउस घटनाएं इस अर्ध पारदर्शी खिड़की (नीचे की खिड़कियों पर) से गुज़रने में सक्षम हों।

यह है कि मैं क्या है का एक सरलीकृत संस्करण है:

<Window x:Class="LightsOut.MaskWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    AllowsTransparency="True" 
    WindowStyle="None" 
    ShowInTaskbar="False" 
    Topmost="True" 
    Background="Transparent"> 

<Grid> 

    <Button HorizontalAlignment="Left" Height="20" Width="60">click</Button> 

    <Path IsHitTestVisible="False" Stroke="Black" Fill="Black" Opacity="0.3"> 

     <Path.Data> 
      <RectangleGeometry Rect="0,0,1000,1000 "/> 
     </Path.Data> 
    </Path>    

</Grid> 

खिड़की पूरी तरह से पारदर्शी है, इसलिए स्थानों पर जहां पथ को कवर नहीं करता पर, माउस घटनाओं सही से गुजरते हैं। अब तक सब ठीक है। IsHitTestvisible पथ वस्तु पर गलत पर सेट है। तो माउस घटनाएं उसी फ़ॉर्म पर अन्य नियंत्रणों से गुजरती हैं (यानी आप बटन पर क्लिक कर सकते हैं, क्योंकि यह एक ही रूप में है)।

लेकिन माउस घटनाएं पथ ऑब्जेक्ट से नीचे की खिड़कियों पर गुजरती नहीं हैं।

कोई विचार? या इस समस्या को हल करने के बेहतर तरीके?

धन्यवाद।

उत्तर

52

मैं इसी तरह की समस्या थी और एक समाधान मिल गया है:

WindowStyle = None 
Topmost = true 
AllowsTransparency = true 
कोड में खिड़की जोड़ने के लिए पीछे

:

protected override void OnSourceInitialized(EventArgs e) 
{ 
    base.OnSourceInitialized(e); 
    var hwnd = new WindowInteropHelper(this).Handle; 
    WindowsServices.SetWindowExTransparent(hwnd); 
} 

और अपने खिड़की सेट के लिए

public static class WindowsServices 
{ 
    const int WS_EX_TRANSPARENT = 0x00000020; 
    const int GWL_EXSTYLE = (-20); 

    [DllImport("user32.dll")] 
    static extern int GetWindowLong(IntPtr hwnd, int index); 

    [DllImport("user32.dll")] 
    static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); 

    public static void SetWindowExTransparent(IntPtr hwnd) 
    { 
    var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE); 
    SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT); 
    } 
} 

voila - क्लिक-थ्रू विंडो! मूल उत्तर देखें: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3cb7db6-5014-430f-a5c2-c9746b077d4f

+2

धन्यवाद यह वही है जो मैं ढूंढ रहा था। – RMK

+0

यह बहुत ही बढ़िया है, मैं बस एक और चीज पूरा करना चाहता हूं: कर्सर को छुपाएं। मूल रूप से कर्सर को किसी को भी सेट नहीं करते हैं, लेकिन इस COOOOL कोड के साथ कर्सर परिवर्तन विंडो के नीचे क्या है के आधार पर बदलता है। क्या हमारी खिड़की के माध्यम से क्लिक गिरने का कोई तरीका है और कर्सर दिखाई नहीं दे रहा है? –

+0

पूरी तरह से काम करता है! मैं WinForms एप्लिकेशन में WPF विंडो पर अपनी "क्लिक थ्रू" विधि का उपयोग करने में सक्षम था। – Alex

2

आपने जो वर्णन किया वह अपेक्षित व्यवहार की तरह लगता है। एक समाधान पथ पर {x: Null} को भरने के लिए है क्योंकि ऑब्जेक्ट को परीक्षण नहीं करने का एकमात्र निश्चित तरीका है।

0

मुझे कोई और विचार है।

क्या होगा यदि आपने माउस कर्सर के नीचे बिल्कुल सही पिक्सेल बनाया है, तो पूरी तरह से पारदर्शी? :]

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