Closing the Windows 8 Charm Bar

c#, c++, windows-8, windows-rt

Solution

In fact, I have found a way to do this (apparently, no one else has :/).

For those wondering, software like "Start8" and "SkipMetroSuite" poll key presses to stop the Charm Bar. They literally simulate the keypresses to close it within a tight loop.

I have found (what I think is) a better way.

First up... some WinAPI functions:

using System.Runtime.InteropServices;
....

private enum WindowShowStyle : uint
{  // find more info at http://stackoverflow.com/a/8210120/1245420
   Hide = 0, ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3,
   ShowNormalNoActvate = 4, Show = 5, Minimize = 6, ShowNoActivate = 8,
   Restore = 9, ShowDefault = 10, ForceMinimized = 11
}

[DllImport("user32.dll", SetLastError = true)]
static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern System.IntPtr FindWindowByCaption(System.IntPtr ZeroOnly, string lpWindowName);

[DllImport("user32.dll")]
static extern bool ShowWindow(System.IntPtr hWnd, WindowShowStyle nCmdShow);

So the problem first up, is the Charm Bar. The Window title for this turns out to be, `Charm Bar`. Spawning a thread that continually looks for this window and hides it works beautifully. So I spawn a thread, and continually poll it:

System.Threading.Tasks.Task.Factory.StartNew(() => {
    while (true) {
        System.IntPtr hWndCharmBar = FindWindowByCaption(System.IntPtr.Zero, "Charm Bar");
        ShowWindow(hWndCharmBar, 0);
        System.Threading.Thread.Sleep(100); // sleep for a bit
    }
});

This works well and gives the added benefit of making the Charm Bar continue to work when the app is closed. The `Thread.Sleep` is there to stop the thread smashing the CPU - but the delay also allows for the Charm Bar to appear for a split second. I am yet to successfully open the Charm Bar and press a button quick enough before the thread hides it again though, so this is fine. Lowering the sleep time obviously makes this quicker.

The other issue with Windows 8 is that if you have some sort of slider (in my app, I have a `ListBox` containing images for a gallery) then you can actually slide to the side of the screen... hold your finger there, and access the taskbar...

So.. the next part is closing the task bar:

IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
ShowWindow(hWndTray, 0);

..then I show it again on app close:

IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
ShowWindow(hWndTray, 1);

Functionally, this is all I needed for my app. Hope that helps someone.

Problem

I have a Surface Pro that I need to "lock down" as a type of Kiosk mode. I am aware that an update is on its way for "Kiosk Mode".. however I need to do this before that. I have searched all over the internet, but it appears that you cannot disable the Charm bar from a swipe on the screen. I have found ways to disable trackpads.. but unfortunately, since this tablet will be used without a keyboard, I need to disable the Charm bar. My new thought is to move the entire Charm bar HWND thousands of pixels off screen, or, maybe set a windows style on it so that it doesn't appear. I have attempted to use Spy++ and a custom `EnumWindows` based console app to give me some Window handles.. however I can't keep the Charm bar open long enough for these to take effect. So my question is: How can I locate the Window Handle (`HWND`) for the Charm Bar in Windows 8? Or, how can I get a reference to the Charm bar some other way in order to throw a `SetWindowLong` or `SetWindowPos` at it?

Original source

Related problems