We have a need in one of our apps where we need to disable some of the built in gestures for Windows 8 to prevent users from leaving the app. (think kiosk sign in screen). Are there methods for still allowing the user to interact with the app using touch but disabling/intercepting some of the built in gestures (things like docking the app on the left, going to the desktop, etc).
Our backup solution is to disable touch altogether when in certain screens (this is something we can do) but we'd like a better user experience and to just disable the gestures that we absolutely need to (similar to disabling the windows key, ctrl+alt+del instead of the whole keyboard).
Initial searches and investigation haven't turned up what we've been looking for so we're either looking for the wrong thing or in the wrong places.
You can disable gesture in Windows 8 Embedded. Maybe you can try this in Windows 8.
Registry Keys:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ImmersiveShell\EdgeUI]
"DisabledEdges"=dword:0000000f
0x01 : Disables left edge input and app switcher gesture.
0x02 : Disables right edge input and charm bar gesture.
0x04 : Disables top edge input and top application bar gesture.
0x08 : Disables bottom edge input and bottom application bar gesture.
if you want to disables each gesture, just add dword:0000000f (15)
To do it programmatically, you can call the function in the link below. It requires the hWnd to the window you would like to target.
http://msdn.microsoft.com/en-us/library/windows/desktop/jj553591%28v=vs.85%29.aspx
The C++ below will search for a window with the window title "helloworld", and disable all of the Windows 8 gestures for it. This does not work for Windows Store apps, and the function has to be called on the window while it is open. If the application is closed and re-opened, the gestures will return. Also, I believe it only works while the application is full-screen.
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <propsys.h>
#include <propkey.h>
using namespace std;
HWND windowHandle;
HRESULT SetTouchDisableProperty(HWND hwnd, BOOL fDisableTouch)
{
IPropertyStore* pPropStore;
HRESULT hrReturnValue = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pPropStore));
if (SUCCEEDED(hrReturnValue))
{
PROPVARIANT var;
var.vt = VT_BOOL;
var.boolVal = fDisableTouch ? VARIANT_TRUE : VARIANT_FALSE;
hrReturnValue = pPropStore->SetValue(PKEY_EdgeGesture_DisableTouchWhenFullscreen, var);
pPropStore->Release();
}
return hrReturnValue;
}
BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM lParam)
{
TCHAR title[500];
ZeroMemory(title, sizeof(title));
GetWindowText(hWnd, title, sizeof(title)/sizeof(title[0]));
if (!_tcscmp(title, _T("helloworld")))
{
SetTouchDisableProperty(hWnd,true);
}
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumWindows(MyEnumProc, 0);
return 0;
}
Windows charms bar is operated by explorer.exe.
So if your app can run without it then you can hack around it by first disabling the autorestart of explorer.exe via (run as administrator):
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "AutoRestartShell" /t REG_DWORD /d 0
Then the lines below represent my launch.bat - which works in the end as expected:
;; kill explorer (this disables all windows functionalities
taskkill /f /im explorer.exe
;; start your kiosk app - should block the batch execution (so explorer.exe doesn't get executed at the end)
"\path\to\your\app.exe"
;; relaunch explorer.exe after you close the app to give back the functionality to windows
explorer.exe
I use the approach outlined above to let a keyboardless kiosk app run. Because with a keyboard you can still close the app with alt+f4.
Setting IsTapEnabled, IsDoubleTapEnabled, IsRightTapEnabled, and IsHoldingEnabled to false should disable the gestures in the UI Element but they are properties, not methods. I haven't seen a method that will disable ALL gestures for a particular element.
I know it would be ridiculous to disable each control to respond to the gestures but if you need to disable all controls literally from Root to Children then creating an attach property on the root and setting these properties to false might be a solution.
The gestures are handled by explorer.exe.
If your replace the windows shell (default: explorer.exe) with your Application, then there are no more gestures at the OS-level.
Registry keys:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows_NT\CurrentVersion\Winlogon\
Key: "Shell" (REG_SZ) = "path_to_your_application"
you can also do this only for the current user (HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows_NT\CurrentVersion\Winlogon)
At least in 8.1, there appears to be a feature called Assigned Access:
http://blogs.technet.com/b/askpfeplat/archive/2013/10/28/how-to-setup-assigned-access-in-windows-8-1-kiosk-mode.aspx
http://windows.microsoft.com/en-us/windows-8/assigned-access
Settings > Change PC Settings > Accounts > Other Accounts > Set up an account for assigned access
Related
I have a Win32 application that determines whether there are any visible, non-iconic, minimizable windows being shown. To the best of my knowledge it's worked fine for Win9x through to Win8.1, but under Windows 10 it often finds several windows that aren't actually visible on the screen.
To try to identify what's going on I've written a simple test application that enumerates and records all such windows. Here's the essence of the EnumWindows callback code:
BOOL CALLBACK EnumFunc( HWND hWnd, LPARAM lParam )
{
if ( IsWindowVisible( hWnd ) )
{
if ( !IsIconic( hWnd ) )
{
const LONG style = GetWindowLong( hWnd, GWL_STYLE );
if ( WS_MINIMIZEBOX & style )
{
// record window info
}
}
}
return TRUE;
}
Most of the phantom windows under Windows 10 belong to background store app processes such as Mail, Calculator, and Photos. These are listed under the Background processes section of Task Manager, and if I use Task Manager to end those background tasks, their phantom window is no longer found by my test application.
In the above screen shot from my test application you can see that all but 1 of the offending windows belong to threads of the same process id 7768, which is ApplicationFrameHost.exe. The final window with process id 11808 is explorer.exe.
I've looked at the phantom windows with Spy++ and can't see any particular style combination that would help in uniquely identifying them.
I've had a suggestion that the undocumented Windows "bands" may be involved, but I've tried using the (undocumented, so this may be wrong) API:
BOOL WINAPI GetWindowBand (HWND hWnd, PDWORD pdwBand);
but it returns a band of 1 for any window, so doesn't differentiate these phantoms.
How to reliably identify these phantom windows?
The approved way of detecting these phantom windows is to use DwmGetWindowAttribute and DWMWA_CLOAKED.
Here's the code I've used:
static bool IsInvisibleWin10BackgroundAppWindow( HWND hWnd )
{
int CloakedVal;
HRESULT hRes = DwmGetWindowAttribute( hWnd, DWMWA_CLOAKED, &CloakedVal, sizeof( CloakedVal ) );
if ( hRes != S_OK )
{
CloakedVal = 0;
}
return CloakedVal ? true : false;
}
Thanks to Scot Br from MS for posting the answer here
Top-level windows of class ApplicationFrameWindow are containers for Windows Store apps. First, here is the window of Mail shown in Spy:
This is truly visible (not phantom). You can tell that it is because the first child is a window of class Windows.UI.Core.CoreWindow. Interestingly, the owner process of the ApplicationFrameWindow is APPLICATIONFRAMEHOST, but the owner process of the Windows.UI.Core.CoreWindow is a different one: HXMAIL. (I've not seen a child window owned by a different process than the parent one before!)
Compare that with a phantom window (as identified in your RWTool):
It is missing the child of class Windows.UI.Core.CoreWindow.
This suggests an answer to your question: If a top-level window is of class ApplicationFrameWindow, iterate it's children. If the first child has class Windows.UI.Core.CoreWindow, the window is visible, otherwise it is not (i.e. it is phantom).
But what if an old-fashioned, non-store app happened to have a top-level window of class ApplicationFrameWindow? It would not have a child of Windows.UI.Core.CoreWindow. Yet it is visible. How to tell this is an ordinary app and not a Windows Store app? I don't have a foolproof way. You could also check for the existence of the other child windows of a Store app: ApplicationFrameTitleBarWindow and ApplicationFrameInputSinkWindow. The chances of a non-Store app having this exact Windows hierarchy is vanishingly small.
EDIT
The ApplicationFrameWindow's (and also Windows.UI.Core.CoreWindow) have the WS_EX_NOREDIRECTIONBITMAP style set:
The window does not render to a redirection surface. This is for windows that do not have visible content or that use mechanisms other than surfaces to provide their visual.
At minimum, you could check for this style instead of special casing ApplicationFrameWindow. Though to see if any content was truly visible, you'd still need to make that depend on whether it has a child of Windows.UI.Core.CoreWindow.
I have a Win32 application that determines whether there are any visible, non-iconic, minimizable windows being shown. To the best of my knowledge it's worked fine for Win9x through to Win8.1, but under Windows 10 it often finds several windows that aren't actually visible on the screen.
To try to identify what's going on I've written a simple test application that enumerates and records all such windows. Here's the essence of the EnumWindows callback code:
BOOL CALLBACK EnumFunc( HWND hWnd, LPARAM lParam )
{
if ( IsWindowVisible( hWnd ) )
{
if ( !IsIconic( hWnd ) )
{
const LONG style = GetWindowLong( hWnd, GWL_STYLE );
if ( WS_MINIMIZEBOX & style )
{
// record window info
}
}
}
return TRUE;
}
Most of the phantom windows under Windows 10 belong to background store app processes such as Mail, Calculator, and Photos. These are listed under the Background processes section of Task Manager, and if I use Task Manager to end those background tasks, their phantom window is no longer found by my test application.
In the above screen shot from my test application you can see that all but 1 of the offending windows belong to threads of the same process id 7768, which is ApplicationFrameHost.exe. The final window with process id 11808 is explorer.exe.
I've looked at the phantom windows with Spy++ and can't see any particular style combination that would help in uniquely identifying them.
I've had a suggestion that the undocumented Windows "bands" may be involved, but I've tried using the (undocumented, so this may be wrong) API:
BOOL WINAPI GetWindowBand (HWND hWnd, PDWORD pdwBand);
but it returns a band of 1 for any window, so doesn't differentiate these phantoms.
How to reliably identify these phantom windows?
The approved way of detecting these phantom windows is to use DwmGetWindowAttribute and DWMWA_CLOAKED.
Here's the code I've used:
static bool IsInvisibleWin10BackgroundAppWindow( HWND hWnd )
{
int CloakedVal;
HRESULT hRes = DwmGetWindowAttribute( hWnd, DWMWA_CLOAKED, &CloakedVal, sizeof( CloakedVal ) );
if ( hRes != S_OK )
{
CloakedVal = 0;
}
return CloakedVal ? true : false;
}
Thanks to Scot Br from MS for posting the answer here
Top-level windows of class ApplicationFrameWindow are containers for Windows Store apps. First, here is the window of Mail shown in Spy:
This is truly visible (not phantom). You can tell that it is because the first child is a window of class Windows.UI.Core.CoreWindow. Interestingly, the owner process of the ApplicationFrameWindow is APPLICATIONFRAMEHOST, but the owner process of the Windows.UI.Core.CoreWindow is a different one: HXMAIL. (I've not seen a child window owned by a different process than the parent one before!)
Compare that with a phantom window (as identified in your RWTool):
It is missing the child of class Windows.UI.Core.CoreWindow.
This suggests an answer to your question: If a top-level window is of class ApplicationFrameWindow, iterate it's children. If the first child has class Windows.UI.Core.CoreWindow, the window is visible, otherwise it is not (i.e. it is phantom).
But what if an old-fashioned, non-store app happened to have a top-level window of class ApplicationFrameWindow? It would not have a child of Windows.UI.Core.CoreWindow. Yet it is visible. How to tell this is an ordinary app and not a Windows Store app? I don't have a foolproof way. You could also check for the existence of the other child windows of a Store app: ApplicationFrameTitleBarWindow and ApplicationFrameInputSinkWindow. The chances of a non-Store app having this exact Windows hierarchy is vanishingly small.
EDIT
The ApplicationFrameWindow's (and also Windows.UI.Core.CoreWindow) have the WS_EX_NOREDIRECTIONBITMAP style set:
The window does not render to a redirection surface. This is for windows that do not have visible content or that use mechanisms other than surfaces to provide their visual.
At minimum, you could check for this style instead of special casing ApplicationFrameWindow. Though to see if any content was truly visible, you'd still need to make that depend on whether it has a child of Windows.UI.Core.CoreWindow.
I want to turn the system network icon on/off in my application likes what we can do via control panel. I know the "HideSCANetwork" registry item, but to use this solution I need to restart the explorer after changing the setting. Is there any other solution which can do this seamlessly like the system?
There is no official API for doing thois. The reason for this is that Microsoft wanted to give the user the ability to keep their notification area from becoming too full. The problem being too many applications starting notification icons that the user doesn't care for.
Since many users don't know how to get rid of these icons, Microsoft decided to help by hiding them by default. If applications had access to these hide/show settings then applications would simply show the notifications by default and we'd be back where we started. So there is no mechanism provided for modifying these settings programmatically.
You want to do something different that sounds equally malicious, namely to hide an important system icon. If you are determined to do this then you can reverse engineer how the setting is stored (likely in the registry) and change the setting that way. However, you'll be going against the system design should you do so.
Now I find a imperfect solution. The basic idea comes from here:
http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons
Some tips:
This solution supports Win 7, you can remove XP checking code.
On wow64, you need to change the struct TRAYDATA and use TBUTTON64:
struct TRAYDATA
{
DWORD64 hwnd;
UINT uID;
UINT uCallbackMessage;
DWORD Reserved[2];
DWORD64 hIcon;
};
typedef struct _TBBUTTON64
{
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
BYTE bReserved[6];
DWORD64 dwData;
DWORD64 iString;
} TBBUTTON64, NEAR* PTBBUTTON64, *LPTBBUTTON64;
typedef const TBBUTTON64 *LPCTBBUTTON64;
When you find the icon you want to hide(By using the tip text plus the owner process), send a TB_HIDEBUTTON message to the notification area window.
The imperfect part is that the tray icon will be hidden, but the notification area will not resize. So there is a blank area on the notification area.
I have an MFC application. In my application if I run on Windows XP it's working fine. But if I run in Windows Vista the MFC dialog hides behind the taskbar.
bool bHide=true;
CRect rectWorkArea = CRect(0,0,0,0);
CRect rectTaskBar = CRect(0,0,0,0);
CWnd* pWnd = CWnd::FindWindow("Shell_TrayWnd", "");
pWnd->ShowWindow(SW_SHOW);
if( bHide )
{ // Code to Hide the System Task Bar
SystemParametersInfo(SPI_GETWORKAREA,0,(LPVOID)&rectWorkArea,0);
if( pWnd )
{
pWnd->GetWindowRect(rectTaskBar);
// rectWorkArea.bottom -= rectTaskBar.Height();
rectWorkArea.bottom += rectTaskBar.Height();//-----to hide taskbar
SystemParametersInfo(SPI_SETWORKAREA,0,(LPVOID)&rectWorkArea,0);
// pWnd->ShowWindow(SW_SHOW);
pWnd->ShowWindow(SW_HIDE); //--to hide taskbar
}
}
I used this code but it hides the taskbar. But I want to show the application above the task bar.
You don't own the taskbar, so you are not supposed to hide it. You have the option to auto-minimize it by the way. You have another option of using secondary monitor without taskbar there.
On the primary monitor your app is given work area, you are being able to locate (judging from the code snippet provided above). It is the best to position your window within this area without interfering with the taskbar, whether it is above or beyond.
If you still feel like making it more like a competition "who is on top" with the task bar, you might want to take a look at SetWindowPos API and window Z-Order.
finally i found the solution , what we want to do is we should add the below code in our oninitdialog,
SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
the above line is enough to show the mfc dialog on above the taskbar . but sometimes the focus of the dialog get changed looks hanged(no response in dialog) the application.if it occurs put the below code.
SetWindowPos(&this->wndBottom,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
I'd like to have the same effect as the windows 7 taskbar.
I've looked in this question:
Keep Window Looking Active
It works great but only if the window has a non-client area.
My window is border-less and the content of it (just a black background) is rendered as it is inactive, no matter what I do.
I've set my window flags just as Windows 7 taskbar but it didn't help.
My only thought at the moment is to draw it with borders and just clip them, is there a better way to achieve what I want?
EDIT 1:
Clipping didn't work, after clipping the borders the window content was rendered as inactive window.
How the hell does windows 7 task-bar works then?
EDIT2:
Adding some photos to explain myself better, The following window content is a black background.
That's an inactive window (the content is rendered kinda dark):
That's an active window:
If the window has no client area the content is always rendered as inactive window however the windows Taskbar is always rendered as active window and it doesn't have any NC area (at least according to spy++). That's what I'm trying to mimic.
EDIT3:
Sharing my recent discoveries.
explorer.exe main window is frameless and has the following flags:
I dived into the explorer's process dwmapi.dll exported functions:
it uses DwmEnableBlurBehindWindow, just as I do.
I've checked the undocumented ordinal functions and none of them is related to rendering the aero glass as active.
Could it be the DWM rules don't apply to explorer?
Tricky one..
set the NCRenderingPolicy to Enabled with the "DwmSetWindowAttribute" API.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[Flags]
public enum DwmWindowAttribute
{
NCRenderingEnabled = 1,
NCRenderingPolicy,
TransitionsForceDisabled,
AllowNCPaint,
CaptionButtonBounds,
NonClientRtlLayout,
ForceIconicRepresentation,
Flip3DPolicy,
ExtendedFrameBounds,
HasIconicBitmap,
DisallowPeek,
ExcludedFromPeek,
Last
}
[Flags]
public enum DwmNCRenderingPolicy
{
UseWindowStyle,
Disabled,
Enabled,
Last
}
public static bool SetNCRenderingActive(IntPtr Handle)
{
int renderPolicy = (int)DwmNCRenderingPolicy.Enabled;
return (DwmSetWindowAttribute(Handle, (int)DwmWindowAttribute.NCRenderingPolicy, ref renderPolicy, sizeof(int) ) == 0);
}