Add hook filter for system keys (eg. ALT+TAB, ALT+ESC, CTRL+ESC) - #145, #556

This commit is contained in:
tomcw 2018-05-27 10:56:35 +01:00
parent 20cd8913f5
commit 19b90800cf
5 changed files with 268 additions and 2 deletions

View File

@ -20,6 +20,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "libyaml\win32\yaml2
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestDebugger", "test\TestDebugger\TestDebugger.vcproj", "{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HookFilter", "HookFilter\HookFilter.vcproj", "{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -50,6 +52,10 @@ Global
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Debug|Win32.Build.0 = Debug|Win32
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Release|Win32.ActiveCfg = Release|Win32
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Release|Win32.Build.0 = Release|Win32
{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug|Win32.ActiveCfg = Debug|Win32
{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Debug|Win32.Build.0 = Debug|Win32
{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release|Win32.ActiveCfg = Release|Win32
{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

41
HookFilter/HookFilter.cpp Normal file
View File

@ -0,0 +1,41 @@
#include <windows.h>
// https://stackoverflow.com/questions/2490577/suppress-task-switch-keys-winkey-alt-tab-alt-esc-ctrl-esc-using-low-level-k
// NB. __stdcall (or WINAPI) and extern "C":
// . symbol is decorated as _<symbol>@bytes
// . so use the #pragma to create an undecorated alias for our symbol
extern "C" __declspec(dllexport) LRESULT CALLBACK LowLevelKeyboardProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
#pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
if (nCode >= 0)
{
bool suppress = false;
PKBDLLHOOKSTRUCT pKbdLlHookStruct = (PKBDLLHOOKSTRUCT) lParam;
// Suppress alt-tab.
if (pKbdLlHookStruct->vkCode == VK_TAB && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN))
suppress = true;
// Suppress alt-escape.
if (pKbdLlHookStruct->vkCode == VK_ESCAPE && (pKbdLlHookStruct->flags & LLKHF_ALTDOWN))
suppress = true;
// Suppress ctrl-escape.
bool ControlDown = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
if (pKbdLlHookStruct->vkCode == VK_ESCAPE && ControlDown)
suppress = true;
// Suppress keys by returning 1.
if (suppress)
return 1;
}
return CallNextHookEx(0/*parameter is ignored*/, nCode, wParam, lParam);
}

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="AppleWinHookFilter"
ProjectGUID="{AA5854AD-2BC7-4EFD-9790-349ADB35E35A}"
RootNamespace="HookFilter"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;HOOKFILTER_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\HookFilter.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -58,7 +58,7 @@
<li>6551 ACIA Status register's error bits: overrun, framing and parity (these are all hardcoded to 0).
<li>6551 ACIA Status register's DCD bit (Data Carrier Detect). This is just set the same as DSR.
<ul>
<li>NB. Use command line -dcd to force AppleWin to use the state of the MS_RLSD_ON bit from GetCommModemStatus().
<li>NB. For COM mode, use command line -dcd to force AppleWin to use the state of the MS_RLSD_ON bit from GetCommModemStatus().
</ul>
<li>NMOS 6551 ACIA CTS bug: transmission of an already-started frame will stop immediately when CTS is taken false, the byte will be lost, and the TxD line will go to marking.
<ul>

View File

@ -1012,6 +1012,40 @@ static void InsertHardDisks(LPSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBo
//---------------------------------------------------------------------------
static HINSTANCE g_hinstDLL = 0;
static HHOOK g_hhook = 0;
void HookFilterForKeyboard()
{
g_hinstDLL = LoadLibrary(TEXT("AppleWinHookFilter.dll"));
HOOKPROC hkprcLowLevelKeyboardProc = (HOOKPROC) GetProcAddress(g_hinstDLL, "LowLevelKeyboardProc");
g_hhook = SetWindowsHookEx(
WH_KEYBOARD_LL,
hkprcLowLevelKeyboardProc,
g_hinstDLL,
0);
if (g_hhook == NULL)
{
std::string msg("Failed to install hook filter for system keys");
DWORD dwErr = GetLastError();
MessageBox(GetDesktopWindow(), msg.c_str(), "Warning", MB_ICONASTERISK | MB_OK); // NB. g_hFrameWindow is not yet valid
msg += "\n";
LogFileOutput(msg.c_str());
}
}
void UnhookFilterForKeyboard()
{
UnhookWindowsHookEx(g_hhook);
FreeLibrary(g_hinstDLL);
}
//---------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{
bool bShutdown = false;
@ -1310,6 +1344,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
DiskInitialize();
LogFileOutput("Init: DiskInitialize()\n");
HookFilterForKeyboard();
//
do
@ -1475,6 +1511,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
}
while (g_bRestart);
UnhookFilterForKeyboard();
if (bChangedDisplayResolution)
ChangeDisplaySettings(NULL, 0); // restore default