首页 新闻 会员 周边

发现WPF中一个关于TouchDown事件和MouseDown事件的激活窗口的问题。

0
悬赏园豆:5 [待解决问题]

TrayWindow和MenuWindow两个窗口,程序启动时都显示。
在鼠标点击一下TrayWindow或者在触摸屏上触碰一下TrayWindow,如果MenuWindow是显示的就隐藏,如果是隐藏的就显示。
此外,MenuWindow在Deactivated时也会隐藏自己。
代码如下
App.xaml

<Application x:Class="TouchTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Startup="Application_Startup">
</Application>

 

App.xaml.cs

using System;
using System.Windows;

namespace TouchTest
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            MenuWindow menuWin = new MenuWindow();
            TrayWindow trayWin = new TrayWindow(menuWin);            
            trayWin.Show();
            menuWin.Show();
        }
    }
}


MenuWindow.xaml

<Window x:Class="TouchTest.MenuWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Menu" Height="300" Width="300" Deactivated="Window_Deactivated">
</Window>


MenuWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Diagnostics;

namespace TouchTest
{
    public partial class MenuWindow : Window
    {
        public MenuWindow()
        {
            InitializeComponent();
        }

        private void Window_Deactivated(object sender, EventArgs e)
        {
            Debug.WriteLine("Hide By Window_Deactivated");
            Hide();
        }
    }
}


TrayWindow.xaml

<Window x:Class="TouchTest.TrayWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Tray" Height="202" Width="279" 
        TouchDown="Window_TouchDown" MouseDown="Window_MouseDown"
        Closed="Window_Closed">
</Window>

 

TrayWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Windows.Input;
using System.Windows.Interop;

namespace TouchTest
{
    public partial class TrayWindow : Window
    {
        private MenuWindow m_MenuWindow;

        public TrayWindow(MenuWindow menuWindow)
        {
            InitializeComponent();
            m_MenuWindow = menuWindow;
        }        

        private void Window_TouchDown(object sender, TouchEventArgs e)
        {            
            if (m_MenuWindow.Visibility == Visibility.Visible)
            {
                Debug.WriteLine("Hide By Window_TouchDown");
                m_MenuWindow.Hide();
            }
            else
            {
                Debug.WriteLine("Show By Window_TouchDown");
                m_MenuWindow.Show();
            }
            e.Handled = true;            
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            
            if (m_MenuWindow.Visibility == Visibility.Visible)
            {
                Debug.WriteLine("Hide By Window_MouseDown");
                m_MenuWindow.Hide();
            }
            else
            {
                Debug.WriteLine("Show By Window_MouseDown");
                m_MenuWindow.Show();
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Application.Current.Shutdown();
        }        
    }
}


问是通过鼠标点击可以正常的显示隐藏MenuWindow.
但是MenuWindow显示后,在触摸屏上点击TrayWindow,MenuWindow会闪一下,不会隐藏。

经过调试发现,MenuWindow显示后,在TrayWindow中点击鼠标时,MenuWindow先被Deactivated, 此时MenuWindow就被隐藏,而且TrayWindow收不到MouseDown事件。
而在MenuWindow显示后,通过触摸屏点击TrayWindow,MenuWindow也是先被Deactivated,此时MenuWindow也被隐藏了,但是紧接着TrayWindow收到了TouchDown事件,由于此时MenuWindow已经不可见,TouchDown处理函数就把MenuWindow显示出来。这也是MenuWindow闪一下的原因。

经过查看MSDN中WM_MOUSEACTIVATE(https://msdn.microsoft.com/EN-US/library/windows/desktop/ms645612%28v=vs.85%29.aspx)的介绍,在TrayWindow中加入如下的代码,拦截WM_MOUSEACTIVATE,但是没有效果。

 protected override void OnSourceInitialized(System.EventArgs e)
 {
     HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
     if (source != null) source.AddHook(WndProc);  
 }

 private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
 {
     if (msg != 0x0021)
     {
         return IntPtr.Zero;
     }
     else
     {
         handled = true;
         return new IntPtr(2);
     }
 } 

 

有什么办法让MouseDown消息和TouchDown消息的效果一致。

TJC2015的主页 TJC2015 | 初学一级 | 园豆:194
提问于:2015-06-04 00:06
< >
分享
所有回答(1)
0

应该用TouchUp吧?代表整个触摸动作已经完成。另外可以自己设置一个Flag去处理点击MenuWindow时另外一个窗口变成Deactivated的情况呀。

XiaoFaye | 园豆:3087 (老鸟四级) | 2015-06-04 08:41
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册