Disable touch visual feedback on windows 8.1 (programmatically) [Desktop App]

1

I have a C# WPF application intended specifically for Win8.1 (a desktop app, NOT metro).

I want users to be able to use touch injections but I'm trying to disable the visualization feedback that windows creates for a Tap gesture Press Hold and Drag (like selecting multiple files on desktop) and other gestures (zooming scrolling etc).

After Searching the web for a long time I've found this post: How do I disable Windows 8 touch contact visualizations for my application? So I tried to do the same...

I tried this (Will put my Win32 class at the end)

public void DisableGestureVisualization()
{
    const int SPI_SETCONTACTVISUALIZATION = 0x2019;
    const int SPI_SETGESTUREVISUALIZATION = 0x201B;
    ulong gv = 0;
    Logger.Debug(!Win32.SystemParametersInfo(SPI_SETGESTUREVISUALIZATION, 0, ref gv, 0)
        ? @"Failed SystemParametersInfo SPI_SETGESTUREVISUALIZATION"
        : @"Successfuly returned from SystemParametersInfo SPI_SETGESTUREVISUALIZATION");

    Logger.Debug(!Win32.SystemParametersInfo(SPI_SETCONTACTVISUALIZATION, 0, ref gv, 0)
        ? @"Failed SystemParametersInfo SPI_SETCONTACTVISUALIZATION"
        : @"Successfuly returned from SystemParametersInfo SPI_SETCONTACTVISUALIZATION");
}

And also this:

public void TryDisableWindowsVisualFeedback(IntPtr hWnd)
{
    bool enable = false;
    foreach (Win32.FEEDBACK_TYPE type in Enum.GetValues(typeof(Win32.FEEDBACK_TYPE)))
    {
        if (type == Win32.FEEDBACK_TYPE.FEEDBACK_MAX)
        {
            continue;
        }

        Logger.Debug(!Win32.SetWindowFeedbackSetting(hWnd, type, 0, 4, ref enable) 
               ? @"Failed to SetWindowFeedbackSetting for " + type
               : @"Successfuly returned from SetWindowFeedbackSetting for " + type);
    }
}

And I call this from my WPF app like this:

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    Window window = Window.GetWindow(this);
    var wih = new WindowInteropHelper(window);
    IntPtr hWnd = wih.Handle;
    TryDisableWindowsVisualFeedback(hWnd);
}

This is my auxiliary Win32 class:

internal class Win32
{
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SystemParametersInfo(
        uint uiAction,
        uint uiParam,
        ref ulong pvParam,
        uint fWinIni
        );

    public enum FEEDBACK_TYPE : uint
    {
        FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
        FEEDBACK_PEN_BARRELVISUALIZATION = 2,
        FEEDBACK_PEN_TAP = 3,
        FEEDBACK_PEN_DOUBLETAP = 4,
        FEEDBACK_PEN_PRESSANDHOLD = 5,
        FEEDBACK_PEN_RIGHTTAP = 6,
        FEEDBACK_TOUCH_TAP = 7,
        FEEDBACK_TOUCH_DOUBLETAP = 8,
        FEEDBACK_TOUCH_PRESSANDHOLD = 9,
        FEEDBACK_TOUCH_RIGHTTAP = 10,
        FEEDBACK_GESTURE_PRESSANDTAP = 11,
        FEEDBACK_MAX = 0xFFFFFFFF
    }

    [DllImport("user32.dll")]
    public static extern bool SetWindowFeedbackSetting(
        IntPtr hwnd,
        FEEDBACK_TYPE feedback,
        uint dwFlags,
        uint size,
        [In] ref bool configuration
        );

}

Non of the above disabled the round gray tap visual feedback nor did it disable the small white circle that appears when holding and dragging.

I even tried using the C# example in the blog:

Windows.UI.Input.PointerVisualizationSettings.
GetForCurrentView().
IsContactFeedbackEnabled = false;

This code works for a metro app, so I tried This SO post and got the Windows namespace but when running the code I get

"An unhandled exception of type 'System.Exception' occurred in MyProg.exe
WinRT information: Element not found.
Additional information: Element not found."

From what I could figure out, the PointerVisualizationSettings is not supported from a desktop application so this way is doomed...

If anyone can help me with this issue, please do.

Thanks

c#
winapi
windows-runtime
touch
windows-8.1
asked on Stack Overflow Dec 18, 2014 by ZivS • edited May 23, 2017 by Community

3 Answers

3

I had a similar problem and I was able to remove my tap gesture feedback by adding

Stylus.IsTapFeedbackEnabled = "False" to my root window.
answered on Stack Overflow May 21, 2015 by JennHarper • edited May 21, 2015 by Robert
1

Your TryDisableWindowsVisualFeedback method looks like it has the wrong pinvoke signature so you may be setting the visual feedback instead of clearing it. The configuration argument is a BOOL* not a bool*, and BOOL is a 4 byte integer. You can fix this with the MarshalAs attribute:

[In , MarshalAs(UnmanagedType.Bool)] ref bool configuration

You can call GetWindowFeedbackSetting to confirm that it was set correctly.

With the right pinvoke and hWnd, SetWindowFeedbackSetting should work. I confirmed that it does for me in a native app. WPF handles touch a bit oddly. I wouldn't expect it to affect this, but I haven't looked at WPF in depth for several years.

For your other methods, the Windows.UI.Input classes are documented to work only in Windows Store apps, so errors calling them from a desktop app are expected. Under the covers they'll make the same changes as SetWindowFeedbackSetting.

Using SystemParametersInfo to affect global UI is overkill: you don't want to solve a local problem by causing a global one. That said, it would probably work if you fire change notifications. Using SetWindowFeedbackSetting to target just your window is a much better solution though.

answered on Stack Overflow Dec 19, 2014 by Rob Caplan - MSFT
0

I don't know if this would resolve the OP's original issue (or even makes a difference), but I can confirm that I have successfully disabled all touch related visual feedback for my own Control-derived class selectively with the following method (almost like the one suggested by the OP) - at least on my Windows 10 machine:

public class MyTouchControl: Control
{
    // ...a lot of other touch related stuff going on...

    enum FEEDBACK_TYPE
    {
        TOUCH_CONTACTVISUALIZATION = 1,
        PEN_BARRELVISUALIZATION = 2,
        PEN_TAP = 3,
        PEN_DOUBLETAP = 4,
        PEN_PRESSANDHOLD = 5,
        PEN_RIGHTTAP = 6,
        TOUCH_TAP = 7,
        TOUCH_DOUBLETAP = 8,
        TOUCH_PRESSANDHOLD = 9,
        TOUCH_RIGHTTAP = 10,
        GESTURE_PRESSANDTAP = 11
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetWindowFeedbackSetting(IntPtr hWnd, FEEDBACK_TYPE feedback, int dwFlags, int size, ref int config);

    void disableAllTouchVisualFeedback()
    {
        int enable = 0;
        foreach (FEEDBACK_TYPE type in Enum.GetValues(typeof(FEEDBACK_TYPE)))
        {
            SetWindowFeedbackSetting(Handle, type, 0, 4, ref enable);
        }
    }

    protected override void OnHandleCreated(EventArgs e)
    {
        disableAllTouchVisualFeedback();
        base.OnHandleCreated(e);
    }
}
answered on Stack Overflow Dec 9, 2018 by oliver

User contributions licensed under CC BY-SA 3.0