简体   繁体   中英

PKEY_EdgeGesture_DisableTouchWhenFullscreen not working with Win 10 Anniversary Update

Can someone figure out why PKEY_EdgeGesture_DisableTouchWhenFullscreen no longer works with Win 10 Anniversary Update and how to fix the issue?

Currently I'm using Ron Schuler's code from here to disable edge gestures in my app.
It works fine in Win 10 RTM and Win 10 November Update (1151), but no longer works with Win 10 Anniversary Update. And by no longer works, I mean there is no error or exception, simply calling the method doesn't disable edge gestures.

And no, re-writing the app for Win 10 Kiosk Mode (eg. making it a Metro or Universal App) is not a solution!

As I am ac# developer not a native c++ one, I don't know how to tackle this issue...

My code in c#:

internal static class EdgeGestureUtil
{
    private static readonly short VT_BOOL = 11;
    private static readonly Guid DISABLE_TOUCH_SCREEN = new Guid("32CE38B2-2C9A-41B1-9BC5-B3784394AA44");
    private static Guid IID_PROPERTY_STORE = new Guid("886d8eeb-8cf2-4446-8d02-cdba1dbdcf99");

    #region "Structures"
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct PropertyKey
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid fmtid;
        public uint pid;

        public PropertyKey(Guid guid, UInt32 pid)
        {
            this.fmtid = guid;
            this.pid = pid;
        }
    }

    [StructLayout(LayoutKind.Explicit)]
    private struct PropVariant
    {
        [FieldOffset(0)]
        public short vt;
        [FieldOffset(2)]
        private short wReserved1;
        [FieldOffset(4)]
        private short wReserved2;
        [FieldOffset(6)]
        private short wReserved3;
        [FieldOffset(8)]
        private sbyte cVal;
        [FieldOffset(8)]
        private byte bVal;
        [FieldOffset(8)]
        private short iVal;
        [FieldOffset(8)]
        public ushort uiVal;
        [FieldOffset(8)]
        private int lVal;
        [FieldOffset(8)]
        private uint ulVal;
        [FieldOffset(8)]
        private int intVal;
        [FieldOffset(8)]
        private uint uintVal;
        [FieldOffset(8)]
        private long hVal;
        [FieldOffset(8)]
        private long uhVal;
        [FieldOffset(8)]
        private float fltVal;
        [FieldOffset(8)]
        private double dblVal;
        [FieldOffset(8)]
        public bool boolVal;
        [FieldOffset(8)]
        private int scode;
        //CY cyVal;
        [FieldOffset(8)]
        private DateTime date;
        [FieldOffset(8)]
        private System.Runtime.InteropServices.ComTypes.FILETIME filetime;
        //CLSID* puuid;
        //CLIPDATA* pclipdata;
        //BSTR bstrVal;
        //BSTRBLOB bstrblobVal;
        [FieldOffset(8)]
        private Blob blobVal;
        //LPSTR pszVal;
        [FieldOffset(8)]
        private IntPtr pwszVal;
        //LPWSTR 
        //IUnknown* punkVal;
        //IDispatch* pdispVal;
        //        IStream* pStream;
        //        IStorage* pStorage;
        //        LPVERSIONEDSTREAM pVersionedStream;
        //        LPSAFEARRAY parray;
        //        CAC cac;
        //        CAUB caub;
        //        CAI cai;
        //        CAUI caui;
        //        CAL cal;
        //        CAUL caul;
        //        CAH cah;
        //        CAUH cauh;
        //        CAFLT caflt;
        //        CADBL cadbl;
        //        CABOOL cabool;
        //        CASCODE cascode;
        //        CACY cacy;
        //        CADATE cadate;
        //        CAFILETIME cafiletime;
        //        CACLSID cauuid;
        //        CACLIPDATA caclipdata;
        //        CABSTR cabstr;
        //        CABSTRBLOB cabstrblob;
        //        CALPSTR calpstr;
        //        CALPWSTR calpwstr;
        //        CAPROPVARIANT capropvar;
        //        CHAR* pcVal;
        //        UCHAR* pbVal;
        //        SHORT* piVal;
        //        USHORT* puiVal;
        //        LONG* plVal;
        //        ULONG* pulVal;
        //        INT* pintVal;
        //        UINT* puintVal;
        //        FLOAT* pfltVal;
        //        DOUBLE* pdblVal;
        //        VARIANT_BOOL* pboolVal;
        //        DECIMAL* pdecVal;
        //        SCODE* pscode;
        //        CY* pcyVal;
        //        DATE* pdate;
        //        BSTR* pbstrVal;
        //        IUnknown** ppunkVal;
        //        IDispatch** ppdispVal;
        //        LPSAFEARRAY* pparray;
        //        PROPVARIANT* pvarVal;
        //        

        /// <summary>
        /// Helper method to gets blob data
        /// </summary>
        private byte[] GetBlob()
        {
            byte[] result = new byte[this.blobVal.Length];
            Marshal.Copy(this.blobVal.Data, result, 0, result.Length);
            return result;
        }

        /// <summary>
        /// Property value
        /// </summary>
        public object Value
        {
            get
            {
                VarEnum ve = (VarEnum)this.vt;
                switch (ve)
                {
                    case VarEnum.VT_I1:
                        return this.bVal;
                    case VarEnum.VT_I2:
                        return this.iVal;
                    case VarEnum.VT_I4:
                        return this.lVal;
                    case VarEnum.VT_I8:
                        return this.hVal;
                    case VarEnum.VT_INT:
                        return this.iVal;
                    case VarEnum.VT_UI4:
                        return this.ulVal;
                    case VarEnum.VT_LPWSTR:
                        return Marshal.PtrToStringUni(this.pwszVal);
                    case VarEnum.VT_BLOB:
                        return this.GetBlob();
                    default:
                        throw new NotImplementedException("PropVariant " + ve.ToString());
                }
            }
        }
    }

    private struct Blob
    {
        public int Length;
        public IntPtr Data;

        //Code Should Compile at warning level4 without any warnings, 
        //However this struct will give us Warning CS0649: Field [Fieldname] 
        //is never assigned to, and will always have its default value
        //You can disable CS0649 in the project options but that will disable
        //the warning for the whole project, it's a nice warning and we do want 
        //it in other places so we make a nice dummy function to keep the compiler
        //happy.
        private void FixCS0649()
        {
            this.Length = 0;
            this.Data = IntPtr.Zero;
        }
    }
    #endregion

    #region "Interfaces"
    [ComImport(), Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IPropertyStore
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetCount([In(), Out()] ref uint cProps);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetAt([In()] uint iProp, ref PropertyKey pkey);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetValue([In()] ref PropertyKey key, ref PropVariant pv);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void SetValue([In()] ref PropertyKey key, [In()] ref PropVariant pv);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void Commit();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void Release();
    }
    #endregion

    #region "Methods"
    [DllImport("shell32.dll", SetLastError = true)]
    private static extern int SHGetPropertyStoreForWindow(IntPtr handle, ref Guid riid, ref IPropertyStore propertyStore);

    internal static void DisableEdgeGestures(IntPtr hwnd, bool disable)
    {
        IPropertyStore pPropStore = null;
        int hr = EdgeGestureUtil.SHGetPropertyStoreForWindow(hwnd, ref EdgeGestureUtil.IID_PROPERTY_STORE, ref pPropStore);
        if (hr == 0)
        {
            PropertyKey propKey = new PropertyKey();
            propKey.fmtid = EdgeGestureUtil.DISABLE_TOUCH_SCREEN;
            propKey.pid = 2;

            PropVariant var = new PropVariant();
            var.vt = EdgeGestureUtil.VT_BOOL;
            var.boolVal = disable;

            pPropStore.SetValue(ref propKey, ref var);
            Marshal.FinalReleaseComObject(pPropStore);
        }
    }
    #endregion
}

I have found a workaround:

How to disable touchscreen edge swipes in Windows 10 (Anniversary Edition only)

1) Open Registry Editor.
2) Go to the following Registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EdgeUI

You probably don't have such a key, so just create it.

3) Create a new 32-bit DWORD value named AllowEdgeSwipe . Leave its value data as 0 (zero) to disable edge swipes.
4) To apply the changes restart Windows 10.

This will of course disable edge swipes permanently. The previous PKEY_EdgeGesture_DisableTouchWhenFullscreen method allowed disabling edge swipes only when your app was running...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM