> > > if ( Msg.message == WM_HOTKEY && Msg.wParam == 'K' ) > > > Launch( L"/Program Files/Common Files/microsoft shared/ink/TabTip.EXE" ), The "random delay" thing is still happening; my latest attempt: if ( WM == WM_HOTKEY && C == 'K' ) { int Cnt = 1 ; static double Mark ; HWND Keyboard ; ITipInvocation * VirKeyboard ; // Alt+Shift+Ctrl+K: Toggles "Touch Keyboard" On/Off. // If the keyboard doesn't come up right away, // toggle 3 times in less than 3 seconds. !Mark || Secs > Mark + 3 ? Mark = Secs, Cnt = 1 : ++Cnt > 3 ? Mark = Secs, Cnt = 1, Keyboard = FindWindow( 0, L"Microsoft Text Input Application" ), Keyboard ? SendMessage( Keyboard, WM_SYSCOMMAND, SC_CLOSE, 0 ) : 0, Launch( L"/Windows/SystemApps/InputApp_cw5n1h2txyewy/" L"WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.EXE" ) : 0 ; if ( CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&VirKeyboard ) ) Launch( L"/Program Files/Common Files/microsoft shared/ink/TabTip.EXE" ); else VirKeyboard->Toggle( GetDesktopWindow() ), VirKeyboard->Release(); }
Yet another Correction... see "TerminateProcess( aProc, 9 )". From "Jeff-Relf.Me/X.CPP" in "Jeff-Relf.Me/X.ZIP". #include <InitGuid.H> #include <tlhelp32.H> typedef LARGE_INTEGER DubInt ; unsigned __int64 u64 ; u64 _Tics, Hz ; double _Secs, _Hz ; #define Tics ( QueryPerformanceCounter( ( DubInt * ) & _Tics ), _Tics ) #define Secs ( _Secs = Tics / _Hz ) ...... QueryPerformanceFrequency( ( DubInt * ) & Hz ), _Hz = Hz ; ...... DEFINE_GUID( CLSID_UIHostNoLaunch, // 4ce576fa-83dc-4F88-951c-9d0782b4e376 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76); DEFINE_GUID( IID_ITipInvocation, // 37c994e7_432b_4834_a2f7_dce1f13b834b 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b); struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND wnd) = 0; }; ..... if ( WM == WM_HOTKEY && C == 'K' ) { static int Cnt ; static double Mark ; ITipInvocation * VirKeyboard ; HANDLE PIDs, aProc ; PROCESSENTRY32 aPID; // Alt+Shift+Ctrl+K: Toggles "Touch Keyboard" On/Off. // If the keyboard doesn't come up right away, // toggle 3 times in less than 3 seconds. if ( !Mark || Secs > Mark + 3 ? Cnt = 0, Mark = Secs : 0, ++Cnt > 3 ) { PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); aPID.dwSize = sizeof( PROCESSENTRY32 ), Process32First( PIDs, &aPID ); NextProc: if ( Eqi( aPID.szExeFile, L"WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.EXE" ) ) aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ), aProc ? TerminateProcess( aProc, 9 ), CloseHandle(aProc) : 0, Launch( L"/Program Files/Common Files/microsoft shared/ink/TabTip.EXE" ); if ( Process32Next( PIDs, &aPID ) ) goto NextProc ; CloseHandle( PIDs ); } if ( CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&VirKeyboard ) ) Launch( L"/Program Files/Common Files/microsoft shared/ink/TabTip.EXE" ); else VirKeyboard->Toggle( GetDesktopWindow() ), VirKeyboard->Release(); }
As it turns out... The best way to toggle the Touch Keyboard, is to "Kill/ReStart" it each time. "KB->Toggle()" still has to be called, as Firefox and Chrome need it. From "X.CPP" in "Jeff-Relf.Me/X.ZIP". if ( WM == WM_HOTKEY && C == 'K' ) { // A mouse button takes me here. HANDLE PIDs, aProc ; PROCESSENTRY32 aPID; ITipInvocation * KB = 0 ; PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); aPID.dwSize = sizeof( PROCESSENTRY32 ), Process32First( PIDs, &aPID ); NextProc: if ( Eqi( aPID.szExeFile, L"TabTip.EXE" ) ) { if ( aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ) ) TerminateProcess( aProc, 9 ), CloseHandle( aProc ); goto ReStart ; } if ( Process32Next( PIDs, &aPID ) ) goto NextProc ; ReStart: CloseHandle( PIDs ); Launch( L"%CommonProgramW6432%/microsoft shared/ink/TabTip.EXE" ); LoopJ(9) if ( CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&KB ), !KB ) Sleep(99); else { KB->Toggle( GetDesktopWindow() ), KB->Release(); break ; } } ..... #include <InitGuid.H> #include <tlhelp32.H> DEFINE_GUID( CLSID_UIHostNoLaunch, // 4ce576fa-83dc-4F88-951c-9d0782b4e376 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76); DEFINE_GUID( IID_ITipInvocation, // 37c994e7_432b_4834_a2f7_dce1f13b834b 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b); struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND wnd) = 0; }; #define Eqi !strCmpI #define LoopJ( N ) int J = -1, eJ = ( N ) - 1 ; while ( ++J <= eJ ) void Launch( LnP Cmd ) { int Err, rv ; wchar _Cmd[333]; ExpandEnvironmentStrings( Cmd, _Cmd, 333 ), Cmd = _Cmd ; static PROCESS_INFORMATION Stat ; static STARTUPINFO SU = { sizeof SU }; SetEnvironmentVariable( L"__compat_layer", L"RunAsInvoker" ); rv = CreateProcess( 0, Cmd, 0,0,1,0,0,0, &SU , &Stat ), CD( LocDir ); if ( !rv ) { Err = GetLastError(), *_B_Sh = 0 ; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, Err, 0, _B_Sh, 999, 0 ); Sh( L"Error: %d, %s\n\n <%s> wasn't launched", Err, _B_Sh, Cmd ); return; } CloseHandle( Stat.hProcess ), CloseHandle( Stat.hThread ); }
Hopefully, I got it right this time ( only time will tell ). stackoverflow.com/questions/38774139/show-touch-keyboard-tabtip-exe-in-windows-10-anniversary-edition To toggle the Touch Keyboard, and not have it randomly stall, Kill "TabTip.EXE" -and- "WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.EXE" each time ( each toggle ). If both were running, then the keyboard _was_ up ( now down, killed ); otherwise, ReLaunch them, and run "KB->Toggle()" ( for Firefox&Chrome ). From "X.CPP" in "Jeff-Relf.Me/X.ZIP". if ( WM == WM_HOTKEY && C == 'K' ) { // A mouse button takes me here. ITipInvocation * KB = 0 ; // Jeff-Relf.Me/g600.PNG if ( Kill( L"TabTip.EXE" ) + Kill( L"WindowsInternal.ComposableShell" L".Experiences.TextInput.InputApp.EXE" ) < 2 ) { Launch( L"%WinDir%/SystemApps/InputApp_cw5n1h2txyewy/" L"WindowsInternal.ComposableShell.Experiences." L"TextInput.InputApp.EXE" ); Launch( L"%CommonProgramW6432%/microsoft shared/ink/TabTip.EXE" ); LoopJ(9) if ( CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&KB ), !KB ) Sleep(99); else { KB->Toggle( GetDesktopWindow() ), KB->Release(); break ; } } } ..... #include <InitGuid.H> #include <tlhelp32.H> DEFINE_GUID( CLSID_UIHostNoLaunch, // 4ce576fa-83dc-4F88-951c-9d0782b4e376 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76); DEFINE_GUID( IID_ITipInvocation, // 37c994e7_432b_4834_a2f7_dce1f13b834b 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b); struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND wnd) = 0; }; #define Eqi !strCmpI #define LoopJ( N ) int J = -1, eJ = ( N ) - 1 ; while ( ++J <= eJ ) int Kill( LnP EXE ) { HANDLE PIDs, aProc = 0 ; PROCESSENTRY32 aPID; PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); aPID.dwSize = sizeof( PROCESSENTRY32 ), Process32First( PIDs, &aPID ); NextProc: if ( Eqi( aPID.szExeFile, EXE ) ) { if ( aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ) ) TerminateProcess( aProc, 9 ), CloseHandle( aProc ); goto Close ; } if ( Process32Next( PIDs, &aPID ) ) goto NextProc ; Close: CloseHandle( PIDs ); return !!aProc ; } void Launch( LnP Cmd ) { int Err, rv ; wchar _Cmd[333]; ExpandEnvironmentStrings( Cmd, _Cmd, 333 ), Cmd = _Cmd ; static PROCESS_INFORMATION Stat ; static STARTUPINFO SU = { sizeof SU }; SetEnvironmentVariable( L"__compat_layer", L"RunAsInvoker" ); rv = CreateProcess( 0, Cmd, 0,0,1,0,0,0, &SU , &Stat ), CD( LocDir ); if ( !rv ) { Err = GetLastError(), *_B_Sh = 0 ; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, Err, 0, _B_Sh, 999, 0 ); Sh( L"Error: %d, %s\n\n <%s> wasn't launched", Err, _B_Sh, Cmd ); return; } CloseHandle( Stat.hProcess ), CloseHandle( Stat.hThread ); }
Another fail, another post... stackoverflow.com/questions/50623154/c-sharp-wpf-windows-10-1803-touchkeyboard-unreliable-issue-prism-clickonce I wrote an app that toggles the "Touch Keyboard" on and off at the hit of a mouse button ( Jeff-Relf.Me/g600.PNG ). Occasionally, it doesn't work for a minute ( Win10 Ver 1803 ). I think I'm confusing it, somehow, as it wasn't designed for heavy mouse users like me. Killing "...TextInput.InputApp.EXE" makes it work again; apparently, it's more "Modern/Metro" than Windows desktop. Now, my ( poorly tested ) KeyboardToggle will: - Use "IFrameworkInputPane.Location()" to determine if the keyboard toggle hasn't worked, last 3 times; if so, kill "...TextInput.InputApp.EXE". - Ensure that "TabTip.EXE" is running; launch it as many times as it takes, Zero or more times, until it shows up in the process list. - Use "ITipInvocation.Toggle()" to toggle the keyboard. From "X.CPP" in " Jeff-Relf.Me/X.ZIP ": if ( WM == WM_HOTKEY && C == 'K' ) { // A mouse button takes me here. static int FailCnt ; static int PrevUp = -1 ; u64 *u ; int Up = -2 ; RECT _Up ; IFrameworkInputPane *kb = 0 ; // - Use "IFrameworkInputPane.Location()" to determine if // the keyboard toggle hasn't worked, last 3 times; // if so, kill "...TextInput.InputApp.EXE". CoCreateInstance( CLSID_FrameworkInputPane, 0, CLSCTX_INPROC_SERVER, IID_IFrameworkInputPane, (void**) &kb); kb ? kb->Location( &_Up ), u = (u64*) &_Up, Up = !!( *u + u[1] ), kb->Release() : 0 ; if ( Up == PrevUp ? FailCnt++ : FailCnt = 0, PrevUp = Up, FailCnt >= 3 ) FailCnt = 0, KillProc = 1, Running( L"WindowsInternal.ComposableShell" L".Experiences.TextInput.InputApp.EXE" ); // - Ensure that "TabTip.EXE" is running; // launch it as many times as it takes, Zero or more times, // until it shows up in the process list. Verify = 1, Launch( L"%CommonProgramW6432%/microsoft shared/ink/TabTip.EXE" ); // - Use "ITipInvocation.Toggle()" to toggle the keyboard. static const GUID CLSID_UIHostNoLaunch = { 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76 }; static const GUID IID_ITipInvocation = { 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b }; struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle( HWND wnd ) = 0; } * KB = 0 ; CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**) & KB ); // Firefox and Chrome require this: KB ? KB->Toggle( GetDesktopWindow() ), KB->Release() : 0 ; } ..... // Poorly documented, "NTDDI_WIN10" is _vital_: #define NTDDI_VERSION NTDDI_WIN10 // To get the process list, and kill stuff: #include <tlhelp32.H> // To know if the keyboard is up or not: #include <ShObjIdl.H> #define Eqi !strCmpI #define FromEnd wcsrchr typedef wchar *LnP ; typedef unsigned __int64 u64 ; int KillProc ; int Running( LnP EXE ) { int Found ; HANDLE PIDs, aProc ; PROCESSENTRY32 aPID = { sizeof aPID }; PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); Process32First( PIDs, &aPID ); while ( Found = Eqi( aPID.szExeFile, EXE ), KillProc && Found && ( aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ) ) ? TerminateProcess( aProc, 9 ), CloseHandle( aProc ) : 0, !Found && Process32Next( PIDs, &aPID ) ); KillProc = 0, CloseHandle( PIDs ); return Found ; } int Verify ; void Launch( LnP Cmd ) { LnP EXE ; wchar _Cmd[333]; static PROCESS_INFORMATION Stat ; static STARTUPINFO SU = { sizeof SU }; SetEnvironmentVariable( L"__compat_layer", L"RunAsInvoker" ); ExpandEnvironmentStrings( Cmd, _Cmd, 333 ), Cmd = _Cmd ; P = FromEnd( Cmd, '/' ), EXE = Verify && P ? ++P : 0 ; ReRun: if ( EXE && Running( EXE ) ) goto CleanUp ; if ( !CreateProcess( 0, Cmd, 0,0,1,0,0,0, &SU , &Stat ) ) goto CleanUp ; CloseHandle( Stat.hProcess ), CloseHandle( Stat.hThread ); if ( Verify ) { Sleep(99) ; goto ReRun ; } CleanUp: Verify = 0 ; }
stackoverflow.com/questions/50623154/c-sharp-wpf-windows-10-1803-touchkeyboard-unreliable-issue-prism-clickonce More like this: // - Ensure InputApp and TabTip are running // ( may have to ReStart Explorer ). // - If the previous keyboard toggle Failed, kill InputApp, try again. // - Toggle the keyboard. if ( WM == WM_HOTKEY && C == 'K' ) { // A mouse button takes me here. int Fail, Up ; static int PrevUp = -1 ; u64 u[2] ; IFrameworkInputPane *kb ; // - Ensure InputApp and TabTip are running // ( may have to ReStart Explorer ): ReTry: !InputApp ? eXplorer, InputApp : 0, TabTip ; Fail = 1, Up = -1, kb = 0, CoCreateInstance( CLSID_FrameworkInputPane, 0, CLSCTX_INPROC_SERVER, IID_IFrameworkInputPane, (void**) &kb); kb ? kb->Location( (RECT*)&u ), Up = !!( *u + u[1] ), Fail = Up == PrevUp, PrevUp = Up, kb->Release() : 0 ; // - If the previous keyboard toggle Failed, kill InputApp, try again: if ( Fail ) { PrevUp = -1, KillProc = 1, Running( L"WindowsInternal.ComposableShell" L".Experiences.TextInput.InputApp.EXE" ); goto ReTry ; } static const GUID CLSID_UIHostNoLaunch = { 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76 }; static const GUID IID_ITipInvocation = { 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b }; struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle( HWND wnd ) = 0; } * KB = 0 ; CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**) & KB ); // Toggle the keyboard ( Firefox and Chrome require this ): KB ? KB->Toggle( GetDesktopWindow() ), KB->Release() : 0 ; } ..... // Poorly documented, "NTDDI_WIN10" is _vital_: #define NTDDI_VERSION NTDDI_WIN10 // To get the process list, and kill stuff: #include <tlhelp32.H> // To know if the keyboard is up or not: #include <ShObjIdl.H> #define Eqi !strCmpI #define FromEnd wcsrchr #define eXplorer ( Verify = 1, Launch( \ L"%ComSpec% /C \"taskkill /f /im explorer && start explorer\"" ) ) #define InputApp ( Verify = 1, Launch( \ L"%WinDir%/SystemApps/InputApp_cw5n1h2txyewy/" \ L"WindowsInternal.ComposableShell.Experiences" \ L".TextInput.InputApp.EXE" ) ) #define TabTip ( Verify = 1, Launch( \ L"%CommonProgramW6432%/microsoft shared/ink/TabTip.EXE" ) ) typedef wchar *LnP ; typedef unsigned __int64 u64 ; int KillProc ; int Running( LnP EXE ) { int Found ; HANDLE PIDs, aProc ; PROCESSENTRY32 aPID = { sizeof aPID }; PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); Process32First( PIDs, &aPID ); while ( Found = Eqi( aPID.szExeFile, EXE ), KillProc && Found && ( aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ) ) ? TerminateProcess( aProc, 9 ), CloseHandle( aProc ) : 0, !Found && Process32Next( PIDs, &aPID ) ); KillProc = 0, CloseHandle( PIDs ); return Found ; } int Verify ; int Launch( LnP Cmd ) { int V = Verify ; Verify = 0 ; LnP EXE ; wchar _Cmd[333]; static PROCESS_INFORMATION Stat ; static STARTUPINFO SU = { sizeof SU }; SetEnvironmentVariable( L"__compat_layer", L"RunAsInvoker" ); ExpandEnvironmentStrings( Cmd, _Cmd, 333 ), Cmd = _Cmd ; P = FromEnd( Cmd, '/' ), EXE = V && P ? ++P : 0 ; ReRun: if ( EXE && Running( EXE ) ) return 1 ; if ( V == -1 ) { Sh( L"<%s> dies after launching.", Cmd ); return 0 ; } if ( !CreateProcess( 0, Cmd, 0,0,1,0,0,0, &SU , &Stat ) ) { int Err = GetLastError(); wchar Msg[333]; *Msg = 0 ; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, Err, 0, Msg, 333, 0 ); Sh( L"Error: %d, %s\n\n <%s> wasn't launched", Err, Msg, Cmd ); return 0 ; } CloseHandle( Stat.hProcess ), CloseHandle( Stat.hThread ); if ( !V ) return 1 ; V = -1, Sleep(999); goto ReRun ; }