diff --git a/.gitignore b/.gitignore index 9453ba3..ea169fc 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ *.hem .nobackup build-*/ +*.zip diff --git a/GNUmakefile b/GNUmakefile index 4042c4e..a64d300 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,16 +1,16 @@ -include ../GNUmakefile.common +include GNUmakefile.common LDLIBS += user32 %.hem: %.dll - cp $< $@ + $(CP) $< $@ all: keyhelp.hem -keyhelp.dll: input.obj keyhelp.obj hiewgate.obj +keyhelp.dll: input.obj keyhelp.obj hiewgate.obj hiewkey.res clean:: $(RM) *.hem -install: keyhelp.hem - cp $^ ~/User/Applications/Hiew/hem/ +release:: + zip hiewkey.zip keyhelp.hem README.md diff --git a/GNUmakefile.common b/GNUmakefile.common new file mode 100644 index 0000000..e776da6 --- /dev/null +++ b/GNUmakefile.common @@ -0,0 +1,191 @@ +# vim: syntax=make +# +# Reasonable default GNU Makefile rules for new Windows development projects. +# +# Notes +# +# * You can append rules to clean by using clean:: +# * If you dont want the default rules, use one colon, e.g. clean: +# * Add everything you want built as a dependency to all +# * Append to existing flags/lists with +=, e.g. LDLIBS+=user32 +# * Target specific changes should look like target: CFLAGS+=/xyz +# * `make debug` is the same as `make all` but without optimization flags. +# * `make release` is the same as `make all` but with NDEBUG and similar. +# * You can append rules to debug and release, just use :: +# * You dont need to override pattern commands, just do this: +# include ../GNUmakefile.common +# all: example.dll +# # The main file should be called example.c +# example.dll: otherdep1.obj otherdep2.obj +# * Append warnings you don't like to WIGNORE, e.g. WIGNORE+=/wd1234 +# +# Examples +# +# simplest +# +# include ../GNUmakefile.common +# +# all: example.exe +# +# dependencies +# +# include ../GNUmakefile.common +# +# all: example.exe +# +# example.exe: example.obj foo.obj bar.obj +# +# cmake +# +# .INTERMEDIATE: cmake@dirname +# test.lib: CMPROJECT=Check # name of the project, default is name of dir +# test.lib: cmake@dirname # where the CMakeLists.txt is +# cp build-$(CMPROJECT)/foo.lib $@ +# +# +# (c) 2019-2020 Tavis Ormandy +# +CC=cl.exe +RC=rc.exe +AR=lib.exe +MIDL=midl.exe +MB=msbuild.exe +MT=mt.exe +CANDLE=candle.exe +LIGHT=light.exe +VSDEVCMD=cmd.exe /c vsdevcmd.bat +CANDLEFLAGS=-nologo +LIGHTFLAGS=-nologo +CPPFLAGS= +RFLAGS=/nologo +COPTFLAGS=/O2 +CSECFLAGS=/guard:cf +CDEBFLAGS=/Wall /analyze $(WIGNORE) +BUILDCONFIG=Release +CFLAGS=/nologo $(CPPFLAGS) /Zi $(COPTFLAGS) $(CSECFLAGS) /GF +LFLAGS=/nologo /machine:x86 +MFLAGS= +MTFLAGS=-nologo -canonicalize +CXXFLAGS=$(CFLAGS) /EHsc +LDLIBS= +LDFLAGS=/MT +LINKFLAGS= +CM=cmake.exe +CMFLAGS=-A Win32 -D CMAKE_BUILD_TYPE=$(BUILDCONFIG) +MBFLAGS=/nologo /m \ + /verbosity:quiet \ + /p:Configuration=$(BUILDCONFIG) \ + /p:PlatformToolset=v142 \ + /p:WindowsTargetPlatformVersion=10 +VFLAGS=-no_logo +CMPROJECT=$( diff --git a/hiewkey.png b/hiewkey.png new file mode 100755 index 0000000..6032f3d Binary files /dev/null and b/hiewkey.png differ diff --git a/hiewkey.rc b/hiewkey.rc new file mode 100644 index 0000000..9cd31d5 --- /dev/null +++ b/hiewkey.rc @@ -0,0 +1,26 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 +{ + BLOCK "StringFileInfo" + { + BLOCK "000004B0" + { + VALUE "CompanyName", "Tavis Ormandy" + VALUE "FileDescription", "Hiew Keyboard Helper" + VALUE "ProductName", "Hiewkey" + VALUE "Comment", "https://github.com/taviso/hiewkey" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0000, 0x04B0 + } +} diff --git a/input.c b/input.c index 761bbad..08e9a73 100644 --- a/input.c +++ b/input.c @@ -247,9 +247,17 @@ BOOL DecodeKeyString(LPCSTR HotKey, PKEY_EVENT_RECORD Record) } } - // In general, for ascii chars the lowercase form seems to be used. if (KeyCode == Record->uChar.AsciiChar && isalpha(KeyCode)) { + + // In general, for ascii chars the lowercase form seems to be used. Record->uChar.AsciiChar = tolower(KeyCode); + + // If you hold ctrl, you get the ctrl characters, in alphabetic + // order. + if (CtrlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { + // Is this right?????????????? + Record->uChar.AsciiChar -= 'a' - 1; + } } if (KeyCode == Record->uChar.AsciiChar && isdigit(KeyCode)) { @@ -258,6 +266,11 @@ BOOL DecodeKeyString(LPCSTR HotKey, PKEY_EVENT_RECORD Record) // without localization, so I'll just simulate it. Record->uChar.AsciiChar = ")!@#$%^&*("[KeyCode - '0']; } + // fallthrough intentional. + // If CTRL is pressed with a digit, AsciiChar is always 0. + if (CtrlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { + Record->uChar.AsciiChar = 0; + } } // https://www.codeproject.com/Questions/511401/apluslittleplusaboutplusMSGplusHandingplusaboutplu @@ -269,9 +282,28 @@ BOOL DecodeKeyString(LPCSTR HotKey, PKEY_EVENT_RECORD Record) } } - if (KeyCode == VK_OEM_PERIOD) { - if (CtrlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { - Record->uChar.AsciiChar = 0; + // This needs some work to understand. + if (CtrlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { + switch (KeyCode) { + case VK_RETURN: + Record->uChar.AsciiChar = '\n'; + break; + case VK_OEM_7: // '#' + Record->uChar.AsciiChar = 28; + break; + case VK_OEM_4: // '[' + case VK_OEM_6: // ']' + case VK_OEM_5: // '\\' + Record->uChar.AsciiChar -= 'A' - 1; + break; + case VK_OEM_1: // ';' + case VK_OEM_3: // '~' + case VK_OEM_PERIOD: + case VK_OEM_MINUS: + case VK_OEM_PLUS: + case VK_TAB: + Record->uChar.AsciiChar = 0; + break; } } diff --git a/keyhelp.c b/keyhelp.c index d274732..f5b31b7 100644 --- a/keyhelp.c +++ b/keyhelp.c @@ -38,7 +38,10 @@ typedef struct _HIEW_KEYS { static HIEW_KEYS HiewKeys[] = { { "Ctrl+Alt", "information" }, { "Ctrl+Backspace", "file history" }, - { "Ctrl+.", "start/stop recording macro to Macro0" } + { "Ctrl+.", "start/stop recording macro to Macro0" }, + { "Ctrl+-", "Macro manager" }, + { "Ctrl+NumMult", "mark all" }, + { "Alt+NumMult", "resize block to current offset" }, }; DWORD WINAPI SendInputThread(LPVOID lpvThreadParam);