加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C#/WPF 获取屏幕触摸消息的方法

(2011-08-24 16:54:40)
标签:

wpf

wm_touch

wndpro

c

获取

分类: 编程技术

using System;

using System.Diagnostics;

using System.IO;

using System.Reflection;

using System.Runtime.InteropServices;

using System.Windows;

using System.Windows.Input;

using System.Windows.Interop;


namespace TouchDelayTestDemo

{

    ///

    /// Interaction logic for MainWindow.xaml

    ///

    public partial class MainWindow : Window

    {

        // Touch API defined structures [winuser.h]

        [StructLayout(LayoutKind.Sequential)]

        public struct TOUCHINPUT

        {

            public int x;

            public int y;

            public System.IntPtr hSource;

            public int dwID;

            public int dwFlags;

            public int dwMask;

            public int dwTime;

            public System.IntPtr dwExtraInfo;

            public int cxContact;

            public int cyContact;

        }


        [StructLayout(LayoutKind.Sequential)]

        public struct POINTS

        {

            public short x;

            public short y;

        }


        private IntPtr _handle;


        // Attributes

        private int touchInputSize; // size of TOUCHINPUT structure


        /// 定义触摸消息,来自winuser.h

        public const int WM_TOUCH = 0x0240;

        // Touch event flags ((TOUCHINPUT.dwFlags) [winuser.h]

        private const int TOUCHEVENTF_MOVE = 0x0001;

        private const int TOUCHEVENTF_DOWN = 0x0002;

        private const int TOUCHEVENTF_UP = 0x0004;


        // Currently touch/multitouch access is done through unmanaged code

        // We must p/invoke into user32 [winuser.h]

        [DllImport("user32")]

        public static extern bool RegisterTouchWindow(System.IntPtr hWnd, int flags);


        [DllImport("user32")]

        public static extern bool GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs,

            [In, Out] TOUCHINPUT[] pInputs, int cbSize);


        public MainWindow()

        {

            InitializeComponent();

            DisableWPFTabletSupport();

            this.Show();

            _handle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;

            if (!RegisterTouchWindow(_handle, 0))

            {

                Debug.Print("ERROR: Could not register window for multi-touch");

            }

            // GetTouchInputInfo needs to be

            // passed the size of the structure it will be filling.

            // We get the size upfront so it can be used later.

            touchInputSize = Marshal.SizeOf(new TOUCHINPUT());


            var hwndSource = HwndSource.FromHwnd(_handle);

            if (hwndSource != null)

                hwndSource.AddHook(WndProc);

        }

        // 详见:使WPF自身触摸不可用       

        public static void DisableWPFTabletSupport()

        {

            // Get a collection of the tablet devices for this window.  

            TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;


            if (devices.Count > 0)

            {

                // Get the Type of InputManager.

                Type inputManagerType = typeof(System.Windows.Input.InputManager);


                // Call the StylusLogic method on the InputManager.Current instance.

                object stylusLogic = inputManagerType.InvokeMember("StylusLogic",

                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,

                    null, InputManager.Current, null);


                if (stylusLogic != null)

                {

                    //  Get the type of the stylusLogic returned from the call to StylusLogic.

                    Type stylusLogicType = stylusLogic.GetType();


                    // Loop until there are no more devices to remove.

                    while (devices.Count > 0)

                    {

                        // Remove the first tablet device in the devices collection.

                        stylusLogicType.InvokeMember("OnTabletRemoved",

                            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,

                            null, stylusLogic, new object[] { (uint)0 });

                    }

                }


            }

        }


        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

        {

            switch (msg)

            {

                case WM_TOUCH:

                    handled = DecodeTouch(wParam, lParam);

                    break;

            }

            return (IntPtr)0;

        }


        // Extracts lower 16-bit word from an 32-bit int.

        // in:

        //      number      int

        // returns:

        //      lower word

        private static int LoWord(int number)

        {

            return (number & 0xffff);

        }


        // Decodes and handles WM_TOUCH message.

        // Unpacks message arguments and invokes appropriate touch events.

        // returns:

        //      whether the message has been handled

        private bool DecodeTouch(IntPtr wParam, IntPtr lParam)

        {

            // More than one touchinput may be associated with a touch message,

            // so an array is needed to get all event information.

            int inputCount = LoWord(wParam.ToInt32()); // Number of touch inputs, actual per-contact messages


            TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures

            inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages


            // Unpack message parameters into the array of TOUCHINPUT structures, each

            // representing a message for one single contact.

            if (!GetTouchInputInfo(lParam, inputCount, inputs, touchInputSize))

            {

                // Get touch info failed.

                return false;

            }


            // For each contact, dispatch the message to the appropriate message

            // handler.

            bool handled = false; // Boolean, is message handled

            for (int i = 0; i < inputCount; i++)

            {

                TOUCHINPUT ti = inputs[i];

                int screenPointX = ti.x / 100;

                int screenPointY = ti.y / 100; 

                // Assign a handler to this message.

                if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0) /// 按下

                {


                }

                else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0) /// 移动

                {


                }

                else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0) /// 弹起

                {

                }


                // Mark this event as handled.

                handled = true;

            }

            return handled;

        }

    }

}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有