How do I disable Windows 8 touch contact visualizations for my application?


You might have an application (like a game) where the default touch contact visualizations are a distraction. In WinRT, you can disable the contact visualizations by simply saying

// JavaScript
Windows.UI.Input.PointerVisualizationSettings.
    getForCurrentView().
    isContactFeedbackEnabled = false;

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

// C++
Windows::UI::Input::PointerVisualizationSettings::
    GetForCurrentView()->
    IsContactFeedbackEnabled = false;

In Win32, you use the Set­Window­Feedback­Setting function. To demonstrate that, let's take our scratch program and make this simple change:

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
 BOOL fEnabled = FALSE;
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_CONTACTVISUALIZATION,
    0, sizeof(fEnabled), &fEnabled);
 return TRUE;
}

The touch visualizations are white and the default window color is white, so the visualizations are hard to see in the scratch program. Let's change the color to something that the visualizations will be more visible against.

    wc.hbrBackground = (HBRUSH)(COLOR_WINDOWTEXT + 1);

Run the program, and you'll see that if you touch the window and drag your finger around, there is no little white circle and no white streak that follows your finger. (Note, however, that the Optimize visual feedback for projection to an external monitor, setting overrides the FEEDBACK_TOUCH_CONTACT­VISUALIZATION setting, so if you have projection contacts enabled, then you still get the dark circles. Another way to get dark circles is to stay up late and not get enough sleep.)

Although we disabled contact visualizations, we still get visualizations for gestures like tap or tap-and-hold. We can turn those off, too:

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
 BOOL fEnabled = FALSE;
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_CONTACTVISUALIZATION,
    0, sizeof(fEnabled), &fEnabled);
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_TAP,
    0, sizeof(fEnabled), &fEnabled);
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_DOUBLETAP,
    0, sizeof(fEnabled), &fEnabled);
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_PRESSANDHOLD,
    0, sizeof(fEnabled), &fEnabled);
 SetWindowFeedbackSetting(hwnd,
    FEEDBACK_TOUCH_RIGHTTAP,
    0, sizeof(fEnabled), &fEnabled);
 return TRUE;
}

The complete list of things you can disable is given by the FEEDBACK_TYPE enumeration.

Comments (13)
  1. Joshua says:

    My first thought was "by being a command line application"

  2. Danny says:

    "How do I disable Windows 8". as in period.

    That's the perfect answer.

    [Okay, so let's put it a different way. "You have been forced against your will to write a program that runs on Windows 8. How do you…" -Raymond]
  3. Is there a reason why two separate APIs exist, and neither can be used on both WinRT and Desktop applications? Our product supports many platforms, including Windows Phone, Windows Store Apps and Windows Desktop. It's somewhat annoying that we have to write the same functionality multiple times for similar platforms. In some cases, those WinRT APIs end up individually calling the underlying method anyway, but god forbid we do it ourselves, or our application will fail WACK. And it seems like it has already become a habit – I'm not sure what's the point of forbidding the use of code that has been written many years ago, works perfectly well, and instead forcing to use the "new" API, which implements the same thing the same way!

    In this case, setting Windows::UI::Input::PointerVisualizationSettings::GetForCurrentView()->IsContactFeedbackEnabled eventually calls _NtUserSetWindowFeedbackSetting, and SetWindowFeedbackSetting looks to be an alias (or redirection?) to _NtUserSetWindowFeedbackSetting as well.

    [_NtUserSetWindowFeedbackSetting doesn't exist on Phone. That's why there is a WinRT wrapper that redirects the call to the correct underlying OS primitive. -Raymond]
  4. Dave Bacher says:

    @Tautvydas:

    That's crazy talk.  The next thing you'll be saying that there shouldn't be two separate touch keyboards, two separate ways of adding a wifi access point, two different (and neither complete) ways of adding devices, that there should be just one interface for Windows Update, etc.  If the two libraries ever cross each other, the universe ends in a giant blinding blue screen — it's UNIVERSE_ENDED_WINRT_TOUCHED_WIN64.

  5. @Raymond: on phone, setting IsContactFeedbackEnabled throws an exception:  "The specified procedure could not be found.". Digging deeper suggests that the error happens when it dynamically tries to find a procedure in ntdll.dll. I couldn't find out whether it was _NtUserSetWindowFeedbackSetting that it was looking for. So I don't buy that was the reason :). More probably, since you can't get yours hands on HWND manually on WinRT apps, the win32 API would be useless, however, that doesn't explain situations why it's forbidden to call win32 APIs when it's perfectly valid.

    @Dave: I think I was misunderstood. I'm not complaining that there are two different ways of doing something. I just think that it's a bit silly to not allow calling certain functions when they are there and instead invent new APIs that wrap them. Why not allow them, even if the wrapper exists?

  6. Myria says:

    Windows 10 actually splits up win32k.sys into the core parts and the main desktop parts.  I presume that Xbone and WinPhone will only use the core win32k.sys, while Windows RT 10 and Windows 10 will use the desktop one as well.

  7. Danny says:

    "Okay, so let's put it a different way. "You have been forced against your will to write a program that runs on Windows 8. How do you…"

    I'll advice my client to upgrade to 10 (btw, where is 9?(sic)), or downgrade to 7. Anything to avoid a flop.

  8. Gabe says:

    I see nothing wrong with having different ways to do the same thing, but I don't understand why you can't use both. I see why they don't let you access Win32 APIs from WinRT apps, but why can't you access WinRT APIs from Win32 apps?

  9. Azarien says:

    @Gabe: this way you can focus on Win32 and forget that WinRT even exists ;-)

  10. AndyCadley says:

    @Gabe: Some of them you can, but the vast majority rely on state provided by the WinRT sandbox that simply doesn't exist for Win32 applications.

  11. Wear says:

    @Gabe

    http://www.hanselman.com/…/HowToCallWinRTAPIsInWindows8FromCDesktopApplicationsWinRTDiagram.aspx

    software.intel.com/…/using-winrt-apis-from-desktop-applications

    msdn.microsoft.com/…/hh438466

    Also going the other way

    msdn.microsoft.com/…/br205757.aspx

    I haven't looked too much into these things but it seems like it's possible to mix APIs fairly easily. The important thing is to find out which ones are supported by what.

  12. cheong00 says:

    @Danny: See this post for possible explanation of why Win9 does not exist.

    channel9.msdn.com/…/Ah-that-explains-it

  13. Muzer_ says:

    @cheong00: I visited a link that led me to a blog article about the possible explanation, from which I visited a link to a CodingHorror blog entry about a similar issue with Intel processors, from which I visited a link to this blog from 2003. Ah, the circle of hacky workarounds ;)

Comments are closed.

Skip to main content