2017-06-29 44 views
9

में कुछ तत्वों पर झूठा रिटर्न देता है, जब मैं वीएस 2017 टाइटल बार में प्रवेश करता हूं तो पता लगाने की कोशिश कर रहा हूं, लेकिन मैंने देखा है कि MouseEnter और MouseLeave ईवेंट सही तरीके से काम नहीं करते हैं। घटना केवल तभी आग लगती है जब माउस नीचे स्क्रीनशॉट पर हरे रंग के आयत द्वारा उल्लिखित बाल नियंत्रण में प्रवेश करता है।IsMouseOver DockPanel

शीर्षक बार DockPanel इसमें कुछ तत्वों के साथ है। यह सुनिश्चित करने के लिए कि हिट टेस्ट सही ढंग से चलता है, मैंने अपनी पृष्ठभूमि SolidColorBrush(Colors.Red) पर सेट की है। जब माउस हरे आयत में तत्वों से अधिक होता है IsMouseOver सही ढंग से सत्य देता है, लेकिन हर जगह यह गलत है। मेनू बार के लिए, IsMouseOver और MouseEnter और MouseLeave ईवेंट सही तरीके से काम करते हैं। क्या गलत हो सकता है?

Screenshot

अद्यतन 2: यह संभावना है कि शीर्षक पट्टी गैर क्लाइंट क्षेत्र के रूप में चिह्नित किया गया है और यह है कि क्या इस समस्या

अद्यतन का कारण बनता है:

यहाँ है दृश्य ट्री मुख्य वीएस विंडो का:

enter image description here

के लिए

using Microsoft.VisualStudio.PlatformUI.Shell.Controls; 
using Microsoft.VisualStudio.Shell; 
using System; 
using System.Windows; 
using System.Windows.Automation.Peers; 
using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Interop; 
using System.Windows.Media; 

namespace Microsoft.VisualStudio.PlatformUI 
{ 
    public sealed class MainWindowTitleBar : Border, INonClientArea 
    { 
     protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) 
     { 
      return new PointHitTestResult(this, hitTestParameters.HitPoint); 
     } 

     int INonClientArea.HitTest(Point point) 
     { 
      return 2; 
     } 

     protected override AutomationPeer OnCreateAutomationPeer() 
     { 
      return new MainWindowTitleBarAutomationPeer(this); 
     } 

     protected override void OnContextMenuOpening(ContextMenuEventArgs e) 
     { 
      if (!e.Handled) 
      { 
       HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; 
       if (hwndSource != null) 
       { 
        CustomChromeWindow.ShowWindowMenu(hwndSource, this, Mouse.GetPosition(this), base.RenderSize); 
       } 
       e.Handled = true; 
      } 
     } 
    } 
} 

निकाले XAML: 210

MainWindowTitleBar वर्ग decompiled

<mwtb:MainWindowTitleBar Name="MainWindowTitleBar" x:Uid="vs:MainWindowTitleBar_1" Grid.Row="0" Grid.Column="0" Background="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowActiveCaptionBrushKey}}" TextElement.Foreground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowActiveCaptionTextBrushKey}}"> 
    <DockPanel x:Uid="DockPanel_2"> 
    <wcp:SystemMenu Name="SystemMenu" x:Uid="Image_1" Source="{TemplateBinding Window.Icon}" VectorFill="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowActiveIconDefaultBrushKey}}" Width="32" Height="27" Margin="0,0,12,4" Padding="12,7,0,0" DockPanel.Dock="Left" VectorIcon="{Binding Source={x:Static Application.Current}, Path=VectorIcon}" /> 
    <StackPanel Name="WindowTitleBarButtons" x:Uid="WindowTitleBarButtons" Orientation="Horizontal" DockPanel.Dock="Right"> 
     <wcp:WindowTitleBarButton Name="MinimizeButton" x:Uid="MinimizeButton" VerticalAlignment="Top" Command="{x:Static vsc:ViewCommands.MinimizeWindow}" BorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveBorderBrushKey}}" BorderThickness="1,0,1,1" GlyphForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveGlyphBrushKey}}" HoverBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBrushKey}}" HoverBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBorderBrushKey}}" HoverForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveGlyphBrushKey}}" HoverBorderThickness="1,0,1,1" PressedBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBrushKey}}" PressedBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBorderBrushKey}}" PressedForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownGlyphBrushKey}}" PressedBorderThickness="1,0,1,1" Padding="0,3,0,0" Width="34" Height="26" AutomationProperties.Name="Minimize" AutomationProperties.AutomationId="Minimize" ToolTip="{x:Static vs:MainWindowResources.WindowMinimizeToolTip}" CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"> 
     <Path Name="MinimizeButtonPath" x:Uid="MinimizeButtonPath" Width="9" Height="9" Stretch="None" Data="F1M0,6L0,9 9,9 9,6 0,6z" Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}" /> 
     </wcp:WindowTitleBarButton> 
     <wcp:WindowTitleBarButton Name="MaximizeRestoreButton" x:Uid="MaximizeRestoreButton" VerticalAlignment="Top" Command="{x:Static vsc:ViewCommands.ToggleMaximizeRestoreWindow}" BorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveBorderBrushKey}}" BorderThickness="1,0,1,1" GlyphForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveGlyphBrushKey}}" HoverBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBrushKey}}" HoverBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBorderBrushKey}}" HoverForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveGlyphBrushKey}}" HoverBorderThickness="1,0,1,1" PressedBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBrushKey}}" PressedBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBorderBrushKey}}" PressedForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownGlyphBrushKey}}" PressedBorderThickness="1,0,1,1" Padding="0,3,0,0" Width="34" Height="26" AutomationProperties.Name="Maximize" AutomationProperties.AutomationId="Maximize" ToolTip="{x:Static vs:MainWindowResources.WindowMaximizeToolTip}" CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"> 
     <Path Name="MaximizeRestoreButtonPath" x:Uid="MaximizeRestoreButtonPath" Width="9" Height="9" Stretch="Uniform" Data="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,8 1,3z" Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}" /> 
     </wcp:WindowTitleBarButton> 
     <wcp:WindowTitleBarButton Name="HideButton" x:Uid="HideButton" VerticalAlignment="Top" Command="{x:Static vsc:ViewCommands.CloseWindow}" BorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveBorderBrushKey}}" BorderThickness="1,0,1,1" GlyphForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonActiveGlyphBrushKey}}" HoverBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBrushKey}}" HoverBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveBorderBrushKey}}" HoverForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonHoverActiveGlyphBrushKey}}" HoverBorderThickness="1,0,1,1" PressedBackground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBrushKey}}" PressedBorderBrush="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownBorderBrushKey}}" PressedForeground="{DynamicResource {x:Static ui:EnvironmentColors.MainWindowButtonDownGlyphBrushKey}}" PressedBorderThickness="1,0,1,1" Padding="0,3,0,0" Width="34" Height="26" AutomationProperties.Name="Close" AutomationProperties.AutomationId="Close" ToolTip="{x:Static vs:MainWindowResources.WindowCloseToolTip}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"> 
     <Path Name="HideButtonPath" x:Uid="HideButtonPath" Width="10" Height="8" Stretch="Uniform" Data="F1M0,0L2,0 5,3 8,0 10,0 6,4 10,8 8,8 5,5 2,8 0,8 4,4 0,0z" Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource Self}}" /> 
     </wcp:WindowTitleBarButton> 
    </StackPanel> 
    <mwtb:FrameControlContainer Name="PART_TitleBarFrameControlContainer" x:Uid="PART_TitleBarFrameControlContainer" DockPanel.Dock="Right" TextElement.FontSize="{DynamicResource VsFont.EnvironmentFontSize}" TextElement.FontFamily="{DynamicResource VsFont.EnvironmentFontFamily}" Margin="0,0,2,0" DataContext="{Binding FrameControls}" /> 
    <TextBlock x:Uid="TextBlock_1" Text="{TemplateBinding Window.Title}" TextBlock.FontFamily="{DynamicResource VsFont.CaptionFontFamily}" TextBlock.FontSize="{DynamicResource VsFont.CaptionFontSize}" TextBlock.FontWeight="{DynamicResource VsFont.CaptionFontWeight}" TextTrimming="CharacterEllipsis" VerticalAlignment="Center" Margin="0,7,0,4" /> 
    </DockPanel> 
</mwtb:MainWindowTitleBar> 
+0

एक और StackPanel या DockPanel कि क्षेत्र है जिसमें आप हेवन 'पर यह खत्म हो गया है पृष्ठभूमि के लिए सेट सेट? –

+0

नहीं, वीएस में बहुत ही सरल दृश्य पेड़ है। प्रासंगिक विवरण के साथ मेरा प्रश्न अपडेट किया गया। मुझे लगता है कि शायद इसके माता-पिता 'INONClientArea' को लागू करने और' HitTestCore' को ओवरराइड करने के साथ कुछ करने के लिए कुछ है, लेकिन मुझे नहीं लगता कि यह वास्तविक हिट टेस्ट को अब तक कैसे प्रभावित कर सकता है। – Poma

+0

क्या आपने 'IsHitTestVisible' संपत्ति मान की जांच की थी? – grek40

उत्तर

1

मेरे मूल जवाब गैर ग्राहक माउस आंदोलनों पता लगाने में सक्षम था, लेकिन माउस नहीं छोड़ा जब। ऐसा करने के लिए ओपी की TrackMouseEvent का उपयोग करने की आवश्यकता के आधार पर, मैंने एक पूर्ण-कार्य करने वाला उदाहरण दिखाने के लिए अपना उत्तर अपडेट कर दिया है।

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

एक वी.एस. विस्तार के भीतर से, हुक इस के साथ शुरू होता है:

IntPtr vsHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; 
HwndSource source = HwndSource.FromHwnd(vsHandle); 
source.AddHook(new HwndSourceHook(WndProc)); 

समर्थन कोड है:

private const int WM_NCHITTEST = 0x0084; 
private const int WM_NCMOUSEMOVE = 0x00a0; 
private const int WM_NCMOUSELEAVE = 0x02a2; 

private enum HtResult 
{ 
    HTERROR = (-2), 
    HTTRANSPARENT = (-1), 
    HTNOWHERE = 0, 
    HTCLIENT = 1, 
    HTCAPTION = 2, 
    HTSYSMENU = 3, 
    HTGROWBOX = 4, 
    HTSIZE = HTGROWBOX, 
    HTMENU = 5, 
    HTHSCROLL = 6, 
    HTVSCROLL = 7, 
    HTMINBUTTON = 8, 
    HTMAXBUTTON = 9, 
    HTLEFT = 10, 
    HTRIGHT = 11, 
    HTTOP = 12, 
    HTTOPLEFT = 13, 
    HTTOPRIGHT = 14, 
    HTBOTTOM = 15, 
    HTBOTTOMLEFT = 16, 
    HTBOTTOMRIGHT = 17, 
    HTBORDER = 18, 
    HTREDUCE = HTMINBUTTON, 
    HTZOOM = HTMAXBUTTON, 
    HTSIZEFIRST = HTLEFT, 
    HTSIZELAST = HTBOTTOMRIGHT, 
    HTOBJECT = 19, 
    HTCLOSE = 20, 
    HTHELP = 21 
} 

[Flags] 
public enum TMEFlags : uint 
{ 
    TME_CANCEL = 0x80000000, 
    TME_HOVER = 0x00000001, 
    TME_LEAVE = 0x00000002, 
    TME_NONCLIENT = 0x00000010, 
    TME_QUERY = 0x40000000 
} 

[DllImport("user32.dll")] 
static extern int TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack); 

[StructLayout(LayoutKind.Sequential)] 
public struct TRACKMOUSEEVENT 
{ 
    public int cbSize; 
    public TMEFlags dwFlags; 
    public IntPtr hwndTrack; 
    public int dwHoverTime; 
} 

private bool _trackingMouseMove; 
private TRACKMOUSEEVENT _tme; 

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    if (msg == WM_NCMOUSEMOVE) 
    { 
     if (!_trackingMouseMove) 
     { 
      _tme = new TRACKMOUSEEVENT(); 
      _tme.hwndTrack = hwnd; 
      _tme.cbSize = Marshal.SizeOf(typeof(TRACKMOUSEEVENT)); 
      _tme.dwFlags = TMEFlags.TME_NONCLIENT | TMEFlags.TME_LEAVE; 
      int success = TrackMouseEvent(ref _tme); 
      _trackingMouseMove = (success != 0); 
     } 

     var hitTestResult = (HtResult)wParam; 

     if ((hitTestResult == HtResult.HTSYSMENU) || (hitTestResult == HtResult.HTCAPTION)) 
     { 
      // Raise event here 
      System.Diagnostics.Debug.WriteLine("Mouse over title bar"); 
     } 
    } 
    else if (msg == WM_NCMOUSELEAVE) 
    { 
     _trackingMouseMove = false; 
     System.Diagnostics.Debug.WriteLine("Mouse left the title bar"); 
    } 

    return IntPtr.Zero; 
} 
+0

यह सुनिश्चित नहीं है कि यह डाउनवॉट क्यों प्राप्त हुआ, यह एक सही समाधान की तरह लगता है हालांकि यह पी/Invoke का उपयोग करता है। अफसोस की बात है कि मैंने अपने प्रश्न को बुरी तरह तैयार किया है और यह उल्लेख करना भूल गया है कि मेरी प्रारंभिक समस्या माउसइंटर और माउसलेव घटनाओं की सदस्यता ले रही है जो गलत तरीके से काम करती हैं (IsMouseOver एक ऐसा लक्षण है जो डीबग करना आसान है) और आपका समाधान मेरी प्रारंभिक समस्या को हल नहीं करता है। मैंने इसे प्रतिबिंबित करने के लिए अपना प्रश्न संपादित कर लिया है। – Poma

+0

एफडब्ल्यूआईडब्लू, इसे पोस्ट करने से पहले, मैंने यह जांचने के लिए डब्ल्यूपीएफ स्नूप का इस्तेमाल किया कि मेनविंडो टिटलेबार किस माउस इवेंट्स का जवाब देता है। यह किसी भी माउस इवेंट (या कोई अन्य घटना जिसे मैं देख सकता था) का जवाब नहीं देता, इसलिए यह पी/आमंत्रण के बिना _may_ संभव नहीं है। मैं देख रहा हूं कि दूसरों को क्या मिल सकता है। – cokeman19

+0

लेकिन यह एक WPF पैनल के लिए तकनीकी रूप से संभव है जो माउस घटनाओं का जवाब नहीं देता है? – Poma

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