├── .gitattributes ├── AltSnap.dni ├── AltSnap.exe.manifest ├── AltSnap.txt ├── AltSnap.xml ├── HelpImages ├── 12buttons_example.png ├── ActionMenu.png ├── AdvancedDiag.png ├── BlacklistDiag.png ├── Fractions.png ├── GeneralDiag.png ├── KeyboardDiag.png ├── MouseDiag.png ├── SnpaLayoutEg.png ├── TestWindow.png ├── taskmgr1.png ├── taskmgr2.png ├── taskmgr3.png ├── taskmgr4.png └── unikeymenu.png ├── Lang ├── _en_US baseline.txt ├── ca_ES.ini ├── de_DE.ini ├── es_ES.ini ├── fi_FI.ini ├── fr_FR.ini ├── gl_ES.ini ├── it_IT.ini ├── ja_JP.ini ├── ko_KR.ini ├── nb_NO.ini ├── nl_NL.ini ├── pl_PL.ini ├── pt_PR.ini ├── ru_RU.ini ├── sz_SK.ini ├── tr_TR.ini ├── zh_CN.ini └── zh_TW.ini ├── License.txt ├── Makefile ├── MakefileClang ├── MakefileClangdb ├── MakefileTCC ├── MakefileX64 ├── MakefileX64db ├── Makefiledb ├── README.md ├── README_ko-KR.md ├── README_zh-CN.md ├── Themes └── erasmion │ ├── TRAY_OFF.ico │ ├── TRAY_ON.ico │ └── TRAY_SUS.ico ├── altsnap.c ├── altsnap.nsi ├── altsnap.rc ├── config.c ├── hooks.c ├── hooks.h ├── hooks.rc ├── languages.c ├── languages.h ├── makerelease.bat ├── media ├── find.cur ├── find.ico ├── icon.ico ├── tray-disabled.ico ├── tray-enabled.ico ├── tray-suspended.ico └── tray-suspended2.ico ├── mk.bat ├── mk64.bat ├── mkvcc6.bat ├── nanolibc.h ├── nsi.bat ├── oldmk64.bat ├── resource.h ├── sch_Off.bat ├── sch_On.bat ├── snap.c ├── thunks.c ├── tray.c ├── unfuck.h ├── window.rc ├── ziprelease.bat ├── zones.c └── zzip.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | *.dni diff merge text linguist-language=ini working-tree-encoding=utf-16le-bom 2 | Lang/* diff merge text linguist-language=ini working-tree-encoding=utf-16le-bom 3 | -------------------------------------------------------------------------------- /AltSnap.dni: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/AltSnap.dni -------------------------------------------------------------------------------- /AltSnap.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | true 20 | PerMonitorV2,PerMonitor 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /AltSnap.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/AltSnap.txt -------------------------------------------------------------------------------- /AltSnap.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/AltSnap.xml -------------------------------------------------------------------------------- /HelpImages/12buttons_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/12buttons_example.png -------------------------------------------------------------------------------- /HelpImages/ActionMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/ActionMenu.png -------------------------------------------------------------------------------- /HelpImages/AdvancedDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/AdvancedDiag.png -------------------------------------------------------------------------------- /HelpImages/BlacklistDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/BlacklistDiag.png -------------------------------------------------------------------------------- /HelpImages/Fractions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/Fractions.png -------------------------------------------------------------------------------- /HelpImages/GeneralDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/GeneralDiag.png -------------------------------------------------------------------------------- /HelpImages/KeyboardDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/KeyboardDiag.png -------------------------------------------------------------------------------- /HelpImages/MouseDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/MouseDiag.png -------------------------------------------------------------------------------- /HelpImages/SnpaLayoutEg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/SnpaLayoutEg.png -------------------------------------------------------------------------------- /HelpImages/TestWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/TestWindow.png -------------------------------------------------------------------------------- /HelpImages/taskmgr1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/taskmgr1.png -------------------------------------------------------------------------------- /HelpImages/taskmgr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/taskmgr2.png -------------------------------------------------------------------------------- /HelpImages/taskmgr3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/taskmgr3.png -------------------------------------------------------------------------------- /HelpImages/taskmgr4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/taskmgr4.png -------------------------------------------------------------------------------- /HelpImages/unikeymenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/HelpImages/unikeymenu.png -------------------------------------------------------------------------------- /Lang/_en_US baseline.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/_en_US baseline.txt -------------------------------------------------------------------------------- /Lang/ca_ES.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/ca_ES.ini -------------------------------------------------------------------------------- /Lang/de_DE.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/de_DE.ini -------------------------------------------------------------------------------- /Lang/es_ES.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/es_ES.ini -------------------------------------------------------------------------------- /Lang/fi_FI.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/fi_FI.ini -------------------------------------------------------------------------------- /Lang/fr_FR.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/fr_FR.ini -------------------------------------------------------------------------------- /Lang/gl_ES.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/gl_ES.ini -------------------------------------------------------------------------------- /Lang/it_IT.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/it_IT.ini -------------------------------------------------------------------------------- /Lang/ja_JP.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/ja_JP.ini -------------------------------------------------------------------------------- /Lang/ko_KR.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/ko_KR.ini -------------------------------------------------------------------------------- /Lang/nb_NO.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/nb_NO.ini -------------------------------------------------------------------------------- /Lang/nl_NL.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/nl_NL.ini -------------------------------------------------------------------------------- /Lang/pl_PL.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/pl_PL.ini -------------------------------------------------------------------------------- /Lang/pt_PR.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/pt_PR.ini -------------------------------------------------------------------------------- /Lang/ru_RU.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/ru_RU.ini -------------------------------------------------------------------------------- /Lang/sz_SK.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/sz_SK.ini -------------------------------------------------------------------------------- /Lang/tr_TR.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/tr_TR.ini -------------------------------------------------------------------------------- /Lang/zh_CN.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/zh_CN.ini -------------------------------------------------------------------------------- /Lang/zh_TW.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Lang/zh_TW.ini -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | WR=windres 3 | 4 | WARNINGS=-Wall \ 5 | -Wformat-security \ 6 | -Wstrict-overflow \ 7 | -Wsign-compare \ 8 | -Wclobbered \ 9 | -Wempty-body \ 10 | -Wignored-qualifiers \ 11 | -Wsuggest-attribute=pure \ 12 | -Wsuggest-attribute=const \ 13 | -Wsuggest-attribute=noreturn \ 14 | -Wuninitialized \ 15 | -Wtype-limits \ 16 | -Woverride-init \ 17 | -Wlogical-op \ 18 | -Wno-multichar \ 19 | -Wno-attributes \ 20 | -Wno-unused-function \ 21 | -Wshadow \ 22 | -Warray-bounds=2 \ 23 | -Wstack-usage=4096 \ 24 | -Werror=vla \ 25 | -pedantic \ 26 | -Wc++-compat 27 | -Wstringop-overflow=4 \ 28 | -Wduplicated-cond \ 29 | -Wduplicated-branches \ 30 | -Wnull-dereference \ 31 | 32 | # -Wunused-parameter 33 | # -Wtraditional-conversion 34 | # -fira-region=one/mixed 35 | # -Wstack-usage=2048 36 | # -finput-charset=UTF-8 37 | # -Wc++-compat 38 | # -fmerge-all-constants 39 | 40 | CFLAGS=-Os -std=c99 \ 41 | -finput-charset=UTF-8 \ 42 | -fshort-wchar \ 43 | -m32 -march=i386 -mtune=i686 \ 44 | -mno-stack-arg-probe \ 45 | -mpreferred-stack-boundary=2 \ 46 | -momit-leaf-frame-pointer \ 47 | -fno-stack-check \ 48 | -fno-stack-protector \ 49 | -fno-ident \ 50 | -fomit-frame-pointer \ 51 | -fshort-enums \ 52 | -fno-exceptions \ 53 | -fno-dwarf2-cfi-asm \ 54 | -fno-asynchronous-unwind-tables \ 55 | -fmerge-all-constants \ 56 | -fno-semantic-interposition \ 57 | -fgcse-sm \ 58 | -fgcse-las \ 59 | -D__USE_MINGW_ANSI_STDIO=0 \ 60 | -Wp,-D_FORTIFY_SOURCE=2 \ 61 | $(WARNINGS) \ 62 | -fno-plt 63 | 64 | LDFLAGS=-nostdlib \ 65 | -lmsvcrt \ 66 | -lkernel32 \ 67 | -luser32 \ 68 | -lgdi32 \ 69 | -s \ 70 | -Wl,-s,-dynamicbase \ 71 | -Wl,-nxcompat \ 72 | -Wl,--no-seh \ 73 | -Wl,--relax \ 74 | -Wl,--disable-runtime-pseudo-reloc \ 75 | -Wl,--enable-auto-import \ 76 | -Wl,--disable-stdcall-fixup \ 77 | 78 | EXELD = $(LDFLAGS) \ 79 | -Wl,--tsaware \ 80 | -lcomctl32 \ 81 | -ladvapi32 \ 82 | -lshell32 \ 83 | -Wl,--disable-reloc-section 84 | 85 | default: AltSnap.exe hooks.dll 86 | 87 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 88 | $(CC) -o hooks.dll hooks.c hooksr.o $(CFLAGS) $(LDFLAGS) -mdll -e_DllMain@12 -Wl,--kill-at 89 | 90 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 91 | $(CC) -o AltSnap.exe altsnap.c altsnapr.o $(CFLAGS) $(EXELD) -mwindows -e_unfuckWinMain@0 92 | 93 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 94 | $(WR) altsnap.rc altsnapr.o -Fpe-i386 95 | 96 | hooksr.o: hooks.rc 97 | $(WR) hooks.rc hooksr.o -Fpe-i386 98 | 99 | clean : 100 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 101 | -------------------------------------------------------------------------------- /MakefileClang: -------------------------------------------------------------------------------- 1 | CC=clang 2 | WR=llvm-rc 3 | 4 | # We need to include MINGW headers files (for i386 here) 5 | MINGW=-ID:\Straw\llvm-mingw\include \ 6 | -LD:\Straw\llvm-mingw\i686-w64-mingw32\lib 7 | 8 | 9 | WARNINGS=-Wall \ 10 | -Wformat-security \ 11 | -Wstrict-overflow \ 12 | -Wsign-compare \ 13 | -Wempty-body \ 14 | -Wignored-qualifiers \ 15 | -Wuninitialized \ 16 | -Wtype-limits \ 17 | -Wno-multichar \ 18 | -Wno-attributes \ 19 | -Wnull-dereference \ 20 | -Wno-unused-function \ 21 | -Wshadow \ 22 | -Werror=vla \ 23 | -Wno-typedef-redefinition \ 24 | -Wno-macro-redefined \ 25 | -Wno-unknown-pragmas \ 26 | -Wno-missing-declarations \ 27 | -Wno-pragma-pack 28 | 29 | # -Wunused-parameter 30 | # -Wtraditional-conversion 31 | # -fira-region=one/mixed 32 | # -Wstack-usage=2048 33 | # -finput-charset=UTF-8 34 | # -Wc++-compat 35 | 36 | CFLAGS=-Os -std=c99 \ 37 | -target i386-pc-windows-gnu \ 38 | -finput-charset=UTF-8 \ 39 | -m32 -march=i386 -mtune=i686 \ 40 | -momit-leaf-frame-pointer \ 41 | -fno-stack-check \ 42 | -fno-stack-protector \ 43 | -fno-ident \ 44 | -fomit-frame-pointer \ 45 | -fshort-enums \ 46 | -fno-exceptions \ 47 | -fno-dwarf2-cfi-asm \ 48 | -fno-asynchronous-unwind-tables \ 49 | -D__USE_MINGW_ANSI_STDIO=0 \ 50 | -Wp,-D_FORTIFY_SOURCE=2 \ 51 | $(WARNINGS) \ 52 | $(MINGW) \ 53 | -DCLANG 54 | 55 | 56 | LDFLAGS=-nostdlib \ 57 | -lkernel32 \ 58 | -luser32 \ 59 | -lgdi32 \ 60 | -s \ 61 | -Wl,-s,-dynamicbase \ 62 | -Wl,-nxcompat \ 63 | -Wl,--no-seh \ 64 | -Wl,--enable-auto-import 65 | 66 | EXELD = $(LDFLAGS) \ 67 | -Wl,--tsaware \ 68 | -lcomctl32 \ 69 | -ladvapi32 \ 70 | -lshell32 71 | 72 | default: AltSnap.exe hooks.dll 73 | 74 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 75 | $(CC) -o hooks.dll hooks.c hooks.res $(CFLAGS) $(LDFLAGS) -shared -e_DllMain@12 -v -Wl,--kill-at 76 | 77 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 78 | $(CC) -o AltSnap.exe altsnap.c altsnap.res $(CFLAGS) $(EXELD) -mwindows -e_unfuckWinMain@0 -v 79 | 80 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 81 | $(WR) altsnap.rc 82 | 83 | hooksr.o: hooks.rc 84 | $(WR) hooks.rc 85 | 86 | clean : 87 | rm altsnap.res AltSnap.exe hooks.res hooks.dll 88 | -------------------------------------------------------------------------------- /MakefileClangdb: -------------------------------------------------------------------------------- 1 | CC=clang 2 | WR=llvm-rc 3 | 4 | # We need to include GCC headers files (for i386 here) 5 | #MINGW=-ID:\Straw\tdm64\x86_64-w64-mingw32\include \ 6 | # -LD:\Straw\tdm64\x86_64-w64-mingw32\lib32 7 | MINGW=-ID:\Straw\llvm-mingw\include \ 8 | -LD:\Straw\llvm-mingw\i686-w64-mingw32\lib 9 | 10 | 11 | WARNINGS=-Wall \ 12 | -Wformat-security \ 13 | -Wstrict-overflow \ 14 | -Wsign-compare \ 15 | -Wempty-body \ 16 | -Wignored-qualifiers \ 17 | -Wuninitialized \ 18 | -Wtype-limits \ 19 | -Wno-multichar \ 20 | -Wno-attributes \ 21 | -Wnull-dereference \ 22 | -Wno-unused-function \ 23 | -Wshadow \ 24 | -Werror=vla \ 25 | -Wno-typedef-redefinition \ 26 | -Wno-macro-redefined \ 27 | -Wno-unknown-pragmas \ 28 | -Wno-missing-declarations \ 29 | -Wno-pragma-pack 30 | 31 | # -Wunused-parameter 32 | # -Wtraditional-conversion 33 | # -fira-region=one/mixed 34 | # -Wstack-usage=2048 35 | # -finput-charset=UTF-8 36 | # -Wc++-compat 37 | 38 | CFLAGS=-Og -g -std=c99 \ 39 | -target i386-pc-windows-gnu \ 40 | -finput-charset=UTF-8 \ 41 | -m32 -march=i386 -mtune=i686 \ 42 | -fshort-enums \ 43 | -fno-asynchronous-unwind-tables \ 44 | -fsanitize=address \ 45 | -fno-omit-frame-pointer \ 46 | -D__USE_MINGW_ANSI_STDIO=0 \ 47 | -Wp,-D_FORTIFY_SOURCE=2 \ 48 | $(WARNINGS) \ 49 | $(MINGW) \ 50 | -DCLANG 51 | 52 | 53 | LDFLAGS=-lkernel32 \ 54 | -luser32 \ 55 | -lgdi32 \ 56 | -Wl,-dynamicbase \ 57 | -Wl,-nxcompat \ 58 | -Wl,--no-seh 59 | 60 | EXELD = $(LDFLAGS) \ 61 | -Wl,--tsaware \ 62 | -lcomctl32 \ 63 | -ladvapi32 \ 64 | -lshell32 \ 65 | 66 | default: AltSnap.exe hooks.dll 67 | 68 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 69 | $(CC) -o hooks.dll hooks.c hooks.res $(CFLAGS) $(LDFLAGS) -shared -e_DllMain@12 -v -Wl,--kill-at 70 | 71 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 72 | $(CC) -o AltSnap.exe altsnap.c altsnap.res $(CFLAGS) $(EXELD) -mwindows -e_unfuckWinMain@0 -v 73 | 74 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 75 | $(WR) altsnap.rc 76 | 77 | hooksr.o: hooks.rc 78 | $(WR) hooks.rc 79 | 80 | clean : 81 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 82 | -------------------------------------------------------------------------------- /MakefileTCC: -------------------------------------------------------------------------------- 1 | CC=tcc 2 | # You still need a resource builder, gcc's windres works just fine. 3 | WR=windres 4 | 5 | CFLAGS=-w -m32 -Os -DNO_VISTA 6 | 7 | DLLEXP=-DLOAD_PROC=\"_Load@4\" -DLOW_LEVEL_KB_PROC=\"_LowLevelKeyboardProc@12\" -DUNLOAD_PROC=\"_Unload@0\" 8 | 9 | LDFLAGS= \ 10 | -lmsvcrt \ 11 | -lkernel32 \ 12 | -luser32 \ 13 | -lgdi32 \ 14 | -ladvapi32 \ 15 | 16 | EXELD = $(LDFLAGS) \ 17 | -lcomctl32 \ 18 | -ladvapi32 \ 19 | -lshell32 20 | 21 | default: AltSnap.exe hooks.dll 22 | 23 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 24 | $(CC) -o hooks.dll hooks.c hooksr.o $(CFLAGS) $(LDFLAGS) -shared 25 | 26 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 27 | $(CC) -o AltSnap.exe altsnap.c altsnapr.o $(DLLEXP) $(CFLAGS) $(EXELD) -Wl,-subsystem=gui -DtWinMain=wWinMain 28 | 29 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 30 | $(WR) altsnap.rc altsnapr.o -Fpe-i386 31 | 32 | hooksr.o: hooks.rc 33 | $(WR) hooks.rc hooksr.o -Fpe-i386 34 | 35 | clean : 36 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 37 | -------------------------------------------------------------------------------- /MakefileX64: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | WR=windres 3 | 4 | WARNINGS=-Wall -Wformat-security -Wstrict-overflow -Wsign-compare -Wclobbered \ 5 | -Wempty-body -Wignored-qualifiers -Wuninitialized -Wtype-limits -Woverride-init \ 6 | -Wlogical-op -Wno-multichar -Wno-attributes -Wduplicated-cond -Wduplicated-branches \ 7 | -Wnull-dereference -Wno-unused-function -Wshadow -Wstack-usage=4096 -pedantic -Wc++-compat 8 | 9 | CFLAGS=-Os -fno-stack-check -fno-stack-protector -fno-ident -fomit-frame-pointer -fmerge-all-constants \ 10 | -mno-stack-arg-probe -momit-leaf-frame-pointer -m64 -march=x86-64 -mtune=generic \ 11 | -nostdlib -lmsvcrt -lkernel32 -luser32 -lgdi32 -lmsvcrt -lwinmm -s -fgcse-sm -fgcse-las -fno-plt \ 12 | -Wl,-dynamicbase,-nxcompat,--no-seh,--relax,--disable-runtime-pseudo-reloc,--enable-auto-import,--disable-stdcall-fixup \ 13 | -D__USE_MINGW_ANSI_STDIO=0 -Wp,-D_FORTIFY_SOURCE=2 -fshort-enums\ 14 | $(INCLUDE) $(WARNINGS) -fno-exceptions -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables 15 | 16 | default: AltSnap.exe hooks.dll 17 | 18 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 19 | $(CC) -o hooks.dll hooks.c hooksr.o $(CFLAGS) -mdll -eDllMain -Wl,--kill-at 20 | 21 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 22 | $(CC) -o AltSnap.exe altsnap.c altsnapr.o $(CFLAGS) -Wl,--tsaware,--disable-reloc-section -mwindows -lcomctl32 -ladvapi32 -lshell32 -eunfuckWinMain 23 | 24 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 25 | $(WR) altsnap.rc altsnapr.o 26 | 27 | hooksr.o: hooks.rc 28 | $(WR) hooks.rc hooksr.o 29 | 30 | clean : 31 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 32 | -------------------------------------------------------------------------------- /MakefileX64db: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | 3 | WARNINGS=-Wall -Wformat-security -Wstrict-overflow -Wsign-compare -Wclobbered \ 4 | -Wempty-body -Wignored-qualifiers -Wuninitialized -Wtype-limits -Woverride-init \ 5 | -Wlogical-op -Wno-multichar -Wno-attributes -Wduplicated-cond -Wduplicated-branches \ 6 | -Wnull-dereference -Wno-unused-function -Wshadow -Wstack-usage=4096 7 | 8 | ## DEBUG FLAGS 9 | CFLAGS= -nostdlib -Os -g -DLOG_STUFF=1 -m64 -march=x86-64 -mtune=generic \ 10 | -lmsvcrt -lkernel32 -luser32 -lgdi32 -fgcse-sm -fgcse-las -fno-plt \ 11 | -Wl,-dynamicbase,-nxcompat,--no-seh,--relax,--disable-runtime-pseudo-reloc,--enable-auto-import,--disable-stdcall-fixup \ 12 | -D__USE_MINGW_ANSI_STDIO=0 -fshort-enums\ 13 | $(INCLUDE) $(WARNINGS) -fno-exceptions -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables 14 | 15 | default: AltSnap.exe hooks.dll 16 | 17 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 18 | $(CC) -o hooks.dll hooks.c hooksr.o $(CFLAGS) -mdll -eDllMain -Wl,--kill-at 19 | 20 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 21 | $(CC) -o AltSnap.exe altsnap.c altsnapr.o $(CFLAGS) -Wl,--tsaware,--disable-reloc-section -lcomctl32 -ladvapi32 -lshell32 -eunfuckWinMain 22 | 23 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 24 | windres altsnap.rc altsnapr.o 25 | 26 | hooksr.o: hooks.rc 27 | windres hooks.rc hooksr.o 28 | 29 | clean : 30 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 31 | -------------------------------------------------------------------------------- /Makefiledb: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | 3 | WARNINGS=-Wall -Wformat-security -Wstrict-overflow -Wsign-compare -Wclobbered \ 4 | -Wempty-body -Wignored-qualifiers -Wuninitialized -Wtype-limits -Woverride-init \ 5 | -Wlogical-op -Wno-multichar -Wno-attributes -Wduplicated-cond -Wduplicated-branches \ 6 | -Wnull-dereference -Wno-unused-function -Wshadow -Wstack-usage=4096 7 | 8 | # -Wunused-parameter 9 | # -Wtraditional-conversion 10 | #-fira-region=one/mixed 11 | # -Wstack-usage=2048 12 | 13 | ## DEBUG FLAGS 14 | # -Wl,--print-memory-usage -fstack-usage -fcallgraph-info 15 | CFLAGS= -nostdlib -Og -g -ggdb -DLOG_STUFF=1 -m32 -march=i686 -mtune=generic \ 16 | -fno-omit-frame-pointer -lgcc -ftrapv -fbounds-check \ 17 | -lmsvcrt -lkernel32 -luser32 -lgdi32 \ 18 | -Wl,-dynamicbase,-nxcompat,--no-seh,--relax,--enable-auto-import,--disable-stdcall-fixup \ 19 | -D__USE_MINGW_ANSI_STDIO=0 -Wp,-D_FORTIFY_SOURCE=2 -fshort-enums\ 20 | $(INCLUDE) $(WARNINGS) -DDEBUG 21 | 22 | default: AltSnap.exe hooks.dll 23 | 24 | hooks.dll : hooks.c hooks.h hooksr.o unfuck.h nanolibc.h zones.c snap.c 25 | $(CC) -o hooks.dll hooks.c hooksr.o $(CFLAGS) -mdll -e_DllMain@12 -Wl,--kill-at 26 | 27 | #--disable-reloc-section, -mwindows 28 | AltSnap.exe : altsnapr.o altsnap.c hooks.h tray.c config.c languages.h languages.c unfuck.h nanolibc.h 29 | $(CC) -o AltSnap.exe altsnap.c altsnapr.o $(CFLAGS) -Wl,--tsaware -lcomctl32 -ladvapi32 -lshell32 -e_unfuckWinMain@0 30 | 31 | altsnapr.o : altsnap.rc window.rc resource.h AltSnap.exe.manifest media/find.cur media/find.ico media/icon.ico media/tray-disabled.ico media/tray-enabled.ico 32 | windres altsnap.rc altsnapr.o -Fpe-i386 33 | 34 | hooksr.o: hooks.rc 35 | windres hooks.rc hooksr.o -Fpe-i386 36 | 37 | clean : 38 | rm altsnapr.o AltSnap.exe hooksr.o hooks.dll 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English | [中文](./README_zh-CN.md) | [한국어](./README_ko-KR.md) 2 | # AltSnap 3 | Fork from Stefan Sundin's AltDrag. 4 | 5 | Check the Wiki: https://github.com/RamonUnch/AltSnap/wiki 6 | 7 | Original documentation: https://stefansundin.github.io/altdrag/doc/ 8 | 9 | Note that the documentation is not 100% accurate because it is a fork. 10 | Read the changelog for more details. 11 | 12 | It allows you to move and resize windows by using the Alt key and clicking wherever on the window instead of relying on very precise clicking. 13 | This behavior is very common on Linux distributions and is not actually hard to implement on Windows. 14 | 15 | This fork tries to keep a version up to date with minimal amount of bugs while keeping it feature-rich. 16 | 17 | It is oriented towards all Windows users from Windows NT 4 to Windows 11, even though it is mostly tested on Windows XP and Windows 10. 18 | 19 | Main differences: 20 | To simplify the code greatly the Hooks windows feature was removed, it allowed you have windows snapping while dragging them normally. It required however to inject a dll in every application and induced thus an obvious security risk. The amount of mess added to the code just for this feature was substantial and in addition forced to have both a 32bits and a 64bits version of the program running at the same time. 21 | 22 | This version injects nothing into other applications. This means you do not have to worry whether you have a 32 or a 64bit operating system. 23 | 24 | Another feature that was disabled is focus on typing, that was too much unusable for me to even start testing, so I removed it. 25 | 26 | Otherwise this has a much simpler source code, added a few extra options, such as transparent windows dragging, Maximize action, pause process options, more blacklists for finer control of AltSnap etc. 27 | 28 | Finally it fixed a ton of undesired behavior and bugs from the original AltDrag. 29 | 30 | WHAT'S NEW 31 | 32 | Many new features can be seen in the option dialog box, however some of them are only available through editing the AltSnap.ini file (middle click on tyhe tray icon for this). 33 | 34 | # VirusTotal false positive 35 | You will see with the latest builds that there are some alerts, usually from SecureAge APEX and sometimes from other vendors. Those are false positives, and I stopped contacting the APEX team for every release because it is a waste of time I would rather spend on improving the program. 36 | I already reduced the number of false positives significantly, simply by changing build flags and by switching to an older version of the NSIS installer system. This is an indication of the impertinence of some modern antivirus solutions. Chocolatey considers that up to five positives on VirusTotal is not even suspicious. 37 | 38 | # Build 39 | AltSnap builds with gcc, I use Mingw-w64 (for i686). 40 | Just install the latest version (I use TDM-gcc 10.3, MinGW64 based) and use: 41 | 42 | `> make` for i386 Win32 GCC build. 43 | 44 | `> make -fMakefiledb` for i386 GCC debug build. 45 | 46 | `> make -fMakefileX64` for x86_64 GCC build. 47 | 48 | `> make -fMakefileX64db` for x86_64 GCC debug build. 49 | 50 | `> make -fMakefileClang` for i386 build using LLVM Clang. 51 | 52 | `> make -fMakefileTCC` for i386 build using tcc, [Bellard's thiny c compiler](https://bellard.org/tcc/) 53 | 54 | You can also use mk.bat and mk64.bat files. 55 | For Clang, I use LLVM5.0.1 with the headers and libs from Mingw-w64. 56 | Be sure to adjust your include and lib directorries on the command line with `-IPath\to\mingw\include` and `-LPath\to\mingw\lib`. 57 | -------------------------------------------------------------------------------- /README_ko-KR.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | [中文](./README_zh-CN.md) | 한국어 2 | # AltSnap 3 | Stefan Sundin의 AltDrag에서 포크되었습니다. 4 | 5 | 위키를 확인하세요: https://github.com/RamonUnch/AltSnap/wiki 6 | 7 | 기존 문서: https://stefansundin.github.io/altdrag/doc/ 8 | 9 | 포크된 코드라서 문서가 100% 정확하지는 않습니다. 10 | 좀 더 자세한 사항이 궁금하시면 변경사항(changelog)을 확인바랍니다. 11 | 12 | AltSnap은 Alt 키를 누르고 윈도 창의 아무곳이나 클릭하여 창을 이동하고 크기를 조절할 수 있도록 하는 유틸리티입니다. 13 | 리눅스에서는 이러한 기능과 동작이 일반적으로 적용되어있고 실제로 윈도우에서도 적용하기 어렵지 않습니다. 14 | 15 | 이 포크는 풍부한 기능을 유지하면서도 최소한의 버그를 최소화하여, 최신 버전으로 유지하려고 노력하는데 목적이 있습니다. 16 | 17 | 이 포크는 주로 Windows XP와 Windows 10에서 테스트 되었습니다만 Windows NT 4에서 Windows 11까지의 모든 Windows에서 사용이 가능합니다. 18 | 19 | 주요 차이점: 20 | 코드를 최대한 단순화하기 위해 창을 후크(Hook)하는 방식을 제거하였습니다. 이러한 방식은 드래그를 하는동안 어떠한 창이든 스냅할 수 있도록 하는 장점이 있는 반면에, 모든 응용 프로그램에 dll을 삽입(DLL Injection)해야 했었으므로 명백히 보안상의 위험이 있었습니다. 단순히 이 기능을 위해 상당한 양의 코드가 추가되었으며 동시에 32비트 및 64비트 버전의 프로그램을 모두 실행해야 했기 때문에 코드의 복잡도를 크게 증가시켰습니다. 21 | 22 | 이 버전은 다른 어플리케이션에 아무것도 삽입(Injection)하지 않습니다. 따라서 32비트 운영체제를 사용하든 64비트 운영체제를 사용하든 걱정할 필요가 없습니다. 23 | 24 | 이외에 제거된 기능은 "타이핑시 포커스"로, 테스트를 시작하기도 전에 이미 사용할 수 없는 상태였으므로 제거 했습니다. 25 | 26 | 이러한 변화로 소스코드가 훨신 간결해졌고, 약간의 추가적인 옵션을 넣었습니다. 예를 들면 드래그 하는 동안 투명 윈도우를 투명하게 한다던가, 최대화 액션, 프로세스 일시 중지, AltSnap을 조금 더 세밀하게 제어할 수 있는 블랙리스트 등의 추가 옵션이 추가되었습니다. 27 | 28 | 마지막으로 기존의 AltDrag에서 발생했던 이상 동작과 버그를 잔뜩 수정했습니다. 29 | 30 | 새로운 기능 31 | 32 | 기본적으로 옵션 다이얼로그 창에서 새로운 기능을 만나보실 수 있지만, 일부 기능은 AltSnap.ini 파일을 직접 수정해야만 합니다. (트레이 아이콘을 가운데 클릭해 보세요) 33 | 34 | # VirusTotal 오탐 35 | 최신 빌드에서는 일반적으로 다른 공급업체의 SecureAge APEX와 마찬가지로 종종 경고가 표시되는 것을 볼 수 있습니다. 이러한 경고는 오탐이며 프로그램 개선에 시간을 낭비하는 것이기 때문에 매 릴리스마다 APEX 팀에 연락하는 것을 중단했습니다. 빌드 플래그를 변경하고 이전 버전의 NSIS 인스톨러 시스템으로 전환하는 것만으로 이미 오탐의 수를 많이 줄였습니다. 이것은 일부 최신 바이러스 백신 솔루션의 부족함을 나타냅니다. Chocolatey에서는 VirusTotal에서 5개정도의 양성 탐지는 전혀 의심운것이 아니라고 간주하고 있습니다. 36 | 37 | # 빌드 38 | AltSnap은 gcc로 빌드할 수 있습니다. 제 경우엔 i686용을 빌드할때 Mingw-w64를 사용합니다. 39 | 40 | 최신 버전을 설치하신 후 (저는 MinGW64 기반의 TDM-gcc 10.3를 사용중입니다): 41 | 42 | `> make` i386 Win32 GCC 빌드. 43 | 44 | `> make -fMakefiledb` i386 GCC 디버그 빌드. 45 | 46 | `> make -fMakefileX64` x86_64 GCC 빌드. 47 | 48 | `> make -fMakefileX64db` x86_64 GCC 디버그 빌드. 49 | 50 | `> make -fMakefileClang` LLVM Clang을 이용한 i386 빌드. 51 | 52 | `> make -fMakefileTCC` tcc(Bellard's thiny c compiler)[https://bellard.org/tcc/]를 이용한 i386 빌드 53 | 54 | `mk.bat` 와 `mk64.bat`파일을 사용하실 수도 있습니다. Clang의 경우 저는 LLVM5.0.1과 Mingw-w64의 header 및 lib를 사용합니다. 커맨드라인을 변경해서 `-IPath\to\mingw\include` and `-LPath\to\mingw\lib`를 추가하는 것을 잊지마세요. 55 | -------------------------------------------------------------------------------- /README_zh-CN.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | 中文 | [한국어](./README_ko-KR.md) 2 | # AltSnap 3 | 由Stefan Sundin的AltDrag制作的一个的分支。 4 | 5 | 查看Wiki:https://github.com/RamonUnch/AltSnap/wiki 6 | 7 | 原始文档:https://stefansundin.github.io/altdrag/doc/ 8 | 9 | 请注意,因为这是一个分支,所以原始的文档并不是100%准确的。请阅读更新日志来了解更多详细信息。 10 | 11 | 它允许您通过按住Alt键并单击窗口上的任何位置来移动和调整窗口大小,并不需要任何精确的点击。 12 | 这种方式在Linux发行版上很常见,其实也并不难在Windows上实现。 13 | 14 | 这个分支的目标是在保持功能丰富的情况下同时让最新版本的错误最少。 15 | 16 | 尽管它主要在Windows XP和Windows 10上进行测试,但它理论上应该可以在Windows NT 4.0到Windows 11之间的任意Windows版本上使用, 17 | 18 | 与原版主要的不同: 19 | 为了大大简化代码,Hooks窗口的功能被删除,它允许在正常拖动窗口的同时捕捉窗口。然而,它需要在每个应用程序中注入一个dll,从而导致了明显的安全风险。仅仅为了这个特性而添加到代码中的混乱程度是巨大的,此外还被迫同时运行32位和64位版本的程序。 20 | 21 | 此版本不向其他应用程序注入任何内容。这意味着您不必担心您使用的是32位还是64位操作系统。 22 | 23 | 另一个被禁用的功能是“专注于打字”,我甚至无法开始测试这个功能,所以我删除了它。 24 | 25 | 除此之外,它还有一个简单得多的源代码,添加了一些额外的选项,如透明窗口拖动、最大化操作、暂停进程选项、更多用于更精细地控制AltSnap的黑名单等。 26 | 27 | 最后,它修复了原始AltDrag中的大量不良行为和错误。 28 | 29 | 新东西: 30 | 31 | 在选项对话框中可以看到许多新功能,但其中一些功能只能通过编辑AltSnap.ini文件才能使用(用鼠标中键单击该文件的托盘图标)。 32 | 33 | # 构建 34 | AltSnap使用gcc构建,对于i686来说,我使用Mingw-w64。 35 | 只需要安装最新版本(我使用基于MinGW64的TDM-gcc 10.3)并使用: 36 | 37 | `> make` 用于i386 Win32的构建 38 | 39 | `> make -fMakefileX64` 用于x86_64构建。 40 | 41 | `> make -fMakefileX64db` 用于构建x86_64的调试版本。 42 | 43 | 您也可以使用mk.bat和mk64.bat文件。 44 | -------------------------------------------------------------------------------- /Themes/erasmion/TRAY_OFF.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Themes/erasmion/TRAY_OFF.ico -------------------------------------------------------------------------------- /Themes/erasmion/TRAY_ON.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Themes/erasmion/TRAY_ON.ico -------------------------------------------------------------------------------- /Themes/erasmion/TRAY_SUS.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/Themes/erasmion/TRAY_SUS.ico -------------------------------------------------------------------------------- /altsnap.c: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * Copyright (C) 2015 Stefan Sundin * 3 | * This program is free software: you can redistribute it and/or modify * 4 | * it under the terms of the GNU General Public License as published by * 5 | * the Free Software Foundation, either version 3 or later. * 6 | * Modified By Raymond Gillibert in 2021 * 7 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 8 | 9 | #include "hooks.h" 10 | 11 | // Messages 12 | #define SWM_TOGGLE (WM_APP+1) 13 | #define SWM_HIDE (WM_APP+2) 14 | #define SWM_ELEVATE (WM_APP+3) 15 | #define SWM_CONFIG (WM_APP+4) 16 | #define SWM_ABOUT (WM_APP+5) 17 | #define SWM_EXIT (WM_APP+6) 18 | #define SWM_FIND (WM_APP+7) 19 | #define SWM_HELP (WM_APP+8) 20 | #define SWM_SAVEZONES (WM_APP+9) 21 | #define SWM_TESTWIN (WM_APP+10) 22 | #define SWM_OPENINIFILE (WM_APP+11) 23 | #define SWM_SNAPLAYOUT (WM_APP+12) 24 | #define SWM_SNAPLAYOUTEND (WM_APP+22) 25 | #define SWM_EDITLAYOUT (WM_APP+30) 26 | #define SWM_CLOSEZONES (WM_APP+31) 27 | 28 | // Boring stuff 29 | static HINSTANCE g_hinst = NULL; 30 | static HWND g_hwnd = NULL; 31 | static UINT WM_TASKBARCREATED = 0; 32 | static TCHAR inipath[MAX_PATH]; 33 | 34 | static WNDPROC G_HotKeyProc = NULL; 35 | 36 | // Cool stuff 37 | HINSTANCE hinstDLL = NULL; 38 | HHOOK keyhook = NULL; 39 | static DWORD ACMenuItems=-1; 40 | static char elevated = 0; 41 | static char ScrollLockState = 0; 42 | static char SnapGap = 0; 43 | static BYTE WinVer = 0; 44 | 45 | #define WIN2K (WinVer >= 5) 46 | #define VISTA (WinVer >= 6) 47 | #define WIN10 (WinVer >= 10) 48 | 49 | #define ENABLED() (!!keyhook) 50 | #define GetWindowRectL(hwnd, rect) GetWindowRectLL(hwnd, rect, SnapGap) 51 | static void UpdateSettings(); 52 | 53 | // Include stuff 54 | #include "languages.c" 55 | #include "tray.c" 56 | #include "config.c" 57 | 58 | static HINSTANCE LoadHooksDLL() 59 | { 60 | // Load library 61 | TCHAR path[MAX_PATH]; 62 | DWORD ret = GetModuleFileName(NULL, path, ARR_SZ(path)); 63 | if(!ret || ret == ARR_SZ(path)) 64 | return NULL; 65 | PathRemoveFileSpecL(path); 66 | lstrcat_s(path, ARR_SZ(path), TEXT("\\hooks.dll")); 67 | return LoadLibrary(path); 68 | } 69 | static void FreeHooksDLL() 70 | { 71 | if (hinstDLL) { 72 | FreeLibrary(hinstDLL); 73 | hinstDLL = NULL; 74 | } 75 | } 76 | ///////////////////////////////////////////////////////////////////////////// 77 | int HookSystem() 78 | { 79 | if (keyhook) return 1; // System already hooked 80 | LOG("Going to Hook the system..."); 81 | 82 | if (!hinstDLL) { 83 | hinstDLL = LoadHooksDLL(); 84 | if (!hinstDLL) { 85 | LOG("Could not load HOOKS.DLL!!!"); 86 | return 1; 87 | } 88 | } 89 | WNDPROC (WINAPI *Load)(HWND, const TCHAR *) = (WNDPROC (WINAPI *)(HWND, const TCHAR*))GetProcAddress(hinstDLL, LOAD_PROC); 90 | if(Load) { 91 | G_HotKeyProc = Load(g_hwnd, inipath); 92 | } 93 | 94 | LOG("HOOKS.DLL Loaded"); 95 | 96 | // Load keyboard hook 97 | HOOKPROC procaddr; 98 | if (!keyhook) { 99 | // Get address to keyboard hook (beware name mangling) 100 | procaddr = (HOOKPROC) GetProcAddress(hinstDLL, LOW_LEVEL_KB_PROC); 101 | if (procaddr == NULL) { 102 | LOG("Could not find "LOW_LEVEL_KB_PROC" entry point in HOOKS.DLL"); 103 | return 1; 104 | } 105 | // Set up the keyboard hook 106 | keyhook = SetWindowsHookEx(WH_KEYBOARD_LL, procaddr, hinstDLL, 0); 107 | if (keyhook == NULL) { 108 | LOG("Keyboard HOOK could not be set"); 109 | return 1; 110 | } 111 | } 112 | LOG("Keyboard HOOK set"); 113 | 114 | // Reading some config options... 115 | UseZones = GetPrivateProfileInt(TEXT("Zones"), TEXT("UseZones"), 0, inipath); 116 | SnapGap = CLAMP(-128, GetPrivateProfileInt(TEXT("Advanced"), TEXT("SnapGap"), 0, inipath), 127); 117 | ACMenuItems = GetPrivateProfileInt(TEXT("Advanced"), TEXT("ACMenuItems"), -1, inipath); 118 | UpdateTray(); 119 | return 0; 120 | } 121 | ///////////////////////////////////////////////////////////////////////////// 122 | int showerror = 1; 123 | int UnhookSystem() 124 | { 125 | LOG("Going to UnHook the system..."); 126 | if (!keyhook) { // System not hooked 127 | return 1; 128 | } else if (!UnhookWindowsHookEx(keyhook) && showerror) { 129 | MessageBox(NULL, l10n->MiscUnhookError, TEXT(APP_NAMEA), 130 | MB_ICONINFORMATION|MB_OK|MB_TOPMOST|MB_SETFOREGROUND); 131 | } 132 | keyhook = NULL; 133 | 134 | // Tell dll file that we are unloading 135 | void (WINAPI *Unload)() = (void (WINAPI *)()) GetProcAddress(hinstDLL, UNLOAD_PROC); 136 | if (Unload) { 137 | Unload(); 138 | // Zero out the message hwnd from DLL. 139 | G_HotKeyProc = NULL; 140 | } 141 | FreeHooksDLL(); 142 | 143 | // Success 144 | UpdateTray(); 145 | return 0; 146 | } 147 | ///////////////////////////////////////////////////////////////////////////// 148 | void ToggleState() 149 | { 150 | if (ENABLED()) { 151 | UnhookSystem(); 152 | } else { 153 | // SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); 154 | HookSystem(); 155 | } 156 | } 157 | ///////////////////////////////////////////////////////////////////////////// 158 | static void UpdateSettings() 159 | { 160 | //PostMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); 161 | if (ENABLED()) { 162 | UnhookSystem(); 163 | HookSystem(); 164 | } 165 | } 166 | ///////////////////////////////////////////////////////////////////////////// 167 | // 168 | void ShowSClickMenu(HWND hwnd, LPARAM param) 169 | { 170 | POINT pt; 171 | if (param&LP_CURSORPOS) { 172 | // Use cursor position to place menu. 173 | GetCursorPos(&pt); 174 | } else { 175 | // Use the pointed window 176 | RECT rc; 177 | HWND clickhwnd = (HWND)SendMessage(hwnd, WM_GETCLICKHWND, 0, 0); 178 | GetWindowRect(clickhwnd, &rc); 179 | pt.x = rc.left + GetSystemMetricsForWin(SM_CXSIZEFRAME, clickhwnd); 180 | pt.y = rc.top + GetSystemMetricsForWin(SM_CYSIZEFRAME, clickhwnd) 181 | + GetSystemMetricsForWin(SM_CYCAPTION, clickhwnd); 182 | } 183 | HMENU menu = CreatePopupMenu(); 184 | UCHAR show_oriclick = (param&LP_NOALTACTION)? AC_ORICLICK: 0xFF; 185 | 186 | #define CHK(LP_FLAG) MF_STRING|((param&LP_FLAG)?MF_CHECKED:MF_UNCHECKED) 187 | 188 | const struct { 189 | UCHAR action; WORD mf; TCHAR *str; 190 | } mnlst[] = { 191 | /* hide, action, MF_FLAG/CHECKED, menu string */ 192 | { AC_ALWAYSONTOP, CHK(LP_TOPMOST), l10n->InputActionAlwaysOnTop }, 193 | { AC_BORDERLESS, CHK(LP_BORDERLESS), l10n->InputActionBorderless }, 194 | { AC_CENTER, MF_STRING, l10n->InputActionCenter}, 195 | { AC_ROLL, CHK(LP_ROLLED), l10n->InputActionRoll}, 196 | { AC_LOWER, MF_STRING, l10n->InputActionLower}, 197 | { AC_MAXHV, MF_STRING, l10n->InputActionMaximizeHV}, 198 | { AC_MINALL, MF_STRING, l10n->InputActionMinAllOther}, 199 | { AC_SIDESNAP, MF_STRING, l10n->InputActionSideSnap}, 200 | { 0, MF_SEPARATOR, NULL }, /* ------------------------ */ 201 | { AC_MAXIMIZE, CHK(LP_MAXIMIZED), l10n->InputActionMaximize}, 202 | { AC_MINIMIZE, MF_STRING, l10n->InputActionMinimize}, 203 | { AC_CLOSE, MF_STRING, l10n->InputActionClose}, 204 | { 0, MF_SEPARATOR, NULL }, /* ------------------------ */ 205 | { AC_KILL, MF_STRING, l10n->InputActionKill}, 206 | { 0, MF_SEPARATOR, NULL }, /* ------------------------ */ 207 | { AC_MOVEONOFF, CHK(LP_MOVEONOFF), l10n->InputActionMoveOnOff}, 208 | { 0, MF_SEPARATOR, NULL }, /* ------------------------ */ 209 | { show_oriclick, MF_STRING, l10n->InputActionOriClick}, 210 | { AC_NONE, MF_STRING, l10n->InputActionNothing}, 211 | }; 212 | #undef CHK 213 | #undef K 214 | unsigned i; 215 | for (i=0; i < ARR_SZ(mnlst); i++) { 216 | if ( (ACMenuItems>>i)&1 && mnlst[i].action != 0xFF) // Put the action in the HIWORD of wParam 217 | AppendMenu(menu, mnlst[i].mf, mnlst[i].action<<16, mnlst[i].str); 218 | } 219 | TrackPopupMenu(menu, GetSystemMetrics(SM_MENUDROPALIGNMENT), pt.x, pt.y, 0, hwnd, NULL); 220 | DestroyMenu(menu); 221 | PostMessage(hwnd, WM_CLOSE, 0, 0); 222 | } 223 | // To get the caret position in screen coordinate. 224 | // We first try to get the carret rect 225 | #include 226 | //static const GUID my_IID_IAccessible = { 0x618736e0, 0x3c3d, 0x11cf, {0x81, 0x0c, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} }; 227 | static void GetKaretPos(POINT *pt) 228 | { 229 | GUITHREADINFO gui; 230 | gui.cbSize = sizeof(GUITHREADINFO); 231 | gui.hwndCaret = NULL; 232 | if (GetGUIThreadInfo(0, &gui)) { 233 | pt->x = (gui.rcCaret.right + gui.rcCaret.left)>>1; 234 | pt->y = (gui.rcCaret.top + gui.rcCaret.bottom)>>1; 235 | if (gui.hwndCaret) { 236 | ClientToScreen(gui.hwndCaret, pt); 237 | return; 238 | // } else if (gui.hwndFocus) { 239 | // IAccessible *pacc = NULL; 240 | // if ( S_OK==AccessibleObjectFromWindow(gui.hwndFocus, OBJID_CARET, &my_IID_IAccessible, (void**)&pacc) ) { 241 | // // MessageBox(NULL, NULL, NULL, 0); 242 | // LONG x=0, y=0, w=0, h=0; 243 | // VARIANT varCaret; 244 | // varCaret.vt = VT_I4; 245 | // varCaret.lVal = CHILDID_SELF; 246 | // if (S_OK == pacc->lpVtbl->accLocation(pacc, &x, &y, &w, &h, varCaret)) { 247 | // pt->x = x+w/2; 248 | // pt->y = y+h/2; 249 | // pacc->lpVtbl->Release(pacc); 250 | // return; 251 | // } 252 | // } 253 | } 254 | } 255 | 256 | GetCursorPos(pt); 257 | } 258 | static void ShowUnikeyMenu(HWND hwnd, LPARAM param) 259 | { 260 | UCHAR vkey = LOBYTE(LOWORD(param)); 261 | UCHAR capital = HIBYTE(LOWORD(param)); 262 | TCHAR *const* const ukmap = &l10n->a; //EXTRAKEYS_MAP; 263 | HMENU menu = CreatePopupMenu(); 264 | if (!menu) return; 265 | 266 | const TCHAR *kl, *keylist = ukmap[(vkey - 0x41)*2]; 267 | UCHAR i; 268 | for (kl = keylist, i='A'; *kl; kl++) { 269 | if(*kl==L'%') { 270 | AppendMenu(menu, MF_SEPARATOR, 0, NULL); 271 | continue; 272 | } 273 | TCHAR unichar = *kl; 274 | if (kl[1] == L'|') { 275 | kl+=2; 276 | if (capital) unichar = *kl; 277 | } else if (capital) { 278 | unichar = (TCHAR)(LONG_PTR)CharUpper((TCHAR *)(LONG_PTR)*kl); 279 | } 280 | if (i > 'Z') i = '1'; 281 | TCHAR mwstr[6]; 282 | mwstr[0] = L'&'; 283 | mwstr[1] = i++; 284 | mwstr[2] = L'\t'; 285 | DWORD utf16c; 286 | if (IS_SURROGATE_PAIR(unichar, kl[1])) { 287 | utf16c =*(DWORD*)kl; 288 | mwstr[3] = LOWORD(utf16c); 289 | mwstr[4] = HIWORD(utf16c); 290 | mwstr[5] = L'\0'; 291 | kl++; // skip high surrogate 292 | } else { 293 | mwstr[3] = utf16c = unichar; 294 | mwstr[4] = L'\0'; 295 | } 296 | if (!AppendMenu(menu, MF_STRING, utf16c, mwstr)) 297 | break; 298 | } 299 | if (kl > keylist) { 300 | POINT pt; 301 | GetKaretPos(&pt); 302 | TrackPopupMenu(menu, GetSystemMetrics(SM_MENUDROPALIGNMENT), pt.x, pt.y, 0, hwnd, NULL); 303 | } 304 | DestroyMenu(menu); 305 | } 306 | ///////////////////////////////////////////////////////////////////////////// 307 | LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 308 | { 309 | if (!msg) { 310 | // In case some messages are not registered. 311 | } else if(wParam && msg == WM_ERASEBKGND) { 312 | return 1; 313 | } else if (wParam && (msg == WM_PAINT || msg == WM_NCPAINT)) { 314 | return 0; 315 | } else if (msg == WM_TRAY) { 316 | if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) { 317 | ToggleState(); 318 | if (lParam == WM_LBUTTONDBLCLK) { 319 | SendMessage(hwnd, WM_OPENCONFIG, 0, 0); 320 | } 321 | } else if (lParam == WM_MBUTTONDOWN) { 322 | SendMessage(hwnd, WM_COMMAND, SWM_OPENINIFILE, 0); 323 | } else if (lParam == WM_RBUTTONUP) { 324 | ShowContextMenu(hwnd); 325 | } 326 | } else if (msg == WM_SCLICK && wParam) { 327 | ShowSClickMenu((HWND)wParam, lParam); 328 | } else if (msg == WM_UNIKEYMENU) { 329 | ShowUnikeyMenu((HWND)wParam, lParam); 330 | } else if (msg == WM_UPDATESETTINGS) { 331 | // Reload hooks 332 | UpdateSettings(); 333 | } else if (msg == WM_ADDTRAY) { 334 | hide = 0; 335 | UpdateTray(); 336 | } else if (msg == WM_UPDATETRAY) { 337 | UpdateTray(); 338 | } else if (msg == WM_HIDETRAY) { 339 | hide = 1; 340 | RemoveTray(); 341 | } else if (msg == WM_OPENCONFIG && (lParam || !hide)) { 342 | OpenConfig(wParam); 343 | } else if (msg == WM_CLOSECONFIG) { 344 | CloseConfig(); 345 | } else if (msg == WM_TASKBARCREATED) { 346 | // Try to add the tray icon because explorer started. 347 | tray_added = 0; 348 | UpdateTray(); 349 | } else if (msg == WM_COMMAND) { 350 | int wmId = LOWORD(wParam); // int wmEvent = HIWORD(wParam); 351 | if (wmId == SWM_TOGGLE) { 352 | ToggleState(); 353 | } else if (wmId == SWM_HIDE) { 354 | hide = 1; 355 | RemoveTray(); 356 | } else if (wmId == SWM_ELEVATE) { 357 | ElevateNow(0); 358 | } else if (wmId == SWM_CONFIG) { 359 | SendMessage(hwnd, WM_OPENCONFIG, 0, 0); 360 | } else if (wmId == SWM_ABOUT) { 361 | SendMessage(hwnd, WM_OPENCONFIG, 5, 0); 362 | } else if (wmId == SWM_OPENINIFILE) { 363 | ShellExecute(NULL, TEXT("open"), inipath, NULL, NULL, SW_SHOWNORMAL); 364 | } else if (wmId == SWM_EXIT) { 365 | DestroyWindow(hwnd); 366 | } else if (wmId == SWM_SAVEZONES) { 367 | TCHAR txt[256]; 368 | lstrcpy_s(txt, ARR_SZ(txt), l10n->MiscZoneConfirmation); 369 | lstrcat_s(txt, ARR_SZ(txt), TEXT("\n\n")); 370 | catFullLayoutName(txt, ARR_SZ(txt), LayoutNumber); 371 | int ret = MessageBox(NULL, txt, TEXT(APP_NAMEA), MB_OKCANCEL); 372 | if (ret == IDOK) { 373 | UnhookSystem(); 374 | SaveCurrentLayout(); 375 | WriteCurrentLayoutNumber(); 376 | HookSystem(); 377 | } 378 | } else if (wmId == SWM_CLOSEZONES) { 379 | CloseAllTestWindows(); 380 | } else if (wmId == SWM_TESTWIN) { 381 | NewTestWindow(); 382 | } else if (SWM_SNAPLAYOUT <= wmId && wmId <= SWM_SNAPLAYOUTEND) { 383 | // Inform hooks.dll that the snap layout changed 384 | LayoutNumber = wmId-SWM_SNAPLAYOUT; 385 | if(G_HotKeyProc) 386 | G_HotKeyProc(hwnd, WM_SETLAYOUTNUM, LayoutNumber, 0); 387 | // Save new value in the .ini file 388 | WriteCurrentLayoutNumber(); 389 | } else if (wmId == SWM_EDITLAYOUT) { 390 | if (G_HotKeyProc) { 391 | unsigned len = G_HotKeyProc(hwnd, WM_GETZONESLEN, LayoutNumber, 0); 392 | if (!len) { 393 | // Empty layout, Let's open a new Test Window 394 | return !NewTestWindow(); 395 | } 396 | RECT *zones = (RECT*)malloc(len * sizeof(RECT)); 397 | if(!zones) return 0; 398 | 399 | G_HotKeyProc(hwnd, WM_GETZONES, LayoutNumber, (LPARAM)zones); 400 | // Open them from bottom to top to ensure 401 | // the windows are in the correct order. 402 | while (len--) { 403 | const RECT *rc = &zones[len]; 404 | NewTestWindowAt(rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top); 405 | } 406 | free(zones); 407 | } 408 | } 409 | } else if (msg == WM_QUERYENDSESSION) { 410 | showerror = 0; 411 | UnhookSystem(); 412 | } else if (msg == WM_DESTROY) { 413 | UnhookSystem(); 414 | RemoveTray(); 415 | PostQuitMessage(0); 416 | } else if (msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { 417 | // Hide cursorwnd if clicked on, this might happen if 418 | // it wasn't hidden by hooks.c for some reason 419 | ShowWindow(hwnd, SW_HIDE); 420 | return 0; 421 | } else if (msg == WM_DISPLAYCHANGE || (msg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA)) { 422 | LOG("WM_DISPLAYCHANGE %d:%d, %dbpp in WindowProc", LOWORD(lParam), HIWORD(lParam), wParam ); 423 | if (G_HotKeyProc) { 424 | int bestlayout = G_HotKeyProc(hwnd, WM_GETBESTLAYOUT, 0, 0); 425 | if( bestlayout != LayoutNumber 426 | && 0 <= bestlayout && bestlayout < MaxLayouts ) { 427 | LayoutNumber = bestlayout; 428 | G_HotKeyProc(hwnd, WM_SETLAYOUTNUM, LayoutNumber, 0); 429 | } 430 | } 431 | } else if (msg == WM_HOTKEY) { 432 | if (G_HotKeyProc) 433 | return G_HotKeyProc(hwnd, msg, wParam, lParam); 434 | } 435 | return DefWindowProc(hwnd, msg, wParam, lParam); 436 | } 437 | ///////////////////////////////////////////////////////////////////////////// 438 | int WINAPI tWinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, TCHAR *params, int iCmdShow) 439 | { 440 | g_hinst = hInst; 441 | 442 | // Get ini path 443 | LOG("\n\nALTSNAP STARTED"); 444 | GetModuleFileName(NULL, inipath, ARR_SZ(inipath)); 445 | inipath[MAX_PATH-1] = '\0'; 446 | size_t inipath_len = lstrlen(inipath)-3; 447 | lstrcpy_s(&inipath[inipath_len], 4, TEXT("ini")); 448 | if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(inipath) 449 | && GetEnvironmentVariable(TEXT("APPDATA"), NULL, 0)) { 450 | // .ini file is not in current directorry, and APPDATA exists 451 | // we should look for %APPDATA%\AltSnap\AltSnap.ini 452 | TCHAR userini[MAX_PATH]; 453 | GetEnvironmentVariable(TEXT("APPDATA"), userini, ARR_SZ(userini)); 454 | lstrcat_s(userini, ARR_SZ(userini), TEXT("\\AltSnap")); 455 | if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(userini)) { 456 | CreateDirectory(userini, NULL); 457 | LOG("CreateDirectory(%S)", userini); 458 | } 459 | // Full user ini name. 460 | //lstrcat_s(userini, ARR_SZ(userini), TEXT("\\AltSnap.ini")); 461 | TCHAR *inifilename = inipath + inipath_len-3; 462 | while (inifilename >= inipath && *inifilename != '\\') inifilename--; 463 | lstrcat_s(userini, ARR_SZ(userini), inifilename); 464 | if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(userini)) { 465 | // Copy AltSnap.dni (Default ini file) if no ini present 466 | lstrcpy_s(&inipath[lstrlen(inipath)-3], 4, TEXT("dni")); 467 | CopyFile(inipath, userini, FALSE); // AltSnap.dni -> AltSnap.ini 468 | LOG("CopyFile(%S -> %S)", inipath, userini); 469 | } 470 | 471 | lstrcpy_s(inipath, ARR_SZ(inipath), userini); 472 | } 473 | LOG("ini file: %S", inipath); 474 | 475 | // Read parameters on command line 476 | int help = !!lstrstr(params, TEXT("-help")) 477 | || !!lstrstr(params, TEXT("/?")) 478 | || !!lstrstr(params, TEXT("-?")); 479 | if (help) { 480 | static const TCHAR *txthelp = 481 | TEXT("AltSnap command line options:\n\n") 482 | TEXT("--help\tShow this help!\n") 483 | TEXT("-h\tHide the tray icon\n") 484 | TEXT("-q\tQuiet mode\n") 485 | TEXT("-m\tMultiple instances allowed\n") 486 | TEXT("-c\tOpen Config dialog\n") 487 | TEXT("-e\tElevate AltSnap\n") 488 | TEXT("-r\tRelaod AltSnap settings\n") 489 | TEXT("-lX\tSelect Snap Layout number X\n") 490 | TEXT("-afX\tExecute action X for the foreground window\n") 491 | TEXT("-apX\tExecute action X for the pointed window\n"); 492 | 493 | MessageBox(NULL, txthelp, TEXT(APP_NAMEA)TEXT(" Usage"), MB_OK|MB_ICONINFORMATION); 494 | return 0; 495 | } 496 | 497 | hide = !!lstrstr(params, TEXT("-h")); 498 | int quiet = !!lstrstr(params, TEXT("-q")); 499 | int elevate = !!lstrstr(params, TEXT("-e")); 500 | int multi = !!lstrstr(params, TEXT("-m")); 501 | int config = !!lstrstr(params, TEXT("-c")); 502 | int rlini = !!lstrstr(params, TEXT("-r")); 503 | 504 | // Check if elevated if in >= WinVer 505 | WinVer = LOBYTE(LOWORD(GetVersion())); 506 | LOG("Running with Windows version %lX", GetVersion()); 507 | #ifndef NO_VISTA 508 | if (WinVer >= 6) { // Vista + 509 | HANDLE token=NULL; 510 | TOKEN_ELEVATION elevation={0}; 511 | DWORD len=0; 512 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) 513 | && GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &len)) { 514 | elevated = elevation.TokenIsElevated; 515 | CloseHandle(token); 516 | } 517 | LOG("Process started %s elevated", elevated? "already": "non"); 518 | } 519 | #endif // NO_VISTA 520 | LOG("Command line parameters read, hide=%d, quiet=%d, elevate=%d, multi=%d, config=%d" 521 | , hide, quiet, elevate, multi, config); 522 | 523 | // Look for previous instance 524 | if (!multi && !GetPrivateProfileInt(TEXT("Advanced"), TEXT("MultipleInstances"), 0, inipath)){ 525 | if (quiet) return 0; 526 | 527 | HWND previnst = FindWindow(TEXT(APP_NAMEA), TEXT("")); 528 | if (previnst) { 529 | // Ask old HotKey window to perform an action. 530 | const TCHAR *actionstr = lstrstr(params, TEXT("-a")); 531 | if (actionstr && actionstr[2] && actionstr[3] && actionstr[4]) { 532 | enum action action = MapActionW(&actionstr[3]); 533 | PostMessage(previnst, WM_HOTKEY, (actionstr[2] == 'p')*0x1000+action, 0); 534 | return 0; 535 | } 536 | // Change layout if asked... 537 | #define isUDigit(x) ( TEXT('0') <= (x) && (x) <= TEXT('9') ) 538 | const TCHAR *layout = lstrstr(params, TEXT("-l")); 539 | if (layout && isUDigit(layout[2])) { 540 | TCHAR numstr[3] = { layout[2], layout[3], TEXT('\0') }; 541 | if (!isUDigit(numstr[1])) 542 | numstr[1] = TEXT('\0'); 543 | //MessageBox(NULL, NULL, NULL, 0); 544 | int layoutnumber = CLAMP(0, strtoi(numstr)-1, 9); 545 | PostMessage(previnst, WM_COMMAND, SWM_SNAPLAYOUT+layoutnumber, 0); 546 | return 0; 547 | } 548 | // Update old instance if no action to be made. 549 | LOG("Previous instance found and no -multi mode"); 550 | if(hide) PostMessage(previnst, WM_CLOSECONFIG, 0, 0); 551 | if(config) PostMessage(previnst, WM_OPENCONFIG, 0, 0); 552 | if(rlini) PostMessage(previnst, WM_UPDATESETTINGS, 0, 0); 553 | PostMessage(previnst, hide? WM_HIDETRAY : WM_ADDTRAY, 0, 0); 554 | LOG("Updated old instance and NORMAL EXIT"); 555 | return 0; 556 | } 557 | LOG("No previous instance found"); 558 | } 559 | 560 | // Check AlwaysElevate (Vista+ only) 561 | if (WinVer >= 6 && !elevated) { 562 | if(!elevate) elevate = GetPrivateProfileInt(TEXT("Advanced"), TEXT("AlwaysElevate"), 0, inipath); 563 | 564 | // Handle request to elevate to administrator privileges 565 | if (elevate) { 566 | LOG("Elevation requested"); 567 | TCHAR path[MAX_PATH]; 568 | GetModuleFileName(NULL, path, ARR_SZ(path)); 569 | HINSTANCE ret = ShellExecute(NULL, TEXT("runas"), path, (hide? TEXT("-h"): NULL), NULL, SW_SHOWNORMAL); 570 | if ((DorQWORD)ret > 32) { 571 | LOG("Elevation Faild => Not cool NORMAL EXIT"); 572 | return 0; 573 | } 574 | LOG("Elevation sucess"); 575 | } else { 576 | LOG("No Elevation requested"); 577 | } 578 | } 579 | // Language 580 | UpdateLanguage(); LOG("Language updated"); 581 | 582 | // Create window 583 | WNDCLASSEX wnd = 584 | { sizeof(WNDCLASSEX), 0 585 | , WindowProc, 0, 0, hInst, NULL, NULL 586 | , NULL, NULL, TEXT(APP_NAMEA), NULL }; 587 | RegisterClassEx(&wnd); 588 | g_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST| WS_EX_TRANSPARENT 589 | , wnd.lpszClassName , NULL , WS_POPUP 590 | , 0, 0, 0, 0, NULL, NULL, hInst, NULL); 591 | LOG("Create main APP Window: %s", g_hwnd? "Sucess": "Failed"); 592 | if (elevated) { 593 | // AltSnap was started elevated! 594 | // Allow some messages to be sent from non-elevated instance 595 | // so that user can do AltSnap.exe -c/r/h/l 596 | UINT i; 597 | for (i = WM_UPDATETRAY; i <= WM_HIDETRAY; i++) 598 | ChangeWindowMessageFilterExL(g_hwnd, i, /*MSGFLT_ALLOW*/1, NULL); 599 | } 600 | // Tray icon 601 | 602 | InitTray(); 603 | UpdateTray(); 604 | 605 | // Hook system 606 | HookSystem(); 607 | 608 | // Add tray if hook failed, even though -hide was supplied 609 | if (hide && !keyhook) { 610 | hide = 0; 611 | UpdateTray(); 612 | } 613 | // Open config if -config was supplied 614 | if (config) { 615 | PostMessage(g_hwnd, WM_OPENCONFIG, 0, 0); 616 | } 617 | // Message loop 618 | LOG("Starting "APP_NAMEA" message loop..."); 619 | BOOL ret; 620 | MSG msg; 621 | while ((ret = GetMessage( &msg, NULL, 0, 0 )) != 0) { 622 | if (ret == -1) { 623 | break; 624 | } else { 625 | TranslateMessage(&msg); 626 | DispatchMessage(&msg); 627 | } 628 | } 629 | 630 | UnhookSystem(); 631 | FreeHooksDLL(); 632 | DestroyWindow(g_hwnd); 633 | LOG("GOOD NORMAL EXIT"); 634 | return msg.wParam; 635 | } 636 | static pure const TCHAR *ParamsFromCmdline(const TCHAR *cmdl) 637 | { 638 | /* in case it starts with " we need to go to the next " */ 639 | if (cmdl[0] == TEXT('"')) { 640 | do { 641 | cmdl++; 642 | } while(*cmdl && *cmdl != TEXT('"')); 643 | } else { 644 | while(*cmdl && *cmdl != TEXT(' ') && *cmdl != TEXT('\t')) { 645 | cmdl++; 646 | } 647 | } 648 | cmdl += !!*cmdl; // Skip the " or the ' ' 649 | while(*cmdl == TEXT(' ') || *cmdl == TEXT('\t')) cmdl++; 650 | return cmdl; 651 | } 652 | 653 | ///////////////////////////////////////////////////////////////////////////// 654 | // Use -nostdlib and -e_unfuckMain@0 to use this main, -eunfuckMain for x64. 655 | #ifdef _MSC_VER 656 | #pragma comment(linker, "/entry:\"unfuckWinMain\"") 657 | #endif 658 | void noreturn WINAPI unfuckWinMain(void) 659 | { 660 | HINSTANCE hInst; 661 | HINSTANCE hPrevInstance = NULL; 662 | const TCHAR *szCmdLine; 663 | int iCmdShow = 0; 664 | 665 | hInst = GetModuleHandle(NULL); 666 | szCmdLine = ParamsFromCmdline(GetCommandLine()); 667 | 668 | ExitProcess(tWinMain(hInst, hPrevInstance, (TCHAR *)szCmdLine, iCmdShow)); 669 | } 670 | -------------------------------------------------------------------------------- /altsnap.nsi: -------------------------------------------------------------------------------- 1 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 2 | # define the name of the installer 3 | 4 | !define APP_NAME "AltSnap" 5 | !define APP_VERSION "1.65" 6 | # define the name of the installer 7 | OutFile "${APP_NAME}${APP_VERSION}-inst.exe" 8 | Name "${APP_NAME} ${APP_VERSION}" 9 | 10 | InstallDir "$APPDATA\${APP_NAME}\" 11 | InstallDirRegKey HKCU "Software\${APP_NAME}" "Install_Dir" 12 | ;RequestExecutionLevel user 13 | ShowInstDetails show 14 | ShowUninstDetails show 15 | SetCompressor /SOLID lzma 16 | 17 | ;!include "LogicLib.nsh" 18 | ;!include "FileFunc.nsh" 19 | ;!include "x64.nsh" 20 | 21 | ; The text to prompt the user to enter a directory 22 | DirText "This will install AltSnap on your computer. Choose a directory" 23 | Page directory 24 | Page instfiles 25 | Page custom customPage "" ": custom page" 26 | 27 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 28 | # DEFAULT SECTION 29 | Section 30 | 31 | Call CloseApp 32 | 33 | # define the output path for this file 34 | SetOutPath $INSTDIR 35 | 36 | File AltSnap.dni 37 | 38 | # define what to install and place it in the output path 39 | File AltSnap.exe 40 | File AltSnap.txt 41 | File AltSnap.xml 42 | File hooks.dll 43 | File License.txt 44 | File sch_On.bat 45 | File sch_Off.bat 46 | SetOutPath $INSTDIR\Lang 47 | File "Lang\_en_US baseline.txt" 48 | File Lang\ca_ES.ini 49 | File Lang\de_DE.ini 50 | File Lang\es_ES.ini 51 | File Lang\fi_FI.ini 52 | File Lang\fr_FR.ini 53 | File Lang\gl_ES.ini 54 | File Lang\it_IT.ini 55 | File Lang\ja_JP.ini 56 | File Lang\ko_KR.ini 57 | File Lang\nb_NO.ini 58 | File Lang\nl_NL.ini 59 | File Lang\pl_PL.ini 60 | File Lang\pt_PR.ini 61 | File Lang\ru_RU.ini 62 | File Lang\sz_SK.ini 63 | File Lang\zh_CN.ini 64 | File Lang\zh_TW.ini 65 | 66 | SetOutPath $INSTDIR\Themes\erasmion 67 | File Themes\erasmion\TRAY_OFF.ico 68 | File Themes\erasmion\TRAY_ON.ico 69 | File Themes\erasmion\TRAY_SUS.ico 70 | 71 | SetOutPath $INSTDIR 72 | CreateShortcut "$SMPROGRAMS\AltSnap.lnk" "$INSTDIR\AltSnap.exe" 73 | 74 | WriteRegStr HKCU "Software\${APP_NAME}" "Install_Dir" "$INSTDIR" 75 | WriteRegStr HKCU "Software\${APP_NAME}" "Version" "${APP_VERSION}" 76 | 77 | ; Create uninstaller 78 | WriteUninstaller "Uninstall.exe" 79 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"' 80 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "QuietUninstallString" '"$INSTDIR\Uninstall.exe" /S' 81 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayName" "${APP_NAME}" 82 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayIcon" '"$INSTDIR\${APP_NAME}.exe"' 83 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayVersion" "${APP_VERSION}" 84 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "HelpLink" "https://github.com/RamonUnch/AltSnap/wiki" 85 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "Publisher" "Raymond Gillibert" 86 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "InstallLocation" "$INSTDIR\" 87 | WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoModify" 1 88 | WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoRepair" 1 89 | 90 | ; Compute size for uninstall information 91 | ;${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 92 | ;IntFmt $0 "0x%08X" $0 93 | WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "EstimatedSize" "400" 94 | 95 | SectionEnd 96 | 97 | Function customPage 98 | MessageBox MB_YESNO "Run AltSnap now?" IDNO NoRunNow 99 | Exec "$INSTDIR\AltSnap.exe" ; view readme or whatever, if you want. 100 | NoRunNow: 101 | FunctionEnd 102 | 103 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 104 | # CLOSEAPP 105 | !define WM_CLOSE 0x0010 106 | !macro CloseApp un 107 | Function ${un}CloseApp 108 | ; Close app if running 109 | FindWindow $0 "${APP_NAME}" "" 110 | IntCmp $0 0 done 111 | DetailPrint "Attempting to close running ${APP_NAME}..." 112 | SendMessage $0 ${WM_CLOSE} 0 0 /TIMEOUT=500 113 | waitloop: 114 | Sleep 10 115 | FindWindow $0 "${APP_NAME}" "" 116 | IntCmp $0 0 closed waitloop waitloop 117 | closed: 118 | Sleep 100 ; Sleep a little extra to let Windows do its thing 119 | 120 | done: 121 | FunctionEnd 122 | !macroend 123 | !insertmacro CloseApp "" 124 | !insertmacro CloseApp "un." 125 | 126 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 127 | # UNINSTALL 128 | Section "Uninstall" 129 | 130 | Call un.CloseApp 131 | 132 | SetOutPath $INSTDIR 133 | # Always delete uninstaller first 134 | Delete "$INSTDIR\Uninstall.exe" 135 | 136 | # now delete installed file 137 | Delete "$INSTDIR\AltSnap.exe" 138 | Delete "$INSTDIR\AltSnap.txt" 139 | Delete "$INSTDIR\AltSnap.xml" 140 | Delete "$INSTDIR\AltSnap.dni" 141 | Delete "$INSTDIR\AltSnap.ini" 142 | Delete "$INSTDIR\AltSnap-old.ini" 143 | Delete "$INSTDIR\hooks.dll" 144 | Delete "$INSTDIR\License.txt" 145 | Delete "$INSTDIR\sch_On.bat" 146 | Delete "$INSTDIR\sch_Off.bat" 147 | 148 | Delete "Lang\_en_US baseline.txt" 149 | Delete Lang\ca_ES.ini 150 | Delete Lang\de_DE.ini 151 | Delete Lang\es_ES.ini 152 | Delete Lang\fi_FI.ini 153 | Delete Lang\fr_FR.ini 154 | Delete Lang\gl_ES.ini 155 | Delete Lang\it_IT.ini 156 | Delete Lang\ja_JP.ini 157 | Delete Lang\ko_KR.ini 158 | Delete Lang\nb_NO.ini 159 | Delete Lang\nl_NL.ini 160 | Delete Lang\pl_PL.ini 161 | Delete Lang\pt_PR.ini 162 | Delete Lang\ru_RU.ini 163 | Delete Lang\sz_SK.ini 164 | Delete Lang\zh_CN.ini 165 | Delete Lang\zh_TW.ini 166 | RMDir "$INSTDIR\Lang" 167 | 168 | Delete Themes\erasmion\TRAY_OFF.ico 169 | Delete Themes\erasmion\TRAY_ON.ico 170 | Delete Themes\erasmion\TRAY_SUS.ico 171 | RMDir "$INSTDIR\Themes\erasmion" 172 | RMDir "$INSTDIR\Themes" 173 | 174 | SetOutPath $APPDATA 175 | RMDir "$INSTDIR" 176 | 177 | Delete $SMPROGRAMS\AltSnap.lnk 178 | DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "AltSnap" 179 | DeleteRegKey /ifempty HKCU "Software\AltSnap" 180 | DeleteRegKey /ifempty HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\AltSnap" 181 | 182 | SectionEnd 183 | -------------------------------------------------------------------------------- /altsnap.rc: -------------------------------------------------------------------------------- 1 | #include "resource.h" 2 | 3 | APP_ICON ICON "media/icon.ico" 4 | TRAY_OFF ICON "media/tray-disabled.ico" 5 | TRAY_ON ICON "media/tray-enabled.ico" 6 | TRAY_SUS ICON "media/tray-suspended.ico" 7 | 8 | #include "window.rc" 9 | 10 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "AltSnap.exe.manifest" 11 | 12 | #define VS_VERSION_INFO 1 13 | VS_VERSION_INFO VERSIONINFO 14 | FILEVERSION VERSIONRC 15 | PRODUCTVERSION VERSIONRC 16 | FILEFLAGSMASK 0x3fL 17 | FILEFLAGS 0x0L 18 | FILEOS 0x40004L 19 | FILETYPE 0x1L 20 | FILESUBTYPE 0x0L 21 | BEGIN 22 | BLOCK "StringFileInfo" 23 | BEGIN 24 | BLOCK "040904b0" 25 | BEGIN 26 | VALUE "FileDescription", "AltSnap" 27 | VALUE "FileVersion", APP_VERSION 28 | VALUE "InternalName", "altsnap" 29 | VALUE "OriginalFilename", "AltSnap.exe" 30 | VALUE "CompanyName", "Gillibert Software" 31 | VALUE "LegalCopyright", "Gillibert" 32 | END 33 | END 34 | BLOCK "VarFileInfo" 35 | BEGIN 36 | VALUE "Translation", 0x409, 1200 37 | END 38 | END 39 | -------------------------------------------------------------------------------- /hooks.h: -------------------------------------------------------------------------------- 1 | #ifndef ALTDRAG_RPC_H 2 | #define ALTDRAG_RPC_H 3 | 4 | #define UNICODE 5 | #define _UNICODE 6 | #define _WIN32_WINNT 0x0600 7 | #define WINVER 0x0600 8 | #include 9 | #include "unfuck.h" 10 | 11 | #ifndef LOW_LEVEL_KB_PROC 12 | #ifndef DECORATED_HOOKS_DLL_PROCS 13 | #define LOW_LEVEL_KB_PROC "LowLevelKeyboardProc" 14 | #define LOAD_PROC "Load" 15 | #define UNLOAD_PROC "Unload" 16 | #else 17 | #define LOW_LEVEL_KB_PROC "_LowLevelKeyboardProc@12" 18 | #define LOAD_PROC "_Load@8" 19 | #define UNLOAD_PROC "_Unload@0" 20 | #endif 21 | #endif 22 | 23 | // Extra messages for Action Menu 24 | #define LP_CURSORPOS (1<<0) 25 | #define LP_TOPMOST (1<<1) 26 | #define LP_BORDERLESS (1<<2) 27 | #define LP_MAXIMIZED (1<<3) 28 | #define LP_ROLLED (1<<4) 29 | #define LP_MOVEONOFF (1<<5) 30 | #define LP_NOALTACTION (1<<6) 31 | 32 | // App 33 | #define APP_NAME TEXT("AltSnap") 34 | #define APP_NAMEA "AltSnap" 35 | #define APP_PROPPT APP_NAME TEXT("-RDim") 36 | #define APP_PROPFL APP_NAME TEXT("-RFlag") 37 | #define APP_PROPOFFSET APP_NAME TEXT("-ROffset") 38 | #define APP_PRBDLESS APP_NAME TEXT("-RStyle") 39 | #define APP_ROLLED APP_NAME TEXT("-Rolled") 40 | #define APP_ASONOFF APP_NAME TEXT("-ASOnOff") 41 | #define APP_MOVEONOFF APP_NAME TEXT("-MoveOnOff") 42 | #define APP_PRODPI APP_NAME TEXT("-ODPI") 43 | #define APP_OWDMCP APP_NAME TEXT("-OWDMCP") 44 | #define FZ_PROPPT TEXT("FancyZones_RestoreSize") 45 | #define FZ_PROPZONES TEXT("FancyZones_zones") 46 | 47 | // User Messages 48 | #define WM_TRAY (WM_USER+2) 49 | #define WM_SCLICK (WM_USER+3) 50 | #define WM_UPDCFRACTION (WM_USER+4) 51 | #define WM_UPDATETRAY (WM_USER+5) 52 | #define WM_OPENCONFIG (WM_USER+6) 53 | #define WM_CLOSECONFIG (WM_USER+7) 54 | #define WM_UPDATESETTINGS (WM_USER+8) 55 | #define WM_ADDTRAY (WM_USER+9) 56 | #define WM_HIDETRAY (WM_USER+10) 57 | #define WM_UNIKEYMENU (WM_USER+11) 58 | #define WM_GETCLICKHWND (WM_USER+12) 59 | #define WM_STACKLIST (WM_USER+13) 60 | #define WM_FINISHMOVEMENT (WM_USER+14) 61 | #define WM_CLOSEMODE (WM_USER+15) 62 | #define WM_SETLAYOUTNUM (WM_USER+16) 63 | #define WM_GETLAYOUTREZ (WM_USER+17) 64 | #define WM_GETBESTLAYOUT (WM_USER+18) 65 | #define WM_GETZONESLEN (WM_USER+19) 66 | #define WM_GETZONES (WM_USER+20) 67 | 68 | // List of possible actions 69 | // ACVALUE(AC_ENUM, "IniString", Info) 70 | #define ACTION_MAP \ 71 | ACVALUE(AC_NONE=0, "Nothing", 00) \ 72 | ACVALUE(AC_MOVE, "Move", MR) \ 73 | ACVALUE(AC_RESIZE, "Resize", MR) \ 74 | ACVALUE(AC_RESTORE, "Restore", MR) \ 75 | ACVALUE(AC_MENU, "Menu", CL) \ 76 | ACVALUE(AC_MINIMIZE, "Minimize", MR) \ 77 | ACVALUE(AC_MAXIMIZE, "Maximize", MR) \ 78 | ACVALUE(AC_CENTER, "Center", MR) \ 79 | ACVALUE(AC_ALWAYSONTOP, "AlwaysOnTop", ZO) \ 80 | ACVALUE(AC_CLOSE, "Close", CL) \ 81 | ACVALUE(AC_LOWER, "Lower", ZO) \ 82 | ACVALUE(AC_FOCUS, "Focus", ZO) \ 83 | ACVALUE(AC_BORDERLESS, "Borderless", 00) \ 84 | ACVALUE(AC_KILL, "Kill", CL) \ 85 | ACVALUE(AC_PAUSE, "Pause", CL) \ 86 | ACVALUE(AC_RESUME, "Resume", CL) \ 87 | ACVALUE(AC_MAXHV, "MaximizeHV", MR) \ 88 | ACVALUE(AC_MINALL, "MinAllOther", 00) \ 89 | ACVALUE(AC_MUTE, "Mute", 00) \ 90 | ACVALUE(AC_SIDESNAP, "SideSnap", MR) \ 91 | ACVALUE(AC_EXTENDSNAP, "ExtendSnap", MR) \ 92 | ACVALUE(AC_EXTENDTNEDGE, "ExtendTNEdge",MR) \ 93 | ACVALUE(AC_MOVETNEDGE, "MoveTNEdge", MV) \ 94 | ACVALUE(AC_NSTACKED, "NStacked", ZO) \ 95 | ACVALUE(AC_NSTACKED2, "NStacked2", ZO) \ 96 | ACVALUE(AC_PSTACKED, "PStacked", ZO) \ 97 | ACVALUE(AC_PSTACKED2, "PStacked2", ZO) \ 98 | ACVALUE(AC_STACKLIST, "StackList", CL) \ 99 | ACVALUE(AC_STACKLIST2, "StackList2", CL) \ 100 | ACVALUE(AC_ALTTABLIST, "AltTabList", CL) \ 101 | ACVALUE(AC_ALTTABFULLLIST, "AltTabFullList", CL) \ 102 | ACVALUE(AC_ASONOFF, "ASOnOff", CL) \ 103 | ACVALUE(AC_MOVEONOFF, "MoveOnOff", CL) \ 104 | \ 105 | ACVALUE(AC_MLZONE, "MLZone", MR) \ 106 | ACVALUE(AC_MTZONE, "MTZone", MR) \ 107 | ACVALUE(AC_MRZONE, "MRZone", MR) \ 108 | ACVALUE(AC_MBZONE, "MBZone", MR) \ 109 | ACVALUE(AC_XLZONE, "XLZone", MR) \ 110 | ACVALUE(AC_XTZONE, "XTZone", MR) \ 111 | ACVALUE(AC_XRZONE, "XRZone", MR) \ 112 | ACVALUE(AC_XBZONE, "XBZone", MR) \ 113 | \ 114 | ACVALUE(AC_XTNLEDGE, "XTNLEdge", MR) \ 115 | ACVALUE(AC_XTNTEDGE, "XTNTEdge", MR) \ 116 | ACVALUE(AC_XTNREDGE, "XTNREdge", MR) \ 117 | ACVALUE(AC_XTNBEDGE, "XTNBEdge", MR) \ 118 | ACVALUE(AC_MTNLEDGE, "MTNLEdge", MV) \ 119 | ACVALUE(AC_MTNTEDGE, "MTNTEdge", MV) \ 120 | ACVALUE(AC_MTNREDGE, "MTNREdge", MV) \ 121 | ACVALUE(AC_MTNBEDGE, "MTNBEdge", MV) \ 122 | \ 123 | ACVALUE(AC_STEPL, "StepL", MR) \ 124 | ACVALUE(AC_STEPT, "StepT", MR) \ 125 | ACVALUE(AC_STEPR, "StepR", MR) \ 126 | ACVALUE(AC_STEPB, "StepB", MR) \ 127 | ACVALUE(AC_SSTEPL, "SStepL", MR) \ 128 | ACVALUE(AC_SSTEPT, "SStepT", MR) \ 129 | ACVALUE(AC_SSTEPR, "SStepR", MR) \ 130 | ACVALUE(AC_SSTEPB, "SStepB", MR) \ 131 | \ 132 | ACVALUE(AC_FOCUSL, "FocusL", ZO) \ 133 | ACVALUE(AC_FOCUST, "FocusT", ZO) \ 134 | ACVALUE(AC_FOCUSR, "FocusR", ZO) \ 135 | ACVALUE(AC_FOCUSB, "FocusB", ZO) \ 136 | \ 137 | ACVALUE(AC_ROLL, "Roll", MR) \ 138 | ACVALUE(AC_ALTTAB, "AltTab", ZO) \ 139 | ACVALUE(AC_VOLUME, "Volume", 00) \ 140 | /* ACVALUE(AC_BRIGHTNESS, "Brightness", 00) */ \ 141 | ACVALUE(AC_TRANSPARENCY, "Transparency", 00) \ 142 | ACVALUE(AC_HSCROLL, "HScroll", 00) \ 143 | ACVALUE(AC_ZOOM, "Zoom", MR) \ 144 | ACVALUE(AC_ZOOM2, "Zoom2", MR) \ 145 | ACVALUE(AC_NPSTACKED, "NPStacked", ZO) \ 146 | ACVALUE(AC_NPSTACKED2, "NPStacked2", ZO) 147 | 148 | #define ACVALUE(a, b, c) a, 149 | enum action { ACTION_MAP AC_MAXVALUE, AC_SHRT0, AC_SHRTF=AC_SHRT0+36, AC_ORICLICK }; 150 | #undef ACVALUE 151 | 152 | // List of extra info options 153 | enum { 154 | ACINFO_MOVE = 1, 155 | ACINFO_RESIZE = 2, 156 | ACINFO_ZORDER = 4, 157 | ACINFO_CLOSE = 8, 158 | }; 159 | #define MV ACINFO_MOVE 160 | #define RZ ACINFO_RESIZE 161 | #define ZO ACINFO_ZORDER 162 | #define CL ACINFO_CLOSE 163 | 164 | #define MR (ACINFO_MOVE|ACINFO_RESIZE) 165 | 166 | // Helper function to get extra action info 167 | static xpure UCHAR ActionInfo(enum action action) 168 | { 169 | #define ACVALUE(a, b, c) (c), 170 | static const UCHAR action_info[] = { ACTION_MAP }; 171 | 172 | #undef ACVALUE 173 | return action_info[action]; 174 | } 175 | #undef MV 176 | #undef RZ 177 | #undef ZO 178 | #undef CL 179 | #undef MR 180 | 181 | #define MOUVEMENT(action) (action <= AC_RESIZE) 182 | 183 | /////////////////////////////////////////////////////////////////////////// 184 | // Check if key is assigned in the HKlist 185 | static int pure IsHotkeyy(unsigned char key, const unsigned char *HKlist) 186 | { 187 | const UCHAR *pos=&HKlist[0]; 188 | while (*pos) { 189 | if (key == *pos) { 190 | return 1; 191 | } 192 | pos++; 193 | } 194 | return 0; 195 | } 196 | static int pure IsActionInList(const enum action ac, const enum action *aclst) 197 | { 198 | do { 199 | if(ac == *aclst) 200 | return 1; 201 | } while(*aclst++ != AC_NONE); 202 | 203 | return 0; 204 | } 205 | // Convert zone number to ini name entry 206 | static TCHAR *ZidxToZonestr(int laynum, int idx, TCHAR zname[AT_LEAST 32]) 207 | { 208 | if (laynum > 9 ) return NULL; 209 | TCHAR txt[UINT_DIGITS+1]; 210 | zname[0] = !laynum?TEXT('\0'): TEXT('A')+laynum-1 ; 211 | zname[1] = '\0'; 212 | lstrcat_s(zname, 32, TEXT("Zone")); 213 | lstrcat_s(zname, 32, Uint2lStr(txt, idx)); // Zone Name from zone number 214 | 215 | return zname; 216 | } 217 | static char *ZidxToZonestrA(int laynum, int idx, char zname[AT_LEAST 32]) 218 | { 219 | if (laynum > 9 ) return NULL; 220 | char txt[16]; 221 | zname[0] = !laynum?'\0': 'A'+laynum-1 ; 222 | zname[1] = '\0'; 223 | lstrcat_sA(zname, 32, "Zone"); 224 | lstrcat_sA(zname, 32, Uint2lStrA(txt, idx)); // Zone Name from zone number 225 | 226 | return zname; 227 | } 228 | 229 | // Map action string to actual action enum 230 | static enum action MapActionW(const TCHAR *txt) 231 | { 232 | #define ACVALUE(a, b, c) (b), 233 | static const char *action_map[] = { ACTION_MAP }; 234 | #undef ACVALUE 235 | UCHAR ac; 236 | for (ac=0; ac < ARR_SZ(action_map); ac++) { 237 | if(!strtotcharicmp(txt, action_map[ac])) 238 | return (enum action)ac; 239 | } 240 | // ShrtX X = 0 to F. 241 | if (txt[0] == 'S' && txt[1] == 'h' && txt[2] == 'r' && txt[3] == 't' 242 | && '0' <= txt[4] && txt[4] <= 'Z' && txt[5] == '\0' ) { 243 | TCHAR c = txt[4]; 244 | UCHAR num = c<='9' ? c - '0' : c-'A'+10; 245 | num = min(num, AC_SHRTF-AC_SHRT0-1); 246 | return (enum action)(AC_SHRT0 + num); 247 | } 248 | return AC_NONE; 249 | } 250 | 251 | #endif /* ALTDRAG_RPC_H */ 252 | -------------------------------------------------------------------------------- /hooks.rc: -------------------------------------------------------------------------------- 1 | #include "resource.h" 2 | 3 | 1 VERSIONINFO 4 | FILEVERSION VERSIONRC 5 | PRODUCTVERSION VERSIONRC 6 | FILEFLAGSMASK 0x3fL 7 | FILEFLAGS 0x0L 8 | FILEOS 0x40004L 9 | FILETYPE 0x1L 10 | FILESUBTYPE 0x0L 11 | BEGIN 12 | BLOCK "StringFileInfo" 13 | BEGIN 14 | BLOCK "040904b0" 15 | BEGIN 16 | VALUE "FileDescription", "Hooks for AltSnap" 17 | VALUE "InternalName", "hooks" 18 | VALUE "OriginalFilename", "hooks.dll" 19 | VALUE "FileVersion", APP_VERSION 20 | VALUE "CompanyName", "Gillibert Software" 21 | VALUE "LegalCopyright", "Gillibert" 22 | END 23 | END 24 | BLOCK "VarFileInfo" 25 | BEGIN 26 | VALUE "Translation", 0x409, 1200 27 | END 28 | END 29 | -------------------------------------------------------------------------------- /languages.c: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * Copyright (C) 2015 Stefan Sundin * 3 | * This program is free software: you can redistribute it and/or modify * 4 | * it under the terms of the GNU General Public License as published by * 5 | * the Free Software Foundation, either version 3 or later. * 6 | * Modified By Raymond Gillibert in 2022 * 7 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 8 | 9 | #include "languages.h" 10 | 11 | static const struct strings *l10n_ini = NULL; 12 | static const struct strings *l10n = &en_US; 13 | 14 | ///////////////////////////////////////////////////////////////////////////// 15 | // Copies and remove the accelerators & sign. and txt between ( ). 16 | static size_t lstrcpy_noaccel(TCHAR *__restrict__ dest, const TCHAR *__restrict__ source, size_t destlen) 17 | { 18 | size_t i=0, j=0; 19 | while(i < destlen && source[i]) { 20 | dest[j] = source[i]; 21 | if (source[i] == '(') { 22 | // If we found a '(' go to the closing one ')'. 23 | while(i < destlen && source[i] && source[i] != ')') i++; 24 | i++; 25 | i += source[i] == ' '; // Remove space after ) if there is one. 26 | } else { 27 | j += source[i] != '&'; 28 | i++; 29 | } 30 | } 31 | dest[j] = '\0'; 32 | return j; 33 | } 34 | ///////////////////////////////////////////////////////////////////////////// 35 | static pure size_t lstrlen_resolved(const TCHAR *__restrict__ str) 36 | { 37 | // Return the length of str, having resolved escape sequences 38 | const TCHAR *ptr; 39 | int num_escape_sequences = 0; 40 | for (ptr=str; *ptr != '\0'; ptr++) { 41 | if (*ptr == '\\' && *(ptr+1) != '\0') { 42 | ptr++; 43 | num_escape_sequences++; 44 | } 45 | } 46 | return ptr-str-num_escape_sequences; 47 | } 48 | 49 | static void lstrcpy_resolve(TCHAR *__restrict__ dest, const TCHAR *__restrict__ source) 50 | { 51 | // Copy from source to dest, resolving \\n to \n 52 | for (; *source != '\0'; source++,dest++) { 53 | if (*source == '\\' && *(source+1) == 'n') { 54 | *dest = '\n'; 55 | source++; 56 | } else { 57 | *dest = *source; 58 | } 59 | } 60 | *dest = '\0'; 61 | } 62 | 63 | ///////////////////////////////////////////////////////////////////////////// 64 | // 65 | static void LoadTranslationOrTT(const TCHAR *__restrict__ ini, const TCHAR * __restrict__ section_name, int offset) 66 | { 67 | // if english is not seleced then we have to allocate l10_ini strings struct 68 | // and we have to read the ini file... 69 | size_t i; 70 | DWORD ret; 71 | DWORD tsectionlen=16383; 72 | TCHAR *tsection = NULL; 73 | do { 74 | tsectionlen *=2; 75 | TCHAR *tmp = (TCHAR *)realloc(tsection, tsectionlen*sizeof(TCHAR)); 76 | if(!tmp) { free(tsection); return; } 77 | tsection = tmp; 78 | ret = GetPrivateProfileSection(section_name, tsection, tsectionlen, ini); 79 | } while (ret == tsectionlen-2); 80 | 81 | if (!ret) 82 | tsection[0] = tsection[1] = TEXT('\0'); 83 | 84 | if(!l10n_ini) l10n_ini = (struct strings *)calloc(1, sizeof(struct strings)); 85 | if(!l10n_ini) return; // Unable to allocate mem 86 | 87 | for (i=0; i < ARR_SZ(l10n_inimapping); i++) { 88 | // Get pointer to default English string to be used if ini entry doesn't exist 89 | const TCHAR *const def = ((TCHAR **)&en_US)[i*2+offset]; 90 | const TCHAR *txt = GetSectionOptionCStr(tsection, l10n_inimapping[i], def); 91 | if(!txt) continue; 92 | 93 | TCHAR buf[128]; 94 | TCHAR **deststr = &((TCHAR **)l10n_ini)[i*2+offset]; 95 | if (deststr == &l10n_ini->AboutVersion) { 96 | // Append version number to version.... 97 | lstrcpy_s(buf, ARR_SZ(buf), txt); 98 | lstrcat_s(buf, ARR_SZ(buf), TEXT(" ") TEXT(APP_VERSION)); 99 | txt = (const TCHAR*)buf; 100 | } 101 | *deststr = (TCHAR *)realloc( *deststr, (lstrlen_resolved(txt)+1)*sizeof(TCHAR) ); 102 | lstrcpy_resolve(*deststr, txt); 103 | } 104 | l10n = l10n_ini; 105 | free(tsection); // free the cached Translation section. 106 | } 107 | 108 | static void LoadTranslation(const TCHAR *__restrict__ ini) 109 | { 110 | if (!ini) { 111 | l10n = (struct strings *)&en_US; 112 | return; 113 | } else if( INVALID_FILE_ATTRIBUTES == GetFileAttributes(ini) ) { 114 | return; 115 | } 116 | 117 | LoadTranslationOrTT(ini, TEXT("Translation"), 0); 118 | LoadTranslationOrTT(ini, TEXT("ToolTips"), 1); 119 | } 120 | 121 | struct langinfoitem *langinfo = NULL; 122 | int nlanguages; 123 | 124 | ///////////////////////////////////////////////////////////////////////////// 125 | void ListAllTranslations() 126 | { 127 | if (langinfo) return; 128 | 129 | HANDLE hFind = INVALID_HANDLE_VALUE; 130 | WIN32_FIND_DATA ffd; 131 | TCHAR szDir[MAX_PATH], fpath[MAX_PATH*2]; 132 | LPCTSTR txt; 133 | 134 | // First element 135 | langinfo = (struct langinfoitem *)malloc( sizeof(struct langinfoitem) ); 136 | if (!langinfo) return; 137 | langinfo[0].code = en_US.Code; 138 | langinfo[0].lang_english = en_US.LangEnglish; 139 | langinfo[0].lang = en_US.Lang; 140 | langinfo[0].author = en_US.Author; 141 | langinfo[0].fn = NULL; 142 | nlanguages = 1; 143 | 144 | GetModuleFileName(NULL, szDir, ARR_SZ(szDir)); 145 | PathRemoveFileSpecL(szDir); 146 | lstrcat_s(szDir, ARR_SZ(szDir), TEXT("\\Lang\\*.ini")); 147 | lstrcpy_s(fpath, ARR_SZ(fpath), szDir); 148 | TCHAR *end = fpath; // not the star! 149 | end += lstrlen(fpath)-5; 150 | hFind = FindFirstFile(szDir, &ffd); 151 | 152 | if (hFind != INVALID_HANDLE_VALUE) { 153 | int n=1; 154 | do { 155 | nlanguages++; 156 | lstrcpy(end, ffd.cFileName); // add filenale at the end of the path 157 | struct langinfoitem *tmp = (struct langinfoitem *)realloc(langinfo, sizeof(*tmp) * nlanguages); 158 | if (!tmp) break; 159 | langinfo = tmp; 160 | 161 | // Preload section start 162 | TCHAR tsection[512]; 163 | DWORD ret = GetPrivateProfileSection(TEXT("Translation"), tsection, ARR_SZ(tsection), fpath); 164 | if(!ret) continue; 165 | 166 | // Short language code such as en-US, fr-FR, it-IT etc. 167 | txt = GetSectionOptionCStr(tsection, "Code", TEXT("")); 168 | langinfo[n].code = (TCHAR *)calloc(lstrlen(txt)+1, sizeof(TCHAR)); 169 | if (!langinfo[n].code) break; 170 | lstrcpy(langinfo[n].code, txt); 171 | 172 | // Language name in English 173 | txt = GetSectionOptionCStr(tsection, "LangEnglish", TEXT("")); 174 | langinfo[n].lang_english = (TCHAR *)calloc(lstrlen(txt)+1, sizeof(TCHAR)); 175 | if (!langinfo[n].lang_english) break; 176 | lstrcpy(langinfo[n].lang_english, txt); 177 | 178 | // Language name in original language 179 | txt = GetSectionOptionCStr(tsection, "Lang", TEXT("")); 180 | langinfo[n].lang = (TCHAR *)calloc(lstrlen(txt)+1, sizeof(TCHAR)); 181 | if (!langinfo[n].lang) break; 182 | lstrcpy(langinfo[n].lang, txt); 183 | 184 | // Author 185 | txt = GetSectionOptionCStr(tsection, "Author", TEXT("")); 186 | langinfo[n].author = (TCHAR *)calloc(lstrlen(txt)+1, sizeof(TCHAR)); 187 | if (!langinfo[n].author) break; 188 | lstrcpy(langinfo[n].author, txt); 189 | 190 | // Full file path 191 | langinfo[n].fn = (TCHAR *)malloc(lstrlen(fpath)*sizeof(TCHAR)+4); 192 | if (!langinfo[n].fn) break; 193 | lstrcpy(langinfo[n].fn, fpath); 194 | 195 | n++; 196 | } while (FindNextFile(hFind, &ffd)); 197 | 198 | FindClose(hFind); 199 | } 200 | } 201 | 202 | ///////////////////////////////////////////////////////////////////////////// 203 | // Helper function to get 204 | static int GetCUserLanguage_xx_XX(wchar_t txt[AT_LEAST 16]) 205 | { 206 | txt[0] = L'\0'; 207 | return LCIDToLocaleNameL(GetUserDefaultLCID(), txt, 16, 0); 208 | } 209 | 210 | ///////////////////////////////////////////////////////////////////////////// 211 | void UpdateLanguage() 212 | { 213 | TCHAR txt[16]; 214 | GetPrivateProfileString(TEXT("General"), TEXT("Language"), TEXT("Auto"), txt, ARR_SZ(txt), inipath); 215 | 216 | // Determine which language should be used 217 | // based on current user's LCID 218 | #ifdef _UNICODE 219 | if (!lstrcmpi(txt, TEXT("Auto"))) { 220 | GetCUserLanguage_xx_XX(txt); 221 | } 222 | #endif // _UNICODE 223 | 224 | if (!lstrcmpi(txt, TEXT("en-US"))) 225 | return; // Hardcoded language 226 | 227 | ListAllTranslations(); 228 | int i; 229 | for (i=0; i < nlanguages; i++) { 230 | if (!lstrcmpi(txt, langinfo[i].code)) { 231 | LoadTranslation(langinfo[i].fn); 232 | break; 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /languages.h: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * This file must be UTF-8, Çe fichier doit être encodé en UTF8 * 3 | * Copyright (C) 2015 Stefan Sundin * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 or later. * 7 | * Modified By Raymond Gillibert in 2020 * 8 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 9 | 10 | #ifndef ALTSNAP_STRINGS_H 11 | #define ALTSNAP_STRINGS_H 12 | 13 | #include 14 | #include 15 | #include "resource.h" 16 | 17 | // Resolve index from entry name. 18 | #define L10NIDX(entryname) (short)( offsetof(struct strings, entryname)/sizeof(TCHAR**) ) 19 | 20 | // Resolve entry name from index. 21 | #define L10NSTR(i) ( ((const TCHAR*const*const)l10n)[i] ) 22 | 23 | struct langinfoitem { 24 | TCHAR *code; 25 | TCHAR *lang_english; 26 | TCHAR *lang; 27 | TCHAR *author; 28 | TCHAR *fn; 29 | }; 30 | 31 | #define LANGUAGE_MAP \ 32 | LNGVALUE(Code, TEXT("en-US"), NULL) \ 33 | LNGVALUE(LangEnglish, TEXT("English"), NULL) \ 34 | LNGVALUE(Lang, TEXT("English"), NULL) \ 35 | LNGVALUE(Author, TEXT("Stefan Sundin, RamonUnch"), NULL) \ 36 | /* Menu */ \ 37 | LNGVALUE(MenuEnable, TEXT("&Enable"), NULL) \ 38 | LNGVALUE(MenuDisable, TEXT("&Disable"), NULL) \ 39 | LNGVALUE(MenuHideTray, TEXT("&Hide tray"), NULL) \ 40 | LNGVALUE(MenuConfigure, TEXT("&Configure..."), NULL) \ 41 | LNGVALUE(MenuAbout, TEXT("&About"), NULL) \ 42 | LNGVALUE(MenuOpenIniFile, TEXT("&Open ini file"), NULL) \ 43 | LNGVALUE(MenuSaveZones, TEXT("&Save test windows as snap layout"), NULL) \ 44 | LNGVALUE(MenuEmptyZone, TEXT("(empty)"), NULL) \ 45 | LNGVALUE(MenuSnapLayout, TEXT("Snap layout &"), NULL) \ 46 | LNGVALUE(MenuEditLayout, TEXT("Edi&t snap layout"), NULL) \ 47 | LNGVALUE(MenuCloseAllZones,TEXT("C&lose all test windows"), NULL) \ 48 | LNGVALUE(MenuExit, TEXT("E&xit"), NULL) \ 49 | /* Config Title and Tabs */ \ 50 | LNGVALUE(ConfigTitle, APP_NAME TEXT(" Configuration"), NULL) \ 51 | LNGVALUE(ConfigTabGeneral, TEXT("General"), NULL) \ 52 | LNGVALUE(ConfigTabMouse, TEXT("Mouse"), NULL) \ 53 | LNGVALUE(ConfigTabKeyboard, TEXT("Keyboard"), NULL) \ 54 | LNGVALUE(ConfigTabBlacklist, TEXT("Blacklist"), NULL) \ 55 | LNGVALUE(ConfigTabAdvanced, TEXT("Advanced"), NULL) \ 56 | LNGVALUE(ConfigTabAbout, TEXT("About"), NULL) \ 57 | /* General Box */ \ 58 | LNGVALUE(GeneralBox, TEXT("General settings"), NULL) \ 59 | LNGVALUE(GeneralAutoFocus, TEXT("&Focus windows when dragging.\nYou can also press Ctrl to focus windows."), NULL) \ 60 | LNGVALUE(GeneralAero, TEXT("Mimi&c Aero Snap"), NULL) \ 61 | LNGVALUE(GeneralSmartAero, TEXT("Smart Aero Sna&p dimensions"), NULL) \ 62 | LNGVALUE(GeneralSmarterAero, TEXT("Smarter Aer&o Snap dimensions"), NULL) \ 63 | LNGVALUE(GeneralStickyResize, TEXT("Resi&ze other snapped windows with Shift"), NULL) \ 64 | LNGVALUE(GeneralInactiveScroll, TEXT("&Scroll inactive windows"), NULL) \ 65 | LNGVALUE(GeneralMDI, TEXT("&MDI support"), NULL) \ 66 | LNGVALUE(GeneralAutoSnap, TEXT("S&nap window edges to:"), NULL) \ 67 | LNGVALUE(GeneralAutoSnap0, TEXT("Disabled"), NULL) \ 68 | LNGVALUE(GeneralAutoSnap1, TEXT("To screen borders"), NULL) \ 69 | LNGVALUE(GeneralAutoSnap2, TEXT("+ outside of windows"), NULL) \ 70 | LNGVALUE(GeneralAutoSnap3, TEXT("+ inside of windows"), NULL) \ 71 | LNGVALUE(GeneralLanguage, TEXT("&Language:"), NULL) \ 72 | LNGVALUE(GeneralFullWin, TEXT("&Drag full windows"), NULL) \ 73 | LNGVALUE(GeneralUseZones, TEXT("Snap to Layo&ut with Shift (configure with tray menu)"), TEXT("This option will mimick FancyZones\r\nOpen TestWindows to set up the zones\n Look at the tray icon menu")) \ 74 | LNGVALUE(GeneralPiercingClick, TEXT("Avoi&d blocking Alt+Click (disables AltSnap double-clicks)"), NULL) \ 75 | LNGVALUE(GeneralResizeAll, TEXT("&Resize all windows"), NULL) \ 76 | LNGVALUE(GeneralResizeCenter, TEXT("Center resize mode"), NULL) \ 77 | LNGVALUE(GeneralResizeCenterNorm, TEXT("All d&irections"), NULL) \ 78 | LNGVALUE(GeneralResizeCenterBr, TEXT("&Bottom right"), NULL) \ 79 | LNGVALUE(GeneralResizeCenterMove, TEXT("Mo&ve"), NULL) \ 80 | LNGVALUE(GeneralResizeCenterClose,TEXT("Clos&est side"), NULL) \ 81 | LNGVALUE(GeneralAutostartBox, TEXT("Autostart"), NULL) \ 82 | LNGVALUE(GeneralAutostart, TEXT("S&tart ") APP_NAME TEXT(" when logging on"), NULL) \ 83 | LNGVALUE(GeneralAutostartHide, TEXT("&Hide tray"), NULL) \ 84 | LNGVALUE(GeneralAutostartElevate, TEXT("&Elevate to administrator privileges"), NULL) \ 85 | LNGVALUE(GeneralAutostartElevateTip, TEXT("Note that a UAC prompt will appear every time you log in, unless you disable UAC completely or use the Task Scheduler.\nTo setup a Scheduled task for this purpose, you can use the sch_On.bat batch files in Altsnap's folder."), NULL) \ 86 | LNGVALUE(GeneralElevate, TEXT("E&levate"), NULL) \ 87 | LNGVALUE(GeneralElevated, TEXT("Elevated"), NULL) \ 88 | LNGVALUE(GeneralElevationAborted, TEXT("Elevation aborted."), NULL) \ 89 | /* Keyboard & Mouse tabs */ \ 90 | LNGVALUE(InputMouseBox, TEXT("Mouse actions"), NULL) \ 91 | LNGVALUE(InputMouseBtAc1, TEXT("&1. Primary"), TEXT("Action performed with Hotkey")) \ 92 | LNGVALUE(InputMouseBtAc2, TEXT("&2. Alternate"), TEXT("Action performed with Hotkey + Modifier key (see Keyboard tab)")) \ 93 | LNGVALUE(InputMouseINTTB, TEXT("&Title bar"), TEXT("Action performed when clicking on the title bar")) \ 94 | LNGVALUE(InputMouseWhileM, TEXT("Whil&e moving"), NULL) \ 95 | LNGVALUE(InputMouseWhileR, TEXT("While resi&zing"), NULL) \ 96 | LNGVALUE(InputMouseLMB, TEXT("Left mouse &button:"), NULL) \ 97 | LNGVALUE(InputMouseMMB, TEXT("&Middle mouse button:"), NULL) \ 98 | LNGVALUE(InputMouseRMB, TEXT("Ri&ght mouse button:"), NULL) \ 99 | LNGVALUE(InputMouseMB4, TEXT("Mouse button &4:"), NULL) \ 100 | LNGVALUE(InputMouseMB5, TEXT("Mouse button &5:"), NULL) \ 101 | LNGVALUE(InputMouseScroll, TEXT("&Scroll wheel:"), NULL) \ 102 | LNGVALUE(InputMouseHScroll, TEXT("Scroll wheel (&horizontal):"), NULL) \ 103 | LNGVALUE(InputMouseMoveUp, TEXT("Long &drag-free Move:"), NULL) \ 104 | LNGVALUE(InputMouseResizeUp,TEXT("Long drag-&free Resize:"), NULL) \ 105 | LNGVALUE(InputMouseTTBActionBox, TEXT("Use specific actions when clicking the Title bar"), NULL) \ 106 | LNGVALUE(InputMouseTTBActionNA, TEXT("Without hot&key"), NULL) \ 107 | LNGVALUE(InputMouseTTBActionWA, TEXT("&With hotkey"), NULL) \ 108 | LNGVALUE(InputMouseMMBHC, TEXT("M&iddle mouse button"), NULL) \ 109 | LNGVALUE(InputMouseMB4HC, TEXT("M&ouse button 4"), NULL) \ 110 | LNGVALUE(InputMouseMB5HC, TEXT("Mo&use button 5"), NULL) \ 111 | LNGVALUE(InputMouseLongClickMove, TEXT("Mo&ve windows with a long left-click"), NULL) \ 112 | LNGVALUE(InputScrollLockState, TEXT("Suspend/Resume AltSnap based on &Scroll lock state"), NULL) \ 113 | LNGVALUE(InputUniKeyHoldMenu, TEXT("Pop&up an extended character menu when holding an alphabetic key down"), NULL) \ 114 | LNGVALUE(InputKeyCombo, TEXT("Use two keys &combo to activate"), NULL) \ 115 | LNGVALUE(InputGrabWithAlt, TEXT("&Action without click:"), NULL) \ 116 | LNGVALUE(InputGrabWithAltB, TEXT("Acti&on without click (alt):"), NULL) \ 117 | \ 118 | LNGVALUE(InputActionMove, TEXT("Move window"), NULL) \ 119 | LNGVALUE(InputActionResize, TEXT("Resize window"), NULL) \ 120 | LNGVALUE(InputActionRestore, TEXT("Restore window"), NULL) \ 121 | LNGVALUE(InputActionClose, TEXT("&Close window"), NULL) \ 122 | LNGVALUE(InputActionKill, TEXT("&Kill program"), NULL) \ 123 | LNGVALUE(InputActionPause, TEXT("Pause program"), NULL) \ 124 | LNGVALUE(InputActionResume, TEXT("Resume program"), NULL) \ 125 | LNGVALUE(InputActionASOnOff, TEXT("S&uspend/Resume AltSnap"), NULL) \ 126 | LNGVALUE(InputActionMoveOnOff, TEXT("Movement dis&abled"), NULL) \ 127 | LNGVALUE(InputActionMinimize, TEXT("Mi&nimize window"), NULL) \ 128 | LNGVALUE(InputActionMaximize, TEXT("Ma&ximize window"), NULL) \ 129 | LNGVALUE(InputActionLower, TEXT("&Lower window"), NULL) \ 130 | LNGVALUE(InputActionFocus, TEXT("Focus window"), NULL) \ 131 | LNGVALUE(InputActionNStacked, TEXT("Next stacked window"), NULL) \ 132 | LNGVALUE(InputActionNStacked2, TEXT("Next laser stacked window"), NULL) \ 133 | LNGVALUE(InputActionPStacked, TEXT("Previous stacked window"), NULL) \ 134 | LNGVALUE(InputActionPStacked2, TEXT("Previous laser stacked window"), NULL) \ 135 | LNGVALUE(InputActionNPStacked, TEXT("Next/Prev stacked window"), NULL) \ 136 | LNGVALUE(InputActionNPStacked2, TEXT("Next/Prev laser stacked window"), NULL) \ 137 | LNGVALUE(InputActionStackList, TEXT("Stacked windows list"), NULL) \ 138 | LNGVALUE(InputActionStackList2, TEXT("Laser stacked windows list"), NULL) \ 139 | LNGVALUE(InputActionAltTabList, TEXT("Windows list"), NULL) \ 140 | LNGVALUE(InputActionAltTabFullList, TEXT("All windows list"), NULL) \ 141 | LNGVALUE(InputActionMLZone, TEXT("Move to the left zone"), NULL) \ 142 | LNGVALUE(InputActionMTZone, TEXT("Move to the top zone"), NULL) \ 143 | LNGVALUE(InputActionMRZone, TEXT("Move to the right zone"), NULL) \ 144 | LNGVALUE(InputActionMBZone, TEXT("Move to the bottom zone"), NULL) \ 145 | LNGVALUE(InputActionXLZone, TEXT("Extend to the left zone"), NULL) \ 146 | LNGVALUE(InputActionXTZone, TEXT("Extend to the top zone"), NULL) \ 147 | LNGVALUE(InputActionXRZone, TEXT("Extend to the right zone"), NULL) \ 148 | LNGVALUE(InputActionXBZone, TEXT("Extend to the bottom zone"), NULL) \ 149 | LNGVALUE(InputActionXTNLEdge, TEXT("Extend to the next left edge"), NULL) \ 150 | LNGVALUE(InputActionXTNTEdge, TEXT("Extend to the next top edge"), NULL) \ 151 | LNGVALUE(InputActionXTNREdge, TEXT("Extend to the next right edge"), NULL) \ 152 | LNGVALUE(InputActionXTNBEdge, TEXT("Extend to the next bottom edge"), NULL) \ 153 | LNGVALUE(InputActionMTNLEdge, TEXT("Move to the next left edge"), NULL) \ 154 | LNGVALUE(InputActionMTNTEdge, TEXT("Move to the next top edge"), NULL) \ 155 | LNGVALUE(InputActionMTNREdge, TEXT("Move to the next right edge"), NULL) \ 156 | LNGVALUE(InputActionMTNBEdge, TEXT("Move to the next bottom edge"), NULL) \ 157 | LNGVALUE(InputActionStepL, TEXT("Step left"), NULL) \ 158 | LNGVALUE(InputActionStepT, TEXT("Step up"), NULL) \ 159 | LNGVALUE(InputActionStepR, TEXT("Step right"), NULL) \ 160 | LNGVALUE(InputActionStepB, TEXT("Step down"), NULL) \ 161 | LNGVALUE(InputActionSStepL, TEXT("Small step left"), NULL) \ 162 | LNGVALUE(InputActionSStepT, TEXT("Small step up"), NULL) \ 163 | LNGVALUE(InputActionSStepR, TEXT("Small step right"), NULL) \ 164 | LNGVALUE(InputActionSStepB, TEXT("Small step down"), NULL) \ 165 | LNGVALUE(InputActionFocusL, TEXT("Focus left window"), NULL) \ 166 | LNGVALUE(InputActionFocusT, TEXT("Focus top window"), NULL) \ 167 | LNGVALUE(InputActionFocusR, TEXT("Focus right window"), NULL) \ 168 | LNGVALUE(InputActionFocusB, TEXT("Focus bottom window"), NULL) \ 169 | LNGVALUE(InputActionRoll, TEXT("&Roll/Unroll window"), NULL) \ 170 | LNGVALUE(InputActionAlwaysOnTop, TEXT("Toggle always on &top"), NULL) \ 171 | LNGVALUE(InputActionBorderless, TEXT("Toggle &borderless"), NULL) \ 172 | LNGVALUE(InputActionCenter, TEXT("C&enter window on screen"), NULL) \ 173 | LNGVALUE(InputActionOriClick, TEXT("Send ori&ginal click"), NULL) \ 174 | LNGVALUE(InputActionNothing, TEXT("Nothing"), NULL) \ 175 | LNGVALUE(InputActionAltTab, TEXT("Alt+Tab"), NULL) \ 176 | LNGVALUE(InputActionVolume, TEXT("Volume"), NULL) \ 177 | LNGVALUE(InputActionMute, TEXT("Mute &sounds"), NULL) \ 178 | LNGVALUE(InputActionMenu, TEXT("Action menu"), NULL) \ 179 | LNGVALUE(InputActionMaximizeHV, TEXT("Maximize &Vertically"), NULL) \ 180 | LNGVALUE(InputActionSideSnap, TEXT("&Snap to monitor side/corner"), NULL) \ 181 | LNGVALUE(InputActionExtendSnap , TEXT("Extend to monitor side/corner"), NULL) \ 182 | LNGVALUE(InputActionExtendTNEdge, TEXT("Extend to next edge"), NULL) \ 183 | LNGVALUE(InputActionMoveTNEdge, TEXT("Move to next edge"), NULL) \ 184 | LNGVALUE(InputActionMinAllOther, TEXT("Minimize &other windows"), NULL) \ 185 | LNGVALUE(InputActionTransparency, TEXT("Transparency"), NULL) \ 186 | LNGVALUE(InputActionZoom, TEXT("Zoom window"), NULL) \ 187 | LNGVALUE(InputActionZoom2, TEXT("Zoom window 2"), NULL) \ 188 | LNGVALUE(InputActionHScroll, TEXT("Horizontal scroll"), NULL) \ 189 | \ 190 | LNGVALUE(InputHotkeysBox, TEXT("Hotkeys"), NULL) \ 191 | LNGVALUE(InputHotkeysModKey, TEXT("Modifier key for al&ternate action:"), NULL) \ 192 | LNGVALUE(InputHotclicksBox, TEXT("Hotclick (activate with a click)"), NULL) \ 193 | LNGVALUE(InputHotclicksMore, TEXT("A checked button can be combined with an action but it will always be blocked in this case."), NULL) \ 194 | LNGVALUE(InputHotkeysAlt, TEXT("Alt"), NULL) \ 195 | LNGVALUE(InputHotkeysWinkey, TEXT("Winkey"), NULL) \ 196 | LNGVALUE(InputHotkeysCtrl, TEXT("Ctrl"), NULL) \ 197 | LNGVALUE(InputHotkeysShift, TEXT("Shift"), NULL) \ 198 | LNGVALUE(InputHotkeysShortcuts, TEXT("S&hortcut for action:"), NULL) \ 199 | LNGVALUE(InputHotkeysShortcutsPick, TEXT("Pick &keys"), NULL) \ 200 | LNGVALUE(InputHotkeysShortcutsClear, TEXT("Clear ke&ys"), NULL) \ 201 | LNGVALUE(InputHotkeysShortcutsSet, TEXT("Sa&ve"), NULL) \ 202 | LNGVALUE(InputHotkeysUsePtWindow, TEXT("Apply to the &pointed window"), NULL) \ 203 | LNGVALUE(InputHotkeysLeftAlt, TEXT("L&eft Alt"), NULL) \ 204 | LNGVALUE(InputHotkeysRightAlt, TEXT("&Right Alt"), NULL) \ 205 | LNGVALUE(InputHotkeysLeftWinkey, TEXT("Left &Winkey"), NULL) \ 206 | LNGVALUE(InputHotkeysRightWinkey, TEXT("Right W&inkey"), NULL) \ 207 | LNGVALUE(InputHotkeysLeftCtrl, TEXT("&Left Ctrl"), NULL) \ 208 | LNGVALUE(InputHotkeysRightCtrl, TEXT("Ri&ght Ctrl"), NULL) \ 209 | LNGVALUE(InputHotkeysLeftShift, TEXT("Left Shift"), NULL) \ 210 | LNGVALUE(InputHotkeysRightShift, TEXT("Right Shift"), NULL) \ 211 | LNGVALUE(InputHotkeysMore, TEXT("You can add any key by editing the ini file.\nUse the shift key to snap windows to each other."), NULL) \ 212 | /* Blacklits Tab*/ \ 213 | LNGVALUE(BlacklistBox, TEXT("Blacklist settings"), NULL) \ 214 | LNGVALUE(BlacklistFormat, TEXT("exename.exe\r\ntitle|class\r\n*|class\r\nexename.exe:title|class"), NULL) \ 215 | LNGVALUE(BlacklistProcessBlacklist, TEXT("&Process blacklist:"), TEXT("Globally applies ie:\r\n*|Notepad, Photoshop.exe, explorer.exe*|#32770")) \ 216 | LNGVALUE(BlacklistBlacklist, TEXT("&Windows blacklist:"), NULL) \ 217 | LNGVALUE(BlacklistScrolllist, TEXT("Windows that should ignore &scroll action:"), NULL) \ 218 | LNGVALUE(BlacklistMDIs, TEXT("&MDIs not to be treated as such:"), NULL) \ 219 | LNGVALUE(BlacklistPause, TEXT("Processes not to be pa&used or killed:"), NULL) \ 220 | LNGVALUE(BlacklistFindWindowBox, TEXT("Identify window"), NULL) \ 221 | /* Advanced Tab */ \ 222 | LNGVALUE(AdvancedMetricsBox, TEXT("Metrics"), NULL) \ 223 | LNGVALUE(AdvancedCenterFraction, TEXT("&Center/Sides fraction (%):"), NULL) \ 224 | LNGVALUE(AdvancedAeroHoffset, TEXT("Aero offset(%) &Horizontal:"), NULL) \ 225 | LNGVALUE(AdvancedAeroVoffset, TEXT("&Vertical:"), NULL) \ 226 | LNGVALUE(AdvancedSnapThreshold, TEXT("&Snap Threshold (pixels):"), NULL) \ 227 | LNGVALUE(AdvancedAeroThreshold, TEXT("A&ero Threshold (pixels):"), NULL) \ 228 | LNGVALUE(AdvancedSnapGap, TEXT("Snapping &gap (pixels):"), NULL) \ 229 | LNGVALUE(AdvancedAeroSpeed, TEXT("Ma&x snapping speed (pixels):"), NULL) \ 230 | LNGVALUE(AdvancedTestWindow, TEXT("Test &Window"), NULL) \ 231 | LNGVALUE(AdvancedMoveTrans, TEXT("Opacit&y when moving:"), NULL) \ 232 | LNGVALUE(AdvancedBehaviorBox, TEXT("Behavior"), NULL) \ 233 | LNGVALUE(AdvancedMultipleInstances,TEXT("Allow multiple &instances of AltSnap"), NULL) \ 234 | LNGVALUE(AdvancedAutoRemaximize, TEXT("Automatically &remaximize windows when changing monitor"), NULL) \ 235 | LNGVALUE(AdvancedAeroTopMaximizes, TEXT("&Maximize windows snapped at top"), NULL) \ 236 | LNGVALUE(AdvancedAeroDBClickShift, TEXT("Invert shift &behavior for double-click aero snapping"), NULL) \ 237 | LNGVALUE(AdvancedMaxWithLClick, TEXT("&Toggle maximize state with the resize button while moving"), NULL) \ 238 | LNGVALUE(AdvancedRestoreOnClick, TEXT("Rest&ore window with single click like original AltDrag"), NULL) \ 239 | LNGVALUE(AdvancedFullScreen, TEXT("Enable on &full screen windows"), NULL) \ 240 | LNGVALUE(AdvancedBLMaximized, TEXT("&Disable AltSnap on Maximized windows"), NULL) \ 241 | LNGVALUE(AdvancedFancyZone, TEXT("Restore Fancy&Zones snapped windows"), NULL) \ 242 | LNGVALUE(AdvancedNoRestore, TEXT("Never restore AltSna&pped windows"), NULL) \ 243 | LNGVALUE(AdvancedTopmostIndicator, TEXT("Show an i&ndicator on always on top windows"), NULL) \ 244 | /* About Tab */ \ 245 | LNGVALUE(AboutBox, TEXT("About ") APP_NAME , NULL) \ 246 | LNGVALUE(AboutVersion, TEXT("Version ") TEXT( APP_VERSION ), NULL) \ 247 | LNGVALUE(AboutAuthor, TEXT("Created by Stefan Sundin"), NULL) \ 248 | LNGVALUE(AboutAuthor2, TEXT("Maintained by Raymond Gillibert"), NULL) \ 249 | LNGVALUE(AboutLicense, APP_NAME TEXT(" is free and open source software!\nFeel free to redistribute!"), NULL) \ 250 | LNGVALUE(AboutTranslationCredit, TEXT("Translation credit"), NULL) \ 251 | /* Misc */ \ 252 | LNGVALUE(MiscUnhookError, TEXT("There was an error disabling AltDrag. This was most likely caused by Windows having already disabled AltDrag's hooks.\n\nIf this is the first time this has happened, you can safely ignore it and continue using AltDrag.\n\nIf this is happening repeatedly, you can read on the website how to prevent this from happening again (look for 'AltDrag mysteriously stops working' in the documentation)."), NULL) \ 253 | LNGVALUE(MiscZoneConfirmation, TEXT("Erase old snap layout and save current Test Windows positions as the new snap layout?"), NULL) \ 254 | LNGVALUE(MiscZoneTestWinHelp, TEXT("To setup Snap layout:\n1) Open several of those Test Windows\n2) Dispose them as you please\n3) Hit the *&Save test windows as snap layout* option in the tray menu"), NULL) \ 255 | /* Extended character list for each virtual key */ \ 256 | LNGVALUE(a, TEXT("àáâäæãåª%āăąǎǟǡǣǻǽȁȃȧ|Ȧḁ%ⱥ|Ⱥɐ|Ɐɑ|Ɑɒ|Ɒⲁ|Ⲁⓐ"), NULL) \ 257 | LNGVALUE(b, TEXT("%ƀɓƃƅɃ%ɓḃḅḇⓑ"), NULL) \ 258 | LNGVALUE(c, TEXT("碩%ćĉċčƈḉȼ|Ȼɕⓒ"), NULL) \ 259 | LNGVALUE(d, TEXT("ð%ďđɖɗƌƍḋḍḏḑḓdžDždzDzȡȸⓓ"), NULL) \ 260 | LNGVALUE(e, TEXT("èéêë€%ēĕėęěǝəɛȅȇḕḗḙḛȩ|Ȩḝɇ|Ɇⱸⓔ"), NULL) \ 261 | LNGVALUE(f, TEXT("ƒ%ḟɸⱷⓕ%♩♪♮♭♯♬♫"), NULL) \ 262 | LNGVALUE(g, TEXT("%ǵǧḡɠɣǥⓖ"), NULL) \ 263 | LNGVALUE(h, TEXT("%ĥħƕǶḣḥḧḩḫȟ|Ȟⱨ|Ⱨⱶ|Ⱶẖⓗ"), NULL) \ 264 | LNGVALUE(i, TEXT("ìíîï%ĩīĭǐȉȋįİıijɩɨḭḯⓘ"), NULL) \ 265 | LNGVALUE(j, TEXT("%ĵǰȷɉ|Ɉⓙ"), NULL) \ 266 | LNGVALUE(k, TEXT("%ķĸƙǩḱḳⱪ|Ⱪꝁ|Ꝁʞ|Ʞⓚ"), NULL) \ 267 | LNGVALUE(l, TEXT("£%ĺļľŀłƛljLjȴƚ|Ƚⱡ|Ⱡɫ|Ɫḷḹḻḽⓛ"), NULL) \ 268 | LNGVALUE(m, TEXT("µ%ḿṁṃɱ|Ɱɯⓜ"), NULL) \ 269 | LNGVALUE(n, TEXT("ñ%ńņňʼnŋɲƞ|ȠnjNjǹȵ%ṅṇṉṋⓝ"), NULL) \ 270 | LNGVALUE(o, TEXT("òóôöœõø°%ōŏő%ɔɵơƣǒǫǭǿȍȏȣ|Ȣȫ|Ȫȭ|Ȭȯ|Ȯȱ|Ȱṍṏṑṓ%ⱺⓞ"), NULL) \ 271 | LNGVALUE(p, TEXT("¶þ·•%ƥᵽ|Ᵽṕṗⓟ"), NULL) \ 272 | LNGVALUE(q, TEXT("¿¤‰‘’“”„…–—«»‹›%ȹɋ|Ɋⓠ"), NULL) \ 273 | LNGVALUE(r, TEXT("®%ŕŗřƦȑȓṙṛṝṟɍ|Ɍɽ|Ɽⱹⓡ"), NULL) \ 274 | LNGVALUE(s, TEXT("šß§%śŝşſ%ƨʃƪș|Șȿ|Ȿ%ṡṣṥṧṩⓢ"), NULL) \ 275 | LNGVALUE(t, TEXT("†‡™%ţťŧƫƭʈț|Țȶⱦ|Ⱦ%ṫṭṯṱẗⓣ"), NULL) \ 276 | LNGVALUE(u, TEXT("ùúûü%ũūůŭűų%ưʊǔǖǘǚǜȕȗʉ|Ʉ%ṳṵṷṹṻⓤ"), NULL) \ 277 | LNGVALUE(v, TEXT("%ʋɅⱱⱴ%ṽṿⓥ"), NULL) \ 278 | LNGVALUE(w, TEXT("%ẁẃŵẅⱳ|Ⱳ%ẇẉⓦ"), NULL) \ 279 | LNGVALUE(x, TEXT("±×÷¬%ẋẍⓧ"), NULL) \ 280 | LNGVALUE(y, TEXT("ýÿ¥%ŷẏȳ|Ȳƴɏ|Ɏⓨ"), NULL) \ 281 | LNGVALUE(z, TEXT("ž%źẑżẓẕ%ƶʒƹƺǯȥ|Ȥɀ|Ɀⱬ|Ⱬⓩ"), NULL) 282 | 283 | 284 | #define LNGVALUE(x, y, z) TCHAR *x, *x##_T_T_; 285 | // String structure definition TCHAR *translation, *tooltip; 286 | struct strings { LANGUAGE_MAP }; 287 | #undef LNGVALUE 288 | 289 | #define LNGVALUE(x, y, z) #x, 290 | // Name of values ini entries 291 | static const char* l10n_inimapping[] = { LANGUAGE_MAP }; 292 | #undef LNGVALUE 293 | 294 | #define LNGVALUE(x, y, z) y, z, 295 | // Default values en-US 296 | static const struct strings en_US = { LANGUAGE_MAP }; 297 | #undef LANGVALUE 298 | 299 | #endif 300 | -------------------------------------------------------------------------------- /makerelease.bat: -------------------------------------------------------------------------------- 1 | if !%VERSION% == ! goto FAIL 2 | 3 | taskkill /IM AltSnap.exe 2> nul 4 | 5 | del AltSnap%version%bin_x64.zip 6 | del AltSnap%version%bin.zip 7 | del AltSnap%version%src.zip 8 | del AltSnap%version%bin.zip 9 | del AltSnap%version%-x64-inst.exe 10 | 11 | make -fMakefileX64 clean 12 | make -fMakefileX64 13 | call nsi.bat 14 | rename AltSnap%VERSION%-inst.exe AltSnap%VERSION%-x64-inst.exe 15 | 16 | call ziprelease.bat 17 | rename AltSnap_bin.zip AltSnap%version%bin_x64.zip 18 | 19 | make clean 20 | make 21 | call nsi.bat 22 | 23 | rhash --sha256 AltSnap%VERSION%-x64-inst.exe > SHA256.TXT 24 | rhash --sha256 AltSnap%VERSION%-inst.exe >> SHA256.TXT 25 | 26 | call ziprelease.bat 27 | rename AltSnap_bin.zip AltSnap%version%bin.zip 28 | 29 | call zzip.bat 30 | rename AltSnap_src.zip AltSnap%version%src.zip 31 | 32 | @GOTO END 33 | :FAIL 34 | @echo Error set the VERSION env variable! 35 | 36 | :END 37 | -------------------------------------------------------------------------------- /media/find.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/find.cur -------------------------------------------------------------------------------- /media/find.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/find.ico -------------------------------------------------------------------------------- /media/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/icon.ico -------------------------------------------------------------------------------- /media/tray-disabled.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/tray-disabled.ico -------------------------------------------------------------------------------- /media/tray-enabled.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/tray-enabled.ico -------------------------------------------------------------------------------- /media/tray-suspended.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/tray-suspended.ico -------------------------------------------------------------------------------- /media/tray-suspended2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RamonUnch/AltSnap/94ef1f796b402b611c67e5b5824c114a9e21f805/media/tray-suspended2.ico -------------------------------------------------------------------------------- /mk.bat: -------------------------------------------------------------------------------- 1 | @taskkill /IM AltSnap.exe 2> nul 2 | @taskkill /IM AltSnap.exe 2> nul 3 | 4 | make %1 5 | 6 | @if !%1 == !clean GOTO FINISH 7 | @start AltSnap.exe 8 | 9 | :FINISH 10 | -------------------------------------------------------------------------------- /mk64.bat: -------------------------------------------------------------------------------- 1 | @taskkill /IM AltSnap.exe 2> nul 2 | @taskkill /IM AltSnap.exe 2> nul 3 | 4 | @if !%1 == !db GOTO DEBUG 5 | 6 | make -fMakefileX64 %1 7 | 8 | @if !%1 == !clean GOTO FINISH 9 | @start AltSnap.exe 10 | @GOTO FINISH 11 | 12 | : DEBUG 13 | @echo x86_64b Debug build 14 | make -fMakefileX64db 15 | gdb.exe AltSnap.exe 16 | 17 | :FINISH 18 | -------------------------------------------------------------------------------- /mkvcc6.bat: -------------------------------------------------------------------------------- 1 | rc hooks.rc 2 | rc altsnap.rc 3 | 4 | @set DEFINES=/D "DWORD_PTR=DWORD" /D "LONG_PTR=INT_PTR" /D "ULONG_PTR=DWORD" 5 | @set DEFINES= %DEFINES% /D "NO_VISTA" /D "NO_OLEAPI" /D "DECORATED_HOOKS_DLL_PROCS" 6 | 7 | cl /c /Tp altsnap.c /nologo /Ox /Oi /Os /Gy %DEFINES% 8 | 9 | link altsnap.obj altsnap.res /nodefaultlib /filealign:512 /subsystem:windows /OPT:REF /OPT:ICF,7 /LARGEADDRESSAWARE /machine:I386 /entry:unfuckWinMain kernel32.lib user32.lib shell32.lib advapi32.lib gdi32.lib comctl32.lib 10 | 11 | cl /c /Tp hooks.c /nologo /Ox /Oi /Os /Gy /GS- /LD %DEFINES% 12 | 13 | link hooks.obj hooks.res /nodefaultlib /DLL /filealign:512 /subsystem:windows /OPT:REF /OPT:ICF,7 /LARGEADDRESSAWARE /machine:I386 /entry:DllMain kernel32.lib user32.lib gdi32.lib 14 | 15 | @set DEFINES= 16 | -------------------------------------------------------------------------------- /nanolibc.h: -------------------------------------------------------------------------------- 1 | #ifndef NANOLIBC_H 2 | #define NANOLIBC_H 3 | 4 | #include 5 | 6 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && !defined(__WATCOMC__) 7 | // C99+ mode but not buggy watcom C99 8 | #define AT_LEAST static 9 | #else 10 | #define AT_LEAST 11 | #endif 12 | 13 | #ifdef __GNUC__ 14 | #define flatten __attribute__((flatten)) 15 | #define xpure __attribute__((const)) 16 | #define pure __attribute__((pure)) 17 | #define noreturn __attribute__((noreturn)) 18 | #define fastcall __attribute__((fastcall)) 19 | #define ainline __attribute__((always_inline)) 20 | #define mallocatrib __attribute__((malloc, freeL)) 21 | #define allnonnull __attribute__((nonnull)) 22 | #define nonnull1(x) __attribute__((nonnull (x))) 23 | #define nonnull2(x, y) __attribute__((nonnull (x, y))) 24 | #define ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0) 25 | #define UNREACHABLE() __builtin_unreachable() 26 | #else 27 | #define flatten 28 | #define xpure 29 | #define pure 30 | #define noreturn 31 | #define fastcall 32 | #define ainline 33 | #define mallocatrib 34 | #define allnonnull 35 | #define nonnull1(x) 36 | #define nonnull2(x, y) 37 | #define __restrict__ 38 | #define inline 39 | #define ASSUME(x) 40 | #define UNREACHABLE() 41 | #endif 42 | /* return +/-1 if x is +/- and 0 if x == 0 */ 43 | static xpure int sign(int x) 44 | { 45 | return (x > 0) - (x < 0); 46 | } 47 | 48 | //#if defined(__GNUC__) && (defined(__i386__) && !defined(__x86_64__)) && !defined(CLANG) 49 | //static __attribute__(( regparm(1) )) xpure 50 | //int Iabs(int x) 51 | //{ 52 | // __asm__ ( 53 | // "cdq \n" 54 | // "xor %%edx, %%eax \n" 55 | // "sub %%edx, %%eax \n" 56 | // : "=eax" (x) 57 | // : "eax" (x) 58 | // : "%edx" 59 | // ); 60 | // return x; 61 | //} 62 | //#define abs(x) Iabs(x) 63 | //#else 64 | //#define abs(x) ((x)>0? (x): -(x)) 65 | //#endif // x86 66 | 67 | #define abs(x) ((x)>0? (x): -(x)) 68 | /* Function to set the kth bit of n */ 69 | static int setBit(int n, int k) 70 | { 71 | return (n | (1 << (k))); 72 | } 73 | 74 | /* Function to clear the kth bit of n */ 75 | static int clearBit(int n, int k) 76 | { 77 | return (n & (~(1 << (k)))); 78 | } 79 | 80 | /* Function to toggle the kth bit of n */ 81 | static int toggleBit(int n, int k) 82 | { 83 | return (n ^ (1 << (k))); 84 | } 85 | 86 | static void str2tchar(TCHAR *w, const char *s) 87 | { 88 | while((*w++ = *s++)); 89 | } 90 | 91 | static void str2tchar_s(TCHAR *w, size_t N, const char *s) 92 | { 93 | const TCHAR *wmax = w + N-1; 94 | while(w < wmax && (*w++ = *s++)); 95 | } 96 | 97 | static void mem00(void *dst, size_t count) 98 | { 99 | register char * a = (char *)dst; 100 | while (count--) 101 | *a++ = 0; 102 | } 103 | 104 | #ifdef CLANG 105 | 106 | void * __cdecl memset(void *dst, int s, size_t count) 107 | { 108 | register char * a = dst; 109 | count++; 110 | while (--count) 111 | *a++ = s; 112 | return dst; 113 | } 114 | /* in case */ 115 | __cdecl size_t strlen(const char *str) 116 | { 117 | const char *ptr; 118 | for (ptr=str; *ptr != '\0'; ptr++); 119 | return ptr-str; 120 | } 121 | void * __cdecl memcpy(void *dst, const void * __restrict__ src, size_t n) 122 | { 123 | size_t i; 124 | char *d = (char *)dst; 125 | const char *s = (char *)src; 126 | 127 | for (i=0; i 9)? (rem-10) + 'A' : rem + '0'; */ 244 | str[i++] = rem + '0' + (rem > 9) * ('A' - '0' - 10); /* branchless version */ 245 | 246 | num = num/base; 247 | } 248 | 249 | /* If number is negative, append '-' */ 250 | if (isNegative) 251 | str[i++] = '-'; 252 | 253 | str[i] = '\0'; /* Append string terminator */ 254 | 255 | /* Reverse the string */ 256 | reverseW(str, i); 257 | 258 | return str; 259 | } 260 | #define _itow itowL 261 | static nonnull1(1) inline void reverseA(char *str, int length) 262 | { 263 | int start = 0; 264 | int end = length -1; 265 | while (start < end) { 266 | char tmp; 267 | tmp = str[start]; 268 | str[start] = str[end]; 269 | str[end] = tmp; 270 | start++; 271 | end--; 272 | } 273 | } 274 | static nonnull1(2) char *itoaL(unsigned num, char *str, int base) 275 | { 276 | int i = 0; 277 | int isNegative = 0; 278 | 279 | /* Handle 0 explicitely */ 280 | if (num == 0) { 281 | str[i++] = '0'; 282 | str[i] = '\0'; 283 | return str; 284 | } 285 | 286 | /* In standard itoa(), negative numbers are handled only with 287 | * base 10. Otherwise numbers are considered unsigned. */ 288 | if ((int)num < 0 && base == 10) { 289 | isNegative = 1; 290 | num = -(int)num; 291 | } 292 | 293 | /* Process individual digits */ 294 | while (num != 0) { 295 | int rem = num % base; 296 | str[i++] = (rem > 9)? (rem-10) + 'A' : rem + '0'; 297 | /* str[i++] = rem + '0' + (rem > 9) * ('A' - '0' - 10);*//* branchless version */ 298 | 299 | num = num/base; 300 | } 301 | 302 | /* If number is negative, append '-' */ 303 | if (isNegative) 304 | str[i++] = '-'; 305 | 306 | str[i] = '\0'; /* Append string terminator */ 307 | 308 | /* Reverse the string */ 309 | reverseA(str, i); 310 | 311 | return str; 312 | } 313 | #define _itoa itoaL 314 | 315 | #define INT_DIGITS 11 316 | #define UINT_DIGITS 10 317 | static const TCHAR *Int2lStr(TCHAR str[AT_LEAST INT_DIGITS+1], int n) 318 | { 319 | int i = 0; 320 | BOOL minus; 321 | minus = (n<0); 322 | str[INT_DIGITS] = TEXT('\0'); 323 | 324 | for( i=INT_DIGITS-1; ; --i ) 325 | { 326 | str[i] = TEXT('0') + (minus ? -1*(n%10) : n%10); 327 | n /= 10; 328 | if( n==0 ) 329 | break; 330 | } 331 | 332 | if( minus ) 333 | str[--i] = TEXT('-'); 334 | 335 | return str+i; 336 | } 337 | 338 | static const wchar_t *Uint2lStrW(wchar_t str[AT_LEAST UINT_DIGITS+1], unsigned n) 339 | { 340 | int i = 0; 341 | str[UINT_DIGITS] = TEXT('\0'); 342 | 343 | for( i=UINT_DIGITS-1; ; --i ) 344 | { 345 | str[i] = TEXT('0') + (wchar_t)(n%10); 346 | if( n < 10 ) 347 | break; 348 | n /= 10; 349 | } 350 | 351 | return str+i; 352 | } 353 | static const char *Uint2lStrA(char str[AT_LEAST UINT_DIGITS+1], unsigned n) 354 | { 355 | int i = 0; 356 | str[UINT_DIGITS] = TEXT('\0'); 357 | 358 | for( i=UINT_DIGITS-1; ; --i ) 359 | { 360 | str[i] = TEXT('0') + (char)(n%10); 361 | if( n < 10 ) 362 | break; 363 | n /= 10; 364 | } 365 | 366 | return str+i; 367 | } 368 | 369 | #ifdef WIN64 370 | #define LPTR_HDIGITS 16 371 | #else 372 | #define LPTR_HDIGITS 8 373 | #endif 374 | static const TCHAR *LPTR2Hex(TCHAR str[AT_LEAST LPTR_HDIGITS+1], UINT_PTR n) 375 | { 376 | int i = 0; 377 | str[LPTR_HDIGITS] = TEXT('\0'); 378 | 379 | for( i=LPTR_HDIGITS-1; ; --i ) 380 | { 381 | TCHAR rem = n & 15; // MD 16 382 | str[i] = (rem > 9)? (rem-10) + 'A' : rem + '0'; 383 | /*str[i++] = rem + '0' + (rem > 9) * ('A' - '0' - 10); *//* branchless version */ 384 | 385 | n >>=4 ; // Divide by 16. 386 | if (n==0) 387 | break; 388 | } 389 | 390 | return str+i; 391 | } 392 | 393 | 394 | static allnonnull pure size_t wcslenL(const wchar_t *__restrict__ const str) 395 | { 396 | const wchar_t *ptr; 397 | for (ptr=str; *ptr != '\0'; ptr++); 398 | return ptr-str; 399 | } 400 | #define wcslen wcslenL 401 | 402 | static allnonnull pure size_t strlenL(const char * const str) 403 | { 404 | const char *ptr; 405 | for (ptr=str; *ptr != '\0'; ptr++); 406 | return ptr-str; 407 | } 408 | 409 | static int pure allnonnull wcscmpL(const wchar_t *__restrict__ a, const wchar_t *__restrict__ b) 410 | { 411 | while(*a && *a == *b) { a++; b++; } 412 | return *a - *b; 413 | } 414 | #define wcscmp wcscmpL 415 | 416 | /* Reverse of the next function */ 417 | static nonnull1(1) pure int lstrcmp_rstar(const TCHAR *__restrict__ a, const TCHAR *__restrict__ b) 418 | { 419 | const TCHAR *oa = a, *ob=b; 420 | if(!b) return 0; 421 | 422 | while(*a++) ; 423 | a--; 424 | while(*b++) ; 425 | b--; 426 | if(*ob != '*' && a-oa != b-ob) 427 | return 1; 428 | 429 | while(a > oa && b > ob && *a == *b) { a--; b--; } 430 | 431 | return (*a != *b) & (*b != '*'); 432 | } 433 | /* stops comp at the '*' in the b param. 434 | * this is a kind of mini regexp that has no performance hit. 435 | * It also returns 0 (equal) if the b param is NULL */ 436 | static nonnull1(1) pure int lstrcmp_star(const TCHAR *__restrict__ a, const TCHAR *__restrict__ b) 437 | { 438 | if(!b) return 0; 439 | if(*b == L'*') return lstrcmp_rstar(a, b); 440 | 441 | while(*a && *a == *b) { a++; b++; } 442 | return (*a != *b) & (*b != '*'); 443 | } 444 | #define tolower(x) ( (x) | ('A'<(x) && (x)<'Z') << 5 ) 445 | #define tolowerevil(x) ( (x) | 1 << 5 ) 446 | 447 | /* Returns 0 if both strings start the same */ 448 | static nonnull1(1) int pure lstrcmpi_samestart(const TCHAR *__restrict__ a, const TCHAR *__restrict__ b) 449 | { 450 | while(*a && tolower(*a) == tolower(*b)) { a++; b++; } 451 | return (*a != *b) && (*b != '\0'); 452 | } 453 | 454 | static allnonnull int pure lstrcmp_samestart(const TCHAR *__restrict__ a, const TCHAR *__restrict__ b) 455 | { 456 | while(*a && *a == *b) { a++; b++; } 457 | return (*a != *b) && (*b != '\0'); 458 | } 459 | 460 | static allnonnull wchar_t *wcscpyL(wchar_t *__restrict__ dest, const wchar_t *__restrict__ in) 461 | { 462 | wchar_t *ret = dest; 463 | while ((*dest++ = *in++)); 464 | return ret; 465 | } 466 | #define wcscpy wcscpyL 467 | 468 | static nonnull2(1,2) wchar_t *wcsncpyL(wchar_t *__restrict__ dest, const wchar_t *__restrict__ src, size_t n) 469 | { 470 | wchar_t *orig = dest; 471 | for (; dest < orig+n && (*dest=*src); ++src, ++dest) ; 472 | for (; dest < orig+n; ++dest) *dest=0; 473 | return orig; 474 | } 475 | #define wcsncpy wcsncpyL 476 | 477 | static allnonnull char *strcpyL(char *__restrict__ dest, const char *__restrict__ in) 478 | { 479 | char *ret = dest; 480 | while ((*dest++ = *in++)); 481 | return ret; 482 | } 483 | #define strcpy strcpyL 484 | 485 | static allnonnull pure int stricmpL(const char* s1, const char* s2) 486 | { 487 | unsigned x1, x2; 488 | 489 | while (1) { 490 | x2 = *s2 - 'A'; 491 | x2 |= (x2 < 26u) << 5; /* Add 32 if UPPERCASE. */ 492 | 493 | x1 = *s1 - 'A'; 494 | x1 |= (x1 < 26u) << 5; 495 | 496 | s1++; s2++; 497 | if (x2 != x1) 498 | break; 499 | if (x1 == (unsigned)-'A') 500 | break; 501 | } 502 | return x1 - x2; 503 | } 504 | #define stricmp stricmpL 505 | 506 | static allnonnull pure int wcsicmpL(const wchar_t* s1, const wchar_t* s2) 507 | { 508 | unsigned x1, x2; 509 | 510 | while (1) { 511 | x2 = *s2 - 'A'; 512 | x2 |= (x2 < 26u) << 5; /* Add 32 if UPPERCASE. */ 513 | 514 | x1 = *s1 - 'A'; 515 | x1 |= (x1 < 26u) << 5; 516 | 517 | s1++; s2++; 518 | if (x2 != x1) 519 | break; 520 | if (x1 == (unsigned)-'A') 521 | break; 522 | } 523 | return x1 - x2; 524 | } 525 | #define wcsicmp wcsicmpL 526 | 527 | static allnonnull pure int strtotcharicmp(const TCHAR* s1, const char* s2) 528 | { 529 | unsigned x1, x2; 530 | 531 | while (1) { 532 | x2 = *s2 - 'A'; 533 | x2 |= (x2 < 26u) << 5; /* Add 32 if UPPERCASE. */ 534 | 535 | x1 = *s1 - 'A'; 536 | x1 |= (x1 < 26u) << 5; 537 | 538 | s1++; s2++; 539 | if (x2 != x1) 540 | break; 541 | if (x1 == (unsigned)-'A') 542 | break; 543 | } 544 | return x1 - x2; 545 | } 546 | 547 | allnonnull wchar_t *wcscatL(wchar_t *__restrict__ dest, const wchar_t *__restrict__ src) 548 | { 549 | wchar_t *orig=dest; 550 | for (; *dest; ++dest) ; /* go to end of dest */ 551 | for (; (*dest=*src); ++src,++dest) ; /* then append from src */ 552 | return orig; 553 | } 554 | allnonnull char *strcatL(char *__restrict__ dest, const char *__restrict__ src) 555 | { 556 | char *orig=dest; 557 | for (; *dest; ++dest) ; /* go to end of dest */ 558 | for (; (*dest=*src); ++src,++dest) ; /* then append from src */ 559 | return orig; 560 | } 561 | 562 | static nonnull2(1,3) char *strcat_sL(char *__restrict__ dest, const size_t N, const char *__restrict__ src) 563 | { 564 | char *orig=dest; 565 | const char *dmax=dest+N-1; /* keep space for a terminating NULL */ 566 | for (; dest= '0' && c <= '9') return c - '0'; 663 | else if (c >= 'A' && c <= 'F') return c-'A'+10; 664 | else if (c >= 'a' && c <= 'f') return c-'a'+10; 665 | else return 0; 666 | } 667 | 668 | static pure int IsSeparator(TCHAR c) 669 | { 670 | return c <= '0'; 671 | } 672 | /* stops at the end of the string or at a any char before '0' */ 673 | static allnonnull pure unsigned lstrhex2u(const TCHAR *s) 674 | { 675 | unsigned ret=0; 676 | while(*s >= '0') 677 | ret = ret << 4 | h2u(*s++) ; 678 | 679 | return ret; 680 | } 681 | 682 | static void *reallocL(void *mem, size_t sz) 683 | { 684 | // if (rand()%256 < 200) return NULL; 685 | if(!mem) return HeapAlloc(GetProcessHeap(), 0, sz); 686 | return HeapReAlloc(GetProcessHeap(), 0, mem, sz); 687 | } 688 | #define realloc reallocL 689 | 690 | static mallocatrib void *mallocL(size_t sz) 691 | { 692 | // if (rand()%256 < 200) return NULL; 693 | return HeapAlloc(GetProcessHeap(), 0, sz); 694 | } 695 | #define malloc mallocL 696 | 697 | static mallocatrib void *callocL(size_t sz, size_t mult) 698 | { 699 | return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz*mult); 700 | } 701 | #define calloc callocL 702 | 703 | static BOOL freeL(void *mem) 704 | { 705 | if(mem) return HeapFree(GetProcessHeap(), 0, mem); 706 | return FALSE; 707 | } 708 | #define free freeL 709 | 710 | #endif 711 | -------------------------------------------------------------------------------- /nsi.bat: -------------------------------------------------------------------------------- 1 | "%PROGRAMFILES%\nsis-2.51\makensis.exe" /V2 AltSnap.nsi 2 | -------------------------------------------------------------------------------- /oldmk64.bat: -------------------------------------------------------------------------------- 1 | @set WARNINGS=-Wall -Wformat-security -Wstrict-overflow -Wsign-compare -Wclobbered -Wempty-body -Wignored-qualifiers -Wuninitialized -Wtype-limits -Woverride-init -Wlogical-op 2 | 3 | @set CFLAGS=-Os -m64 -momit-leaf-frame-pointer -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-stack-check -fno-stack-protector -lkernel32 -lmsvcrt -luser32 -lgdi32 -flto -Wl,-dynamicbase,-nxcompat,--no-seh -s -Wp,-D_FORTIFY_SOURCE=2 4 | 5 | :: -finline-functions-called-once 6 | :: -Wunused-parameter 7 | :: -nostdlib 8 | :: -Wduplicated-cond -Wduplicated-branches -Wnull-dereference 9 | 10 | @taskkill /IM AltSnap.exe 2> nul 11 | 12 | @ECHO WINDRES ALTDRAG.RC 13 | @windres altsnap.rc altsnapr.o 14 | 15 | @ECHO WINDRES HOOKS.RC 16 | @windres hooks.rc hooksr.o 17 | 18 | @ECHO CC ALTSNAP.EXE 19 | @gcc -o AltSnap.exe altsnap.c altsnapr.o %CFLAGS% -lcomctl32 -mwindows -ladvapi32 -lshell32 20 | 21 | @ECHO CC HOOKS.DLL 22 | @gcc -o hooks.dll hooks.c hooksr.o -nostdlib %CFLAGS% -mdll -D__USE_MINGW_ANSI_STDIO=0 -eDllMain 23 | 24 | @set CFLAGS= 25 | 26 | @start AltSnap.exe 27 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | #ifndef AS_RESOURCE_H 2 | #define AS_RESOURCE_H 3 | 4 | #ifndef IDC_STATIC 5 | #define IDC_STATIC (-1) 6 | #endif 7 | 8 | #define VERSIONRC 1,6,5,0 9 | #define APP_VERSION "1.65" 10 | 11 | #define APP_ICON 101 12 | #define TRAY_OFF 102 13 | #define TRAY_ON 103 14 | #define TRAY_SUS 104 15 | 16 | #define IDD_GENERALPAGE 201 17 | #define IDD_MOUSEPAGE 202 18 | #define IDD_KBPAGE 203 19 | #define IDD_BLACKLISTPAGE 204 20 | #define IDD_ADVANCEDPAGE 205 21 | #define IDD_ABOUTPAGE 206 22 | 23 | #define IDI_FIND 301 24 | #define IDI_BIGICON 302 25 | #define IDC_HELPPANNEL 303 26 | 27 | #define IDC_AUTOSNAP_HEADER 1000 28 | #define IDC_FINDWINDOW 1000 29 | #define IDC_CHECKNOW 1001 30 | #define IDC_LANGUAGE_HEADER 1001 31 | #define IDC_TTBACTIONSNA 1001 32 | #define IDC_TRANSLATIONS_BOX 1001 33 | #define IDC_INI 1002 34 | #define IDC_NEWRULE 1002 35 | #define IDC_MDI 1003 36 | #define IDC_SCROLL 1003 37 | #define IDC_TRANSLATIONS 1003 38 | #define IDC_AUTOSAVE 1004 39 | #define IDC_PROCESSBLACKLIST_HEADER 1004 40 | #define IDC_SCROLL_HEADER 1004 41 | #define IDC_AUTOSTART_ELEVATE 1005 42 | #define IDC_BLACKLIST_HEADER 1006 43 | #define IDC_ELEVATE 1006 44 | #define IDC_LMB_HEADER 1006 45 | #define IDC_MMB_HEADER 1007 46 | #define IDC_RMB_HEADER 1008 47 | #define IDC_CHECKONSTARTUP 1009 48 | #define IDC_MB4_HEADER 1009 49 | #define IDC_BETA 1010 50 | #define IDC_MB5_HEADER 1010 51 | #define IDC_FINDWINDOW_BOX 1012 52 | #define IDC_HOTKEYS_MORE 1013 53 | #define IDC_BLACKLIST_BOX 1014 54 | #define IDC_SCROLLLIST_HEADER 1015 55 | #define IDC_BLACKLIST_EXPLANATION 1016 56 | #define IDC_ADVANCED_BOX 1017 57 | #define IDC_GENERAL_BOX 1018 58 | #define IDC_AUTOSTART_BOX 1019 59 | #define IDC_AUTOFOCUS 1101 60 | #define IDC_AUTOSNAP 1102 61 | #define IDC_AERO 1103 62 | #define IDC_INACTIVESCROLL 1104 63 | #define IDC_LANGUAGE 1105 64 | #define IDC_LMB 1201 65 | #define IDC_MMB 1202 66 | #define IDC_RMB 1203 67 | #define IDC_MB4 1204 68 | #define IDC_MB5 1205 69 | #define IDC_LEFTALT 1206 70 | #define IDC_RIGHTALT 1207 71 | #define IDC_LEFTWINKEY 1208 72 | #define IDC_RIGHTWINKEY 1209 73 | #define IDC_LEFTCTRL 1210 74 | #define IDC_RIGHTCTRL 1211 75 | #define IDC_HOOKWINDOWS 1401 76 | #define IDC_OPENINI 1402 77 | #define IDC_DONATE 1501 78 | #define IDC_SCROLLLIST 1505 79 | #define IDC_BLACKLIST 1506 80 | #define IDC_PROCESSBLACKLIST 1507 81 | #define IDC_AUTOSTART 1508 82 | #define IDC_AUTOSTART_HIDE 1511 83 | #define IDC_MOUSE_BOX 1511 84 | #define IDC_HOTKEYS_BOX 1512 85 | #define IDC_FINDWINDOW_EXPLANATION 1513 86 | #define IDC_ABOUT_BOX 1514 87 | #define IDC_VERSION 1515 88 | #define IDC_AUTHOR 1516 89 | #define IDC_LICENSE 1517 90 | #define IDC_URL 1518 91 | #define IDC_NEWPROGNAME 1519 92 | #define IDC_HOTCLICKS_BOX 1520 93 | #define IDC_AUTHOR2 1521 94 | 95 | #define IDC_MBA1 1601 96 | #define IDC_MBA2 1602 97 | #define IDC_INTTB 1603 98 | #define IDC_WHILEM 1604 99 | #define IDC_WHILER 1605 100 | 101 | #define IDC_FULLWIN 2008 102 | #define IDC_SHOWCURSOR 2009 103 | #define IDC_RESIZECENTER 2010 104 | #define IDC_RESIZEALL 2011 105 | 106 | #define IDC_AGGRESSIVEPAUSE 2012 107 | #define IDC_PAUSEBL_HEADER 2013 108 | #define IDC_PAUSEBL 2014 109 | #define IDC_MDISBL_HEADER 2015 110 | #define IDC_MDIS 2016 111 | 112 | #define IDC_RZCENTER_NORM 2017 113 | #define IDC_RZCENTER_BR 2018 114 | #define IDC_RZCENTER_MOVE 2019 115 | #define IDC_RZCENTER_CLOSE 2020 116 | 117 | #define IDC_AUTOREMAXIMIZE 2021 118 | #define IDC_AEROTOPMAXIMIZES 2022 119 | #define IDC_MULTIPLEINSTANCES 2023 120 | #define IDC_CENTERFRACTION 2024 121 | #define IDC_CENTERFRACTION_H 2025 122 | #define IDC_AEROHOFFSET 2026 123 | #define IDC_AEROHOFFSET_H 2027 124 | #define IDC_AEROVOFFSET 2028 125 | #define IDC_AEROVOFFSET_H 2029 126 | #define IDC_SNAPTHRESHOLD 2030 127 | #define IDC_SNAPTHRESHOLD_H 2031 128 | #define IDC_AEROTHRESHOLD 2032 129 | #define IDC_AEROTHRESHOLD_H 2033 130 | #define IDC_NORMRESTORE 2034 131 | #define IDC_MAXWITHLCLICK 2035 132 | #define IDC_RESTOREONCLICK 2036 133 | #define IDC_TTBACTIONSWA 2037 134 | #define IDC_MMB_HC 2038 135 | #define IDC_MB4_HC 2039 136 | #define IDC_MB5_HC 2040 137 | #define IDC_KEYBOARD_BOX 2041 138 | #define IDC_KEYCOMBO 2042 139 | #define IDC_HOTCLICKS_MORE 2043 140 | #define IDC_GRABWITHALT 2044 141 | #define IDC_GRABWITHALT_H 2045 142 | #define IDC_METRICS_BOX 2046 143 | #define IDC_BEHAVIOR_BOX 2047 144 | #define IDC_MODKEY_H 2048 145 | #define IDC_MODKEY 2049 146 | #define IDC_AERODBCLICKSHIFT 2050 147 | #define IDC_FULLSCREEN 2051 148 | #define IDC_AGGRESSIVEKILL 2052 149 | #define IDC_TESTWINDOW 2053 150 | #define IDC_MOVETRANS_H 2054 151 | #define IDC_MOVETRANS 2055 152 | #define IDC_AEROSPEED_H 2056 153 | #define IDC_AEROSPEED 2057 154 | #define IDC_AEROSPEEDTAU 2058 155 | #define IDC_SMARTAERO 2059 156 | #define IDC_STICKYRESIZE 2060 157 | #define IDC_NCHITTEST 2061 158 | #define IDC_GWLSTYLE 2062 159 | #define IDC_HSCROLL 2063 160 | #define IDC_HSCROLL_HEADER 2064 161 | #define IDC_SCROLLLOCKSTATE 2065 162 | #define IDC_TITLEBARMOVE 2066 163 | #define IDC_GRABWITHALTB 2067 164 | #define IDC_GRABWITHALTB_H 2068 165 | #define IDC_RECT 2069 166 | #define IDC_TTBACTIONS_BOX 2070 167 | #define IDC_PEARCEDBCLICK 2071 168 | 169 | #define IDC_USEZONES 2072 170 | #define IDC_FANCYZONE 2073 171 | #define IDC_GWLEXSTYLE 2074 172 | #define IDC_SMARTERAERO 2075 173 | #define IDC_NORESTORE 2076 174 | #define IDC_LONGCLICKMOVE 2077 175 | #define IDC_BLMAXIMIZED 2078 176 | #define IDC_PIERCINGCLICK 2079 177 | 178 | #define IDC_OUTTB 2083 179 | #define IDC_UNIKEYHOLDMENU 2084 180 | #define IDC_DWMCAPBUTTON 2085 181 | #define IDC_WINHANDLES 2086 182 | 183 | #define IDC_MOVEUP 2087 184 | #define IDC_MOVEUP_HEADER 2088 185 | #define IDC_RESIZEUP 2089 186 | #define IDC_RESIZEUP_HEADER 2090 187 | #define IDC_SNAPGAP 2091 188 | #define IDC_SNAPGAP_H 2092 189 | #define IDC_NPSTACKED 2093 190 | #define IDC_TOPMOSTINDICATOR 2094 191 | 192 | #define IDC_SHORTCUTS 2095 193 | #define IDC_SHORTCUTS_H 2096 194 | #define IDC_SHORTCUTS_AC 2097 195 | #define IDC_SHORTCUTS_SET 2098 196 | #define IDC_SHORTCUTS_PICK 2099 197 | #define IDC_ALT 2100 198 | #define IDC_WINKEY 2101 199 | #define IDC_CONTROL 2102 200 | #define IDC_SHIFT 2103 201 | #define IDC_SHORTCUTS_VK 2104 202 | #define IDC_SHORTCUTS_CLEAR 2105 203 | #define IDC_USEPTWINDOW 2106 204 | #define IDC_SIDESFRACTION 2107 205 | 206 | #endif // AS_RESOURCE_H 207 | -------------------------------------------------------------------------------- /sch_Off.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: Check for elevation 3 | fsutil dirty query %systemdrive% >nul 2>&1 4 | if '%errorlevel%' NEQ '0' ( 5 | :: Not elevated, so relaunch using vbscript 6 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 7 | echo UAC.ShellExecute "cmd.exe", "/c ""%~f0"" %*", "", "runas", 1 >> "%temp%\getadmin.vbs" 8 | "%temp%\getadmin.vbs" 9 | del "%temp%\getadmin.vbs" 10 | exit /b 11 | ) 12 | 13 | setlocal 14 | 15 | :: ============================================================================= 16 | :: = This batch will remove the AltSnap's Scheduled task! = 17 | :: = If you do not want to continue, close the window or hit Ctrl+C = 18 | :: ============================================================================= 19 | 20 | echo ============================================================================= 21 | echo = This batch will remove the AltSnap's Scheduled task! = 22 | echo = If you do not want to continue, close the window or hit Ctrl+C = 23 | echo ============================================================================= 24 | 25 | echo. 26 | echo Going to run command: 27 | echo schtasks.exe /DELETE /TN "AltSnap" %1 %2 %3 %4 %5 %6 %7 %8 %9 28 | echo. 29 | 30 | set /p "choice=Are you sure you want to delete the AltSnap scheduled task? [Y/n]: " 31 | 32 | :: Handle empty input (user just pressed Enter) as "Y" 33 | if "%choice%"=="" ( 34 | set "choice=y" 35 | ) 36 | 37 | if /i "%choice%" equ "y" ( 38 | echo Deleting the AltSnap scheduled task... 39 | schtasks.exe /DELETE /TN "AltSnap" %1 %2 %3 %4 %5 %6 %7 %8 %9 /F 40 | ) else ( 41 | echo Deletion cancelled. 42 | ) 43 | 44 | pause 45 | exit /b 0 46 | -------------------------------------------------------------------------------- /sch_On.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: Check for elevation 3 | fsutil dirty query %systemdrive% >nul 2>&1 4 | if '%errorlevel%' NEQ '0' ( 5 | :: Not elevated, so relaunch using vbscript 6 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 7 | echo UAC.ShellExecute "cmd.exe", "/c ""%~f0"" %*", "", "runas", 1 >> "%temp%\getadmin.vbs" 8 | "%temp%\getadmin.vbs" 9 | del "%temp%\getadmin.vbs" 10 | exit /b 11 | ) 12 | 13 | setlocal 14 | 15 | :: ============================================================================= 16 | :: = Setup Scheduled task for elevated AltSnap auto-start without UAC prompt = 17 | :: = Make sure you are running this from an elevated shell = 18 | :: = Default AltSnap executable location is %%APPDATA%%\AltSnap\AltSnap.exe = 19 | :: = Adjust the executable location in the AltSnap.xml file if AltSnap is = 20 | :: = installed in a different location = 21 | :: = If you do not want to continue, close the window or hit Ctrl+C = 22 | :: ============================================================================= 23 | 24 | echo ============================================================================= 25 | echo = Setup Scheduled task for elevated AltSnap auto-start without UAC prompt = 26 | echo = Make sure you are running this from an elevated shell = 27 | echo = Default AltSnap executable location is %%APPDATA%%\AltSnap\AltSnap.exe = 28 | echo = Adjust the executable location in the AltSnap.xml file if AltSnap is = 29 | echo = installed in a different location = 30 | echo = If you do not want to continue, close the window or hit Ctrl+C = 31 | echo ============================================================================= 32 | 33 | set "AltSnapXML=%APPDATA%\AltSnap\AltSnap.xml" 34 | set "AltSnapExe=%APPDATA%\AltSnap\AltSnap.exe" 35 | 36 | :: Check if AltSnap.exe exists 37 | if not exist "%AltSnapExe%" ( 38 | echo. 39 | echo AltSnap executable not found in the default location: %AltSnapExe% 40 | echo Please ensure AltSnap is installed or specify the correct path in the AltSnap.xml file. 41 | echo. 42 | pause 43 | exit /b 1 44 | ) 45 | 46 | :: Check if AltSnap.xml exists 47 | if not exist "%AltSnapXML%" ( 48 | echo. 49 | echo AltSnap.xml file not found: %AltSnapXML% 50 | echo Please ensure the AltSnap.xml file exists in the specified location. 51 | echo. 52 | pause 53 | exit /b 1 54 | ) 55 | 56 | echo. 57 | echo Going to run command: 58 | echo schtasks.exe /CREATE /XML "%AltSnapXML%" /TN "AltSnap" %* 59 | echo. 60 | pause 61 | 62 | schtasks.exe /CREATE /XML "%AltSnapXML%" /TN "AltSnap" %* 63 | 64 | echo. 65 | pause 66 | 67 | endlocal 68 | exit /b 0 69 | -------------------------------------------------------------------------------- /snap.c: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * (C) Raymond GILLIBERT * 3 | * Functions to handle Snap/restore informations AltSnap * 4 | * Snapping informations set with Set/GetProp. * 5 | * Window database is used as fallback. * 6 | * General Public License Version 3 or later (Free Software Foundation) * 7 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 8 | 9 | #define SNAPPED 1 10 | #define ROLLED 2 11 | #define SNLEFT (1<<2) 12 | #define SNRIGHT (1<<3) 13 | #define SNTOP (1<<4) 14 | #define SNBOTTOM (1<<5) 15 | #define SNMAXH (1<<6) 16 | #define SNMAXW (1<<7) 17 | #define SNCLEAR (1<<8) // to clear the flag at init movement. 18 | #define TORESIZE (1<<9) 19 | #define SNTHENROLLED (1<<10) 20 | #define SNZONE (1<<11) 21 | #define SNMIN (1<<12) 22 | #define SNTOPLEFT (SNTOP|SNLEFT) 23 | #define SNTOPRIGHT (SNTOP|SNRIGHT) 24 | #define SNBOTTOMLEFT (SNBOTTOM|SNLEFT) 25 | #define SNBOTTOMRIGHT (SNBOTTOM|SNRIGHT) 26 | #define SNAPPEDSIDE (SNTOPLEFT|SNBOTTOMRIGHT) 27 | 28 | #define PureLeft(flag) ( (flag&SNLEFT) && !(flag&(SNTOP|SNBOTTOM)) ) 29 | #define PureRight(flag) ( (flag&SNRIGHT) && !(flag&(SNTOP|SNBOTTOM)) ) 30 | #define PureTop(flag) ( (flag&SNTOP) && !(flag&(SNLEFT|SNRIGHT)) ) 31 | #define PureBottom(flag) ( (flag&SNBOTTOM) && !(flag&(SNLEFT|SNRIGHT)) ) 32 | 33 | ///////////////////////////////////////////////////////////////////////////// 34 | #define NUMWNDDB 16 35 | struct wnddata { 36 | unsigned restore; 37 | HWND hwnd; 38 | int width; 39 | int height; 40 | // int rolledh; 41 | // UINT odpi 42 | }; 43 | static struct wnddata wnddb[NUMWNDDB]; 44 | 45 | ///////////////////////////////////////////////////////////////////////////// 46 | // Database functions: used as fallback if SetProp fails 47 | 48 | // Zero-out the database to be called in Load() 49 | static void ResetDB() 50 | { 51 | int i; 52 | for (i=0; i < NUMWNDDB; i++) { 53 | wnddb[i].hwnd = NULL; 54 | wnddb[i].restore = 0; 55 | } 56 | } 57 | // Return the entry if it was already in db. Or NULL otherwise 58 | static pure int GetWindowInDB(HWND hwndd) 59 | { 60 | // Check if window is already in the wnddb database 61 | // And set it in the current state 62 | unsigned i; 63 | for (i=0; i < NUMWNDDB; i++) { 64 | if (wnddb[i].hwnd == hwndd) { 65 | return i; 66 | } 67 | } 68 | return -1; 69 | } 70 | static void AddWindowToDB(HWND hwndd, int width, int height, unsigned flag) 71 | { 72 | int idx = GetWindowInDB(hwndd); 73 | 74 | // Find a nice place in wnddb if not already present 75 | if (idx < 0) { 76 | int i; 77 | for (i=0; i < NUMWNDDB && wnddb[i].hwnd; i++); 78 | if (i >= NUMWNDDB) return; 79 | idx = i; 80 | } 81 | wnddb[idx].hwnd = hwndd; 82 | wnddb[idx].width = width; 83 | wnddb[idx].height = height; 84 | wnddb[idx].restore = flag; 85 | } 86 | static void DelWindowFromDB(HWND hwnd) 87 | { 88 | unsigned i; 89 | for (i=0; i < NUMWNDDB; i++) { 90 | if (wnddb[i].hwnd == hwnd) { 91 | wnddb[i].hwnd = NULL; 92 | wnddb[i].restore = 0; 93 | } 94 | } 95 | } 96 | ///////////////////////////////////////////////////////////////////////////// 97 | // Windows restore data are saved in properties 98 | // In 32b mode width and height are shrunk to 16b WORDS 99 | // In 64b mode width and height are stored on 32b DWORDS 100 | // I 64b mode we also check for FancyZone info that are stored the same way! 101 | // There is a lot of cast because of annoying warnings... 102 | // There is also a fallback to a database for some spetial windows. 103 | static unsigned GetRestoreData(HWND hwnd, int *width, int *height) 104 | { 105 | DorQWORD WH = (DorQWORD)GetProp(hwnd, APP_PROPPT); 106 | if (WH) { 107 | *width = (int)LOWORDPTR(WH); 108 | *height = (int)HIWORDPTR(WH); 109 | UINT dpi = GetDpiForWindow(hwnd); 110 | UINT odpi; 111 | if (dpi && (odpi = (UINT)(DorQWORD)GetProp(hwnd, APP_PRODPI)) && odpi != dpi) { 112 | // The current dpi is different for the window, We must scale the content. 113 | *width = MulDiv(*width, dpi, odpi); 114 | *height = MulDiv(*height, dpi, odpi); 115 | } 116 | return (unsigned)(DorQWORD)GetProp(hwnd, APP_PROPFL);; 117 | 118 | # ifdef WIN64 // Try fancy zone flag only in 64bit mode! 119 | } else if (conf.FancyZone && (WH = (DorQWORD)GetProp(hwnd, FZ_PROPPT))) { 120 | // It seems FancyZones stores size info in points, not pixels. 121 | *width = (int)LOWORDPTR(WH); 122 | *height = (int)HIWORDPTR(WH); 123 | if (conf.FancyZone != 2) { 124 | int dpi = GetDpiForWindow(hwnd); 125 | if (dpi) { 126 | // Scale bcak to current dpi from 96 127 | *width = MulDiv(*width, dpi, 96); 128 | *height = MulDiv(*height, dpi, 96); 129 | } 130 | } 131 | return SNAPPED|SNZONE; 132 | # endif 133 | } else { // fallback to database 134 | int idx = GetWindowInDB(hwnd); 135 | if (idx >= 0) { 136 | *width = wnddb[idx].width; 137 | *height = wnddb[idx].height; 138 | return wnddb[idx].restore; 139 | } 140 | } 141 | // Unable to find the window in the db 142 | *width = *height = 0; 143 | return 0; 144 | } 145 | static void ClearRestoreData(HWND hwnd) 146 | { 147 | RemoveProp(hwnd, APP_PROPPT); 148 | RemoveProp(hwnd, APP_PROPFL); 149 | // RemoveProp(hwnd, APP_PROPOFFSET); 150 | # ifdef WIN64 151 | if(conf.FancyZone) { 152 | RemoveProp(hwnd, FZ_PROPPT); 153 | RemoveProp(hwnd, FZ_PROPZONES); 154 | } 155 | # endif 156 | DelWindowFromDB(hwnd); 157 | } 158 | // Sets width, height and restore flag in a hwnd 159 | static void SetRestoreData(HWND hwnd, int width, int height, unsigned restore) 160 | { 161 | BOOL ret; 162 | ret = SetProp(hwnd, APP_PROPFL, (HANDLE)(DorQWORD)restore); 163 | ret &= SetProp(hwnd, APP_PROPPT, (HANDLE)MAKELONGPTR(width, height)); 164 | UINT dpi=0; 165 | if ( (dpi = GetDpiForWindow(hwnd)) ) 166 | ret &= SetProp(hwnd, APP_PRODPI, (HANDLE)(DorQWORD)dpi); 167 | 168 | if (!ret) AddWindowToDB(hwnd, width, height, restore); 169 | } 170 | 171 | static unsigned GetRestoreFlag(HWND hwnd) 172 | { 173 | unsigned flag = (DorQWORD)GetProp(hwnd, APP_PROPFL); 174 | 175 | # ifdef WIN64 176 | if(conf.FancyZone && GetProp(hwnd, FZ_PROPPT)) 177 | flag |= SNAPPED|SNZONE; 178 | # endif 179 | 180 | int idx; // fallback to db. 181 | if (!flag && ((idx = GetWindowInDB(hwnd)) >=0)) { 182 | return wnddb[idx].restore; 183 | } 184 | return flag; 185 | } 186 | static void SetRestoreFlag(HWND hwnd, unsigned flag) 187 | { 188 | BOOL ret = SetProp(hwnd, APP_PROPFL, (HANDLE)(DorQWORD)flag); 189 | int idx; 190 | if (!ret && ((idx = GetWindowInDB(hwnd)) >=0)) { 191 | wnddb[idx].restore = flag; 192 | } 193 | } 194 | 195 | static int IsAnySnapped(HWND hwnd) 196 | { 197 | // Any kind of snapping, including maximization. 198 | // In short whenever the window will be restored. 199 | unsigned flg; 200 | return IsZoomed(hwnd) 201 | ||( !(conf.SmartAero&4) && SNAPPED & (flg=GetRestoreFlag(hwnd)) && !(flg&SNCLEAR) ) 202 | || IsWindowSnapped(hwnd); 203 | } 204 | ///////////////////////////////////////////////////////////////////////////// 205 | // borderless flag (saving old GWL_STYLE) 206 | static void SetBorderlessFlag(HWND hwnd, LONG_PTR flag) 207 | { 208 | SetProp(hwnd, APP_PRBDLESS,(HANDLE)flag); 209 | } 210 | static LONG_PTR GetBorderlessFlag(HWND hwnd) 211 | { 212 | return (LONG_PTR)GetProp(hwnd, APP_PRBDLESS); 213 | } 214 | static LONG_PTR ClearBorderlessFlag(HWND hwnd) 215 | { 216 | return (LONG_PTR)RemoveProp(hwnd, APP_PRBDLESS); 217 | } 218 | 219 | static void SetSquareCorners(HWND hwnd) 220 | { 221 | int cornerPref = DWMWCP_DEFAULT; 222 | HRESULT ok = DwmGetWindowAttributeL(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref)); 223 | if (ok) { 224 | SetProp(hwnd, APP_OWDMCP, (HANDLE)(UINT_PTR)(cornerPref+1)); // Do not store Zero. 225 | cornerPref = DWMWCP_DONOTROUND; 226 | DwmSetWindowAttributeL(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref)); 227 | } 228 | } 229 | static void RestoreOldCorners(HWND hwnd) 230 | { 231 | int cp = (int)(UINT_PTR)GetProp(hwnd, APP_OWDMCP); 232 | RemoveProp(hwnd, APP_OWDMCP); 233 | if (cp) { 234 | cp--; 235 | DwmSetWindowAttributeL(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cp, sizeof(cp)); 236 | } 237 | } 238 | 239 | /////////////////////////////////////////////////////////////////////////////// 240 | //// Roll unroll stuff 241 | //static int GetRolledHeight(HWND hwnd) 242 | //{ 243 | // int ret = (int)GetProp(hwnd, APP_ROLLED); 244 | // int idx; 245 | // if (!ret && ((idx = GetWindowInDB(hwnd)) >=0)) { 246 | // ret = wnddb[idx].rolledh; 247 | // } 248 | // return ret; 249 | //} 250 | //static int ClearRolledHeight(HWND hwnd) 251 | //{ 252 | // int ret = (int)RemoveProp(hwnd, APP_ROLLED); 253 | // 254 | // int idx; 255 | // if (!ret && ((idx = GetWindowInDB(hwnd)) >=0)) { 256 | // ret = wnddb[idx].rolledh; 257 | // wnddb[idx].rolledh = 0; 258 | // } 259 | // return ret; 260 | //} 261 | //static void SetRolledHeight(HWND hwnd, int rolledh) 262 | //{ 263 | // BOOL ret = SetProp(hwnd, APP_ROLLED, (HANDLE)(DorQWORD)rolledh); 264 | // if (ret) return; 265 | // 266 | // int idx; 267 | // if (((idx = GetWindowInDB(hwnd)) >=0)) { 268 | // wnddb[idx].rolledh = rolledh; 269 | // } else { 270 | // int i; 271 | // for (i=0; i < NUMWNDDB && wnddb[i].hwnd; i++); 272 | // if (i >= NUMWNDDB) return; 273 | // idx = i; 274 | // wnddb[idx].hwnd = hwnd; 275 | // wnddb[idx].rolledh = rolledh; 276 | // wnddb[idx].restore = 0; 277 | // } 278 | // 279 | //} 280 | //static void AddToFlag(HWND hwnd, unsigned flag) 281 | //{ 282 | // SetRestoreFlag(hwnd, flag|GetRestoreFlag(hwnd)); 283 | //} 284 | // 285 | //static void RemoveToFlag(HWND hwnd, unsigned flag) 286 | //{ 287 | // SetRestoreFlag(hwnd, flag & (~GetRestoreFlag(hwnd))); 288 | //} 289 | -------------------------------------------------------------------------------- /thunks.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | enum { 5 | TOT_THUNK_SIZE=4096, 6 | #if defined(_M_AMD64) || defined(WIN64) 7 | THUNK_SIZE=22, 8 | #elif defined(_M_IX86) 9 | THUNK_SIZE=14, // 13 aligned to USHORT 10 | #else 11 | #error Unsupported processor type, determine THUNK_SIZE here... 12 | #endif 13 | MAX_THUNKS=TOT_THUNK_SIZE/THUNK_SIZE, 14 | }; 15 | 16 | static BYTE *thunks_array = NULL; 17 | static WORD numthunks = 0; 18 | static WORD free_idx = 0; // Free index mem; 19 | 20 | static void *AllocThunk(LONG_PTR tProc, void *vParam) 21 | { 22 | if (!thunks_array) { 23 | thunks_array = (BYTE*)VirtualAlloc( NULL, TOT_THUNK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); 24 | if (!thunks_array) 25 | return NULL; 26 | 27 | free_idx = 0; 28 | for (WORD i=0; i < MAX_THUNKS; i++) 29 | *(WORD*)&thunks_array[i*THUNK_SIZE] = i+1; 30 | } 31 | 32 | if (numthunks >= MAX_THUNKS) { 33 | return NULL; 34 | } 35 | ++numthunks; 36 | 37 | // get the free thunk 38 | BYTE *thunk = &thunks_array[free_idx * THUNK_SIZE]; 39 | free_idx = *(WORD*)thunk; // Pick up the free index 40 | 41 | DWORD oldprotect; 42 | VirtualProtect(thunks_array, TOT_THUNK_SIZE, PAGE_EXECUTE_READWRITE, &oldprotect); 43 | // x86 44 | // | mov dword ptr [esp+4] this 45 | // | jmp MainProc 46 | // AMD64 47 | // | mov rcx this 48 | // | mov rax MainProc 49 | // | jmp rax 50 | // 51 | #if defined(_M_AMD64) || defined(WIN64) 52 | *(WORD*) (thunk + 0) = 0xb948; 53 | *(void**) (thunk + 2) = vParam; 54 | *(WORD*) (thunk +10) = 0xb848; 55 | *(void**) (thunk +12) = tProc; 56 | *(WORD*) (thunk +20) = 0xe0ff; 57 | #elif defined(_M_IX86) 58 | *(DWORD*) (thunk +0) = 0x042444C7; 59 | *(void**) (thunk +4) = vParam; 60 | *(BYTE*) (thunk +8) = 0xE9; 61 | *(DWORD *) (thunk+9) = (BYTE*)((BYTE*)tProc)-(thunk+13); 62 | #else 63 | #error Unsupported processor type, please implement assembly code... 64 | #endif 65 | 66 | // Make thuk execute only for safety. 67 | VirtualProtect(thunks_array, TOT_THUNK_SIZE, PAGE_EXECUTE, &oldprotect); 68 | FlushInstructionCache( GetCurrentProcess(), thunks_array, TOT_THUNK_SIZE ); 69 | 70 | return thunk; 71 | } 72 | static void ReleaseThunk(BYTE *thunk) 73 | { 74 | if (!thunk || thunks_array + TOT_THUNK_SIZE < thunk || thunk < thunks_array ) 75 | return; 76 | 77 | DWORD oldprotect; 78 | VirtualProtect(thunks_array, TOT_THUNK_SIZE, PAGE_EXECUTE_READWRITE, &oldprotect); 79 | 80 | *(WORD*)thunk = free_idx; // Set free index in the current thunk location 81 | free_idx = (WORD)( (thunk - thunks_array) / THUNK_SIZE ); 82 | --numthunks; 83 | 84 | VirtualProtect(thunks_array, TOT_THUNK_SIZE, PAGE_EXECUTE_READ, &oldprotect); 85 | 86 | // Everything is free! 87 | if (numthunks == 0) { 88 | VirtualFree( thunks_array, 0, MEM_RELEASE ); 89 | thunks_array = NULL; 90 | } 91 | } 92 | #ifdef TEST_MAIN 93 | #include 94 | int main(void) 95 | { 96 | enum { LEN = 1024 }; 97 | BYTE *t[LEN]; 98 | for (int i =0; i < LEN; i++) 99 | { 100 | t[i] = (BYTE*)AllocThunk((LONG_PTR)333, NULL); 101 | if (t[i]) 102 | printf("t[%d] = %lx\n", i, (DWORD)t[i]); 103 | } 104 | 105 | for (int i = LEN-1; i >=0; i--) 106 | { 107 | size_t prevfreeidx = free_idx; 108 | ReleaseThunk(t[i]); 109 | if (t[i]) 110 | printf("released t[%d] = %lx free_idx=%d / prev=%d\n", i, (DWORD)t[i], (int)free_idx, prevfreeidx); 111 | if(i%3==0) 112 | t[i] = (BYTE*)AllocThunk((LONG_PTR)444, NULL); 113 | } 114 | 115 | return 0; 116 | } 117 | #endif 118 | -------------------------------------------------------------------------------- /tray.c: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * Copyright (C) 2015 Stefan Sundin * 3 | * This program is free software: you can redistribute it and/or modify * 4 | * it under the terms of the GNU General Public License as published by * 5 | * the Free Software Foundation, either version 3 or later. * 6 | * Modified By Raymond Gillibert in 2020 * 7 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 8 | 9 | #ifndef NIF_INFO 10 | #define NIF_INFO 0x00000010 11 | #endif 12 | 13 | static struct { // NOTIFYICONDATA for NT4 14 | DWORD cbSize; 15 | HWND hWnd; 16 | UINT uID; 17 | UINT uFlags; 18 | UINT uCallbackMessage; 19 | HICON hIcon; 20 | TCHAR szTip[64]; 21 | } tray; 22 | 23 | static int tray_added = 0; 24 | static int hide = 0; 25 | static int UseZones = 0; 26 | static int LayoutNumber=0; 27 | static int MaxLayouts=0; 28 | 29 | static const TCHAR *iconstr[] = { 30 | TEXT("TRAY_OFF"), 31 | TEXT("TRAY_ON"), 32 | TEXT("TRAY_SUS") 33 | }; 34 | static const TCHAR *traystr[] = { 35 | TEXT(APP_NAMEA)TEXT(" (Off)"), 36 | TEXT(APP_NAMEA)TEXT(" (On)"), 37 | TEXT(APP_NAMEA)TEXT("..."), 38 | }; 39 | static HICON icons[3]; 40 | 41 | static void LoadAllIcons() 42 | { 43 | TCHAR theme[MAX_PATH]; // Get theme name 44 | int ret = GetPrivateProfileString(TEXT("General"), TEXT("Theme"), TEXT(""), theme, ARR_SZ(theme), inipath); 45 | if (ret && theme[1]) { 46 | TCHAR path[MAX_PATH]; 47 | DWORD mod = GetModuleFileName(NULL, path, ARR_SZ(path)); 48 | if (mod) { 49 | PathRemoveFileSpecL(path); 50 | lstrcat_s(path, ARR_SZ(path), TEXT("\\Themes\\")); // Themes subfolder 51 | lstrcat_s(path, ARR_SZ(path), theme); // Theme name 52 | int len = lstrlen(path); 53 | TCHAR *p = path+len; 54 | *p++ = TEXT('\\'); 55 | if (len < MAX_PATH-13) { // strlen("TRAY_OFF.ICO")==12 56 | UCHAR i; 57 | for(i=0; i<3; i++) { 58 | lstrcpy_s(p, ARR_SZ(path)-len, iconstr[i]); 59 | lstrcat_s(path, ARR_SZ(path), TEXT(".ico")); 60 | HICON tmp = (HICON)LoadImage(g_hinst, path, IMAGE_ICON,0,0, LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_LOADTRANSPARENT); 61 | icons[i] = tmp? tmp: LoadIcon(g_hinst, MAKEINTRESOURCE( TRAY_OFF+i )); 62 | } 63 | return; 64 | } 65 | } 66 | } 67 | // Fallback to internal icons. 68 | UCHAR i; 69 | for (i=0; i<3; i++) 70 | icons[i] = LoadIcon(g_hinst, MAKEINTRESOURCE( TRAY_OFF+i )); 71 | } 72 | 73 | ///////////////////////////////////////////////////////////////////////////// 74 | static int InitTray() 75 | { 76 | ScrollLockState = GetPrivateProfileInt(TEXT("Input"), TEXT("ScrollLockState"), 0, inipath); 77 | LayoutNumber = GetPrivateProfileInt(TEXT("Zones"), TEXT("LayoutNumber"), 0, inipath); 78 | MaxLayouts = GetPrivateProfileInt(TEXT("Zones"), TEXT("MaxLayouts"), 0, inipath); 79 | MaxLayouts = CLAMP(0, MaxLayouts, 10); 80 | LayoutNumber = CLAMP(0, LayoutNumber, max(0,MaxLayouts-1)); 81 | 82 | LoadAllIcons(); 83 | 84 | // Create icondata 85 | tray.cbSize = sizeof(tray); 86 | tray.hWnd = g_hwnd; 87 | tray.uID = 0; 88 | tray.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; 89 | tray.uCallbackMessage = WM_TRAY; 90 | 91 | // Register TaskbarCreated so we can re-add the tray icon if (when) explorer.exe crashes 92 | WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated")); 93 | LOG("Register TaskbarCreated message: %X", WM_TASKBARCREATED); 94 | 95 | return 0; 96 | } 97 | ///////////////////////////////////////////////////////////////////////////// 98 | static int UpdateTray() 99 | { 100 | int Index = !!ENABLED(); 101 | if (Index) { 102 | Index += (ScrollLockState&1) 103 | && !( !(GetKeyState(VK_SCROLL)&1) ^ !(ScrollLockState&2) ); 104 | if (GetProp(g_hwnd, APP_ASONOFF)) 105 | Index=2; 106 | } 107 | // Load info tool tip and tray icon 108 | lstrcpy_s(tray.szTip, ARR_SZ(tray.szTip), traystr[Index]); 109 | tray.hIcon = icons[Index]; 110 | 111 | // Only add or modify if not hidden or if balloon will be displayed 112 | if (!hide || tray.uFlags&NIF_INFO) { 113 | // Try a few times, sleep 100 ms between each attempt 114 | int i=1; 115 | LOG("Updating tray icon"); 116 | while (!Shell_NotifyIcon(tray_added? NIM_MODIFY: NIM_ADD, (PNOTIFYICONDATA)&tray) ) { 117 | LOG("Failed in try No. %d", i); 118 | 119 | // Maybe we just tried to add an already existing tray. 120 | // Happens after DPI change under Win 10 (TaskbarCreated) msg. 121 | if (!tray_added && Shell_NotifyIcon(NIM_MODIFY, (PNOTIFYICONDATA)&tray)) { 122 | LOG("Updated tray icon"); 123 | tray_added = 1; 124 | return 0; 125 | } 126 | 127 | if (i > 2) { 128 | LOG("Failed all atempts!!"); 129 | return 1; 130 | } 131 | Sleep(100); 132 | i++; 133 | } 134 | LOG("Sucess at try %d", i); 135 | // Success 136 | tray_added = 1; 137 | } 138 | return 0; 139 | } 140 | ///////////////////////////////////////////////////////////////////////////// 141 | static int RemoveTray() 142 | { 143 | if (!tray_added) 144 | return 1; 145 | 146 | if (!Shell_NotifyIcon(NIM_DELETE, (PNOTIFYICONDATA)&tray)) 147 | return 1; 148 | 149 | // Success 150 | tray_added = 0; 151 | return 0; 152 | } 153 | 154 | ///////////////////////////////////////////////////////////////////////////// 155 | // Zones functions 156 | static void WriteCurrentLayoutNumber() 157 | { 158 | if (MaxLayouts) { 159 | TCHAR txt[UINT_DIGITS+1]; 160 | WritePrivateProfileString(TEXT("Zones"), TEXT("LayoutNumber"), Uint2lStr(txt, LayoutNumber), inipath); 161 | } 162 | } 163 | static TCHAR *RectToStr(const RECT *rc, TCHAR rectstr[AT_LEAST INT_DIGITS*4+4+1]) 164 | { 165 | TCHAR txt[INT_DIGITS+1]; 166 | int i; 167 | const long *RC = (const long *)rc; 168 | rectstr[0] = '\0'; 169 | for(i = 0; i < 4; i++) { 170 | lstrcat_s(rectstr, 64, Int2lStr(txt, (int)RC[i])); 171 | lstrcat_s(rectstr, 64, TEXT(",")); 172 | } 173 | return rectstr; 174 | } 175 | // Save a rect as a string in a Zone entry in the inifile 176 | static void SaveZone(const RECT *rc, unsigned num) 177 | { 178 | TCHAR txt[64], name[32]; 179 | WritePrivateProfileString(TEXT("Zones"), ZidxToZonestr(LayoutNumber, num, name), RectToStr(rc, txt), inipath); 180 | } 181 | static void ClearAllZones() 182 | { 183 | int i; 184 | TCHAR txt[128], name[32]; 185 | for (i = 0; i < 2048; i++) { 186 | ZidxToZonestr(LayoutNumber, i, name); 187 | if (GetPrivateProfileString(TEXT("Zones"), name, TEXT(""), txt, ARR_SZ(txt), inipath)) { 188 | WritePrivateProfileString(TEXT("Zones"), name, TEXT(""), inipath); 189 | } 190 | } 191 | } 192 | // Call with lParam = 1 to reset NZones 193 | BOOL CALLBACK SaveTestWindow(HWND hwnd, LPARAM lParam) 194 | { 195 | static unsigned NZones; 196 | if (lParam) { // Reset number of Zones 197 | NZones = 0; 198 | return FALSE; 199 | } 200 | 201 | TCHAR classn[256]; 202 | RECT rc; 203 | if (IsWindowVisible(hwnd) 204 | && GetClassName(hwnd, classn, ARR_SZ(classn)) 205 | && !lstrcmp(classn, TEXT(APP_NAMEA) TEXT("-Test")) 206 | && GetWindowRectL(hwnd, &rc)) { 207 | SaveZone(&rc, NZones++); 208 | PostMessage(hwnd, WM_CLOSE, 0, 0); 209 | } 210 | return TRUE; 211 | } 212 | 213 | static void SaveCurrentLayout() 214 | { 215 | ClearAllZones(); 216 | SaveTestWindow(NULL, 1); 217 | EnumThreadWindows(GetCurrentThreadId(), SaveTestWindow, 0); 218 | } 219 | 220 | BOOL CALLBACK CloseTestWindowCB(HWND hwnd, LPARAM lParam) 221 | { 222 | TCHAR classn[256]; 223 | if (GetClassName(hwnd, classn, ARR_SZ(classn)) 224 | && !lstrcmp(classn, TEXT(APP_NAMEA) TEXT("-Test")) ) { 225 | PostMessage(hwnd, WM_CLOSE, 0, 0); 226 | } 227 | return TRUE; 228 | } 229 | 230 | static void CloseAllTestWindows() 231 | { 232 | EnumThreadWindows(GetCurrentThreadId(), CloseTestWindowCB, 0); 233 | } 234 | 235 | static void catFullLayoutName(TCHAR *txt, size_t len, int laynum) 236 | { 237 | TCHAR n1[UINT_DIGITS+1]; 238 | lstrcat_s(txt, len, l10n->MenuSnapLayout); 239 | lstrcat_s(txt, len, Uint2lStr(n1, laynum+1)); 240 | if (G_HotKeyProc) { 241 | DWORD rez =0; 242 | if ((rez = G_HotKeyProc(g_hwnd, WM_GETLAYOUTREZ, laynum, 0))) { 243 | // TCHAR n2[UINT_DIGITS+1]; 244 | // Add (width:height) to label the layout. 245 | // lstrcatM_s(txt, len ,TEXT(" ("), Uint2lStr(n1, LOWORD(rez)),TEXT(":"),Uint2lStr(n2, HIWORD(rez)), TEXT(")"), NULL); 246 | lstrcat_s(txt, len, TEXT(" (")); 247 | lstrcat_s(txt, len, Uint2lStr(n1, LOWORD(rez))); 248 | lstrcat_s(txt, len, TEXT(":")); 249 | lstrcat_s(txt, len, Uint2lStr(n1, HIWORD(rez))); 250 | lstrcat_s(txt, len, TEXT(")")); 251 | } else { 252 | lstrcat_s(txt, len, TEXT(" ")); 253 | lstrcat_s(txt, len, l10n->MenuEmptyZone); // (empty) 254 | } 255 | } else { 256 | lstrcat_s(txt, len, TEXT(" (...)")); 257 | } 258 | } 259 | 260 | ///////////////////////////////////////////////////////////////////////////// 261 | static void ShowContextMenu(HWND hwnd) 262 | { 263 | POINT pt; 264 | GetCursorPos(&pt); 265 | HMENU menu = CreatePopupMenu(); 266 | 267 | AppendMenu(menu, MF_STRING, SWM_TOGGLE, (ENABLED()?l10n->MenuDisable:l10n->MenuEnable)); 268 | AppendMenu(menu, MF_STRING, SWM_HIDE, l10n->MenuHideTray); 269 | if(VISTA) 270 | InsertMenu(menu, -1, elevated?MF_BYPOSITION|MF_GRAYED:MF_BYPOSITION 271 | , SWM_ELEVATE, (elevated? l10n->GeneralElevated: l10n->GeneralElevate)); 272 | 273 | AppendMenu(menu, MF_SEPARATOR, 0, NULL); 274 | AppendMenu(menu, MF_STRING, SWM_CONFIG, l10n->MenuConfigure); 275 | AppendMenu(menu, MF_STRING, SWM_ABOUT, l10n->MenuAbout); 276 | AppendMenu(menu, MF_STRING, SWM_OPENINIFILE, l10n->MenuOpenIniFile); 277 | 278 | if (UseZones&1) { // Zones section 279 | if(MaxLayouts) 280 | AppendMenu(menu, MF_SEPARATOR, 0, NULL); 281 | int i; 282 | TCHAR txt[128]; 283 | for (i=0; i < MaxLayouts; i++) { 284 | txt[0] = '\0'; 285 | catFullLayoutName(txt, ARR_SZ(txt), i); 286 | // Check the current layout We use a simple checkmark, 287 | // because a radio button is more complex to setup. 288 | UINT mfflags = i==LayoutNumber? MF_STRING|MF_CHECKED: MF_STRING|MF_UNCHECKED; 289 | AppendMenu(menu, mfflags, SWM_SNAPLAYOUT+i, txt); 290 | } 291 | 292 | if (!(UseZones&2)) { 293 | TCHAR numstr[INT_DIGITS+1]; 294 | lstrcpy_s(txt, ARR_SZ(txt), l10n->MenuEditLayout); 295 | lstrcat_s(txt, ARR_SZ(txt), TEXT(" ")); 296 | lstrcat_s(txt, ARR_SZ(txt), Int2lStr(numstr, LayoutNumber+1)); 297 | AppendMenu(menu, MF_SEPARATOR, 0, NULL); 298 | AppendMenu(menu, MF_STRING, SWM_TESTWIN, l10n->AdvancedTestWindow); 299 | AppendMenu(menu, MF_STRING, SWM_EDITLAYOUT, txt); 300 | AppendMenu(menu, FindWindow(TEXT(APP_NAMEA)TEXT("-test"), NULL)? MF_STRING :MF_STRING|MF_GRAYED 301 | , SWM_SAVEZONES, l10n->MenuSaveZones); 302 | 303 | AppendMenu(menu, FindWindow(TEXT(APP_NAMEA)TEXT("-test"), NULL)? MF_STRING :MF_STRING|MF_GRAYED 304 | , SWM_CLOSEZONES, l10n->MenuCloseAllZones); 305 | } 306 | } 307 | 308 | AppendMenu(menu, MF_SEPARATOR, 0, NULL); 309 | AppendMenu(menu, MF_STRING, SWM_EXIT, l10n->MenuExit); 310 | 311 | // Track menu 312 | SetForegroundWindow(hwnd); 313 | TrackPopupMenu(menu, TPM_BOTTOMALIGN, pt.x, pt.y, 0, hwnd, NULL); 314 | DestroyMenu(menu); 315 | } 316 | -------------------------------------------------------------------------------- /window.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "resource.h" 4 | #define MY_CBS_STYLE CBS_DROPDOWN|WS_TABSTOP|WS_VSCROLL|CBS_AUTOHSCROLL 5 | ///////////////////////////////////////////////////////////////////////////// 6 | IDD_ABOUTPAGE DIALOG 0, 0, 220, 225 7 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 8 | CAPTION "" // ABOUT 9 | FONT 8, "Ms Shell Dlg" 10 | BEGIN 11 | GROUPBOX "",IDC_ABOUT_BOX, 3,1, 212,105 12 | 13 | ICON APP_ICON, IDC_STATIC, 15,15,0,0 14 | LTEXT "",IDC_VERSION, 48, 15, 160,8 15 | EDITTEXT IDC_URL, 48,25,160,10, ES_READONLY|NOT WS_BORDER 16 | LTEXT "",IDC_AUTHOR, 10, 40, 200, 8 17 | LTEXT "https://stefansundin.com/", 0, 10,50,200,10 18 | 19 | LTEXT "",IDC_AUTHOR2, 10, 65, 200, 8 20 | 21 | LTEXT "", IDC_LICENSE,10, 80, 200, 20 22 | 23 | GROUPBOX "",IDC_TRANSLATIONS_BOX,3,111,212,110 24 | EDITTEXT IDC_TRANSLATIONS,10,120,200,95, ES_MULTILINE|ES_AUTOHSCROLL|ES_READONLY|WS_VSCROLL 25 | END 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | IDD_BLACKLISTPAGE DIALOG DISCARDABLE 0, 0, 220, 225 29 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 30 | CAPTION "" // BLACKLIST 31 | FONT 8, "Ms Shell Dlg" 32 | BEGIN 33 | 34 | GROUPBOX "", IDC_BLACKLIST_BOX, 3,1,212,138 35 | LTEXT "", IDC_PROCESSBLACKLIST_HEADER, 10,11,200,8 36 | EDITTEXT IDC_PROCESSBLACKLIST,10,20, 200,14,ES_AUTOHSCROLL 37 | LTEXT "", IDC_BLACKLIST_HEADER, 10,36,200,8 38 | EDITTEXT IDC_BLACKLIST, 10,45, 200,14,ES_AUTOHSCROLL 39 | LTEXT "", IDC_SCROLLLIST_HEADER, 10,61,200,8 40 | EDITTEXT IDC_SCROLLLIST, 10,70, 200,14,ES_AUTOHSCROLL 41 | LTEXT "", IDC_MDISBL_HEADER, 10,86,200,8 42 | EDITTEXT IDC_MDIS, 10,95,200,14,ES_AUTOHSCROLL 43 | LTEXT "", IDC_PAUSEBL_HEADER, 10,111,200,8 44 | EDITTEXT IDC_PAUSEBL, 10,120,200,14,ES_AUTOHSCROLL 45 | 46 | GROUPBOX "", IDC_FINDWINDOW_BOX, 3,140,212,78 47 | ICON IDI_FIND, IDC_FINDWINDOW, 12,160,16,16, SS_NOTIFY|SS_REALSIZEIMAGE 48 | EDITTEXT IDC_NEWRULE, 30,150,180,12,ES_AUTOHSCROLL 49 | EDITTEXT IDC_NEWPROGNAME, 30,165,95,12,ES_AUTOHSCROLL 50 | RTEXT "STYLE:", 0, 125,167,32,8 51 | EDITTEXT IDC_GWLSTYLE, 160,165,50,12,ES_AUTOHSCROLL 52 | 53 | RTEXT "WM_NCHITTEST:", IDC_STATIC, 10,183,60,8 54 | EDITTEXT IDC_NCHITTEST, 72,180,25,12,ES_AUTOHSCROLL 55 | RTEXT "In DWM Buttons:", IDC_STATIC, 10,197,60,8 56 | EDITTEXT IDC_DWMCAPBUTTON, 72,195,25,12,ES_AUTOHSCROLL 57 | RTEXT "EXSTYLE:", IDC_STATIC, 115,182,42,8 58 | EDITTEXT IDC_GWLEXSTYLE, 160,180,50,12,ES_AUTOHSCROLL 59 | LTEXT "RECT:", IDC_STATIC, 102,197,22,8 60 | EDITTEXT IDC_RECT, 125,195,85,12,ES_AUTOHSCROLL 61 | LTEXT "", IDC_WINHANDLES, 6,208,206,8 62 | END 63 | 64 | ///////////////////////////////////////////////////////////////////////////// 65 | IDD_GENERALPAGE DIALOG 0, 0, 220, 225 66 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 67 | EXSTYLE WS_EX_WINDOWEDGE 68 | CAPTION "" // GENERAL 69 | FONT 8, "Ms Shell Dlg" 70 | BEGIN 71 | GROUPBOX "", IDC_GENERAL_BOX,3,1,212,172 72 | AUTOCHECKBOX "", IDC_AUTOFOCUS, 10,12,203,18,BS_MULTILINE 73 | AUTOCHECKBOX "", IDC_AERO, 10, 30, 203,8 74 | AUTOCHECKBOX "", IDC_SMARTAERO, 10, 40, 203,8 75 | AUTOCHECKBOX "", IDC_SMARTERAERO, 10, 50, 203,8 76 | AUTOCHECKBOX "", IDC_STICKYRESIZE, 10, 60, 203,8 77 | AUTOCHECKBOX "", IDC_INACTIVESCROLL, 10, 70, 203,8 78 | AUTOCHECKBOX "", IDC_MDI, 10, 80, 203,8 79 | AUTOCHECKBOX "", IDC_RESIZEALL, 10, 90, 203,8 80 | AUTOCHECKBOX "", IDC_USEZONES, 10,100, 203,8 81 | AUTOCHECKBOX "", IDC_PIERCINGCLICK, 10,110, 203,8 82 | 83 | GROUPBOX "", IDC_RESIZECENTER, 108,120, 104, 50 84 | AUTORADIOBUTTON "", IDC_RZCENTER_NORM, 112,130, 95,8, WS_GROUP 85 | AUTORADIOBUTTON "", IDC_RZCENTER_BR, 112,140, 95,8 86 | AUTORADIOBUTTON "", IDC_RZCENTER_MOVE, 112,150, 95,8 87 | AUTORADIOBUTTON "", IDC_RZCENTER_CLOSE,112,160, 95,8 88 | 89 | LTEXT "", IDC_AUTOSNAP_HEADER,10,122,95,8 90 | COMBOBOX IDC_AUTOSNAP, 10,131 ,95,120, CBS_DROPDOWNLIST|CBS_HASSTRINGS|WS_TABSTOP|WS_VSCROLL 91 | LTEXT "", IDC_LANGUAGE_HEADER,10,145,95,8 92 | COMBOBOX IDC_LANGUAGE, 10,155,95,120, CBS_DROPDOWNLIST|CBS_HASSTRINGS|WS_TABSTOP|WS_VSCROLL 93 | 94 | GROUPBOX "", IDC_AUTOSTART_BOX ,3,175,212,43 95 | AUTOCHECKBOX "", IDC_AUTOSTART, 10,185,203,8 96 | AUTOCHECKBOX "", IDC_AUTOSTART_HIDE, 10,195,145,8 97 | AUTOCHECKBOX "", IDC_AUTOSTART_ELEVATE,10,205,145,8 98 | DEFPUSHBUTTON "", IDC_ELEVATE, 157,200,55,14 99 | 100 | // EDITTEXT IDC_HELPPANNEL,220,5,175,210, NOT WS_TABSTOP|ES_MULTILINE|ES_READONLY 101 | END 102 | 103 | ///////////////////////////////////////////////////////////////////////////// 104 | IDD_MOUSEPAGE DIALOG DISCARDABLE 0, 0, 220, 230 105 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 106 | CAPTION "" // MOUSE 107 | FONT 8, "Ms Shell Dlg" 108 | BEGIN 109 | GROUPBOX "", IDC_MOUSE_BOX, 3,1,212,178 110 | AUTORADIOBUTTON "", IDC_MBA1, 10,10,60,8, WS_GROUP 111 | AUTORADIOBUTTON "", IDC_MBA2, 75,10,60,8 112 | AUTORADIOBUTTON "", IDC_INTTB, 140,10,60,8 113 | AUTORADIOBUTTON "", IDC_WHILEM, 10,20,100,8 114 | AUTORADIOBUTTON "", IDC_WHILER,111,20,100,8 115 | 116 | LTEXT "", IDC_LMB_HEADER, 10,33,95,8 117 | COMBOBOX IDC_LMB, 105,30,105,160, MY_CBS_STYLE 118 | LTEXT "", IDC_MMB_HEADER, 10,47,95,8 119 | COMBOBOX IDC_MMB, 105,44,105,160, MY_CBS_STYLE 120 | LTEXT "", IDC_RMB_HEADER, 10,61,95,8 121 | COMBOBOX IDC_RMB, 105,58,105,160, MY_CBS_STYLE 122 | LTEXT "", IDC_MB4_HEADER, 10,75,95,8 123 | COMBOBOX IDC_MB4, 105,72,105,160, MY_CBS_STYLE 124 | LTEXT "", IDC_MB5_HEADER, 10,89,95,8 125 | COMBOBOX IDC_MB5, 105,86,105,160, MY_CBS_STYLE 126 | LTEXT "", IDC_SCROLL_HEADER,10,103,95,8 127 | COMBOBOX IDC_SCROLL,105,100,105,160, MY_CBS_STYLE 128 | LTEXT "", IDC_HSCROLL_HEADER,10,117,95,8 129 | COMBOBOX IDC_HSCROLL,105,114,105,160, MY_CBS_STYLE 130 | 131 | LTEXT "", IDC_MOVEUP_HEADER,10,131,105,8 132 | COMBOBOX IDC_MOVEUP,115,128,95,160, MY_CBS_STYLE 133 | LTEXT "", IDC_RESIZEUP_HEADER,10,145,105,8 134 | COMBOBOX IDC_RESIZEUP,115,142,95,160, MY_CBS_STYLE 135 | 136 | GROUPBOX "", IDC_TTBACTIONS_BOX, 6,155,206,21 137 | AUTOCHECKBOX "", IDC_TTBACTIONSNA, 12,165,95,8 138 | AUTOCHECKBOX "", IDC_TTBACTIONSWA, 112,165,95,8 139 | 140 | GROUPBOX "", IDC_HOTCLICKS_BOX, 3,179,212,51 141 | AUTOCHECKBOX "", IDC_MMB_HC, 10 ,188,80,10 142 | AUTOCHECKBOX "", IDC_MB4_HC, 10 ,198,80,10 143 | AUTOCHECKBOX "", IDC_MB5_HC, 10 ,208,80,10 144 | AUTOCHECKBOX "", IDC_LONGCLICKMOVE,10 ,218,203,10 145 | RTEXT "", IDC_HOTCLICKS_MORE, 100,186,110,32 146 | END 147 | 148 | ///////////////////////////////////////////////////////////////////////////// 149 | IDD_KBPAGE DIALOG DISCARDABLE 0, 0, 220, 225 150 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 151 | CAPTION "" // KEYBOARD 152 | FONT 8, "Ms Shell Dlg" 153 | BEGIN 154 | GROUPBOX "", IDC_KEYBOARD_BOX, 3,1,212,138 155 | LTEXT "", IDC_GRABWITHALT_H, 10,13,90,8 156 | COMBOBOX IDC_GRABWITHALT, 105,10,105,160, MY_CBS_STYLE 157 | LTEXT "", IDC_GRABWITHALTB_H,10,27,90,8 158 | COMBOBOX IDC_GRABWITHALTB, 105,24,105,160, MY_CBS_STYLE 159 | 160 | AUTOCHECKBOX "", IDC_SCROLLLOCKSTATE, 10,40,203,16, BS_MULTILINE 161 | AUTOCHECKBOX "", IDC_UNIKEYHOLDMENU, 10,60,203,16, BS_MULTILINE 162 | 163 | LTEXT "", IDC_SHORTCUTS_H, 10,82,90,8 164 | COMBOBOX IDC_SHORTCUTS_AC, 105,80,105,160, MY_CBS_STYLE 165 | RTEXT "vKey:", 0, 60,98,20,8 166 | EDITTEXT IDC_SHORTCUTS_VK, 85, 96, 16, 12 167 | LTEXT "", IDC_SHORTCUTS, 104,98,55,8 168 | AUTOCHECKBOX "", IDC_SHIFT, 10,98,50,8 169 | AUTOCHECKBOX "", IDC_CONTROL, 10,112,50,8 170 | AUTOCHECKBOX "", IDC_WINKEY, 60,112,50,8 171 | AUTOCHECKBOX "", IDC_ALT, 110,112,50,8 172 | DEFPUSHBUTTON "", IDC_SHORTCUTS_PICK, 160, 95, 50, 13 173 | DEFPUSHBUTTON "", IDC_SHORTCUTS_CLEAR, 160, 109, 50, 13 174 | DEFPUSHBUTTON "", IDC_SHORTCUTS_SET, 160, 123, 50, 13 175 | AUTOCHECKBOX "", IDC_USEPTWINDOW, 10,125,150,8 176 | 177 | GROUPBOX "", IDC_HOTKEYS_BOX, 3,139,212, 80 178 | LTEXT "", IDC_MODKEY_H, 10,152,150,8 179 | COMBOBOX IDC_MODKEY, 160,149,50,120, MY_CBS_STYLE 180 | AUTOCHECKBOX "", IDC_LEFTALT, 10,165,60,8 181 | AUTOCHECKBOX "", IDC_RIGHTALT, 10,175,60,8 182 | AUTOCHECKBOX "", IDC_LEFTWINKEY, 71,165,72,8 183 | AUTOCHECKBOX "", IDC_RIGHTWINKEY, 71,175,72,8 184 | AUTOCHECKBOX "", IDC_LEFTCTRL, 145,165,65,8 185 | AUTOCHECKBOX "", IDC_RIGHTCTRL, 145,175,65,8 186 | 187 | AUTOCHECKBOX "", IDC_KEYCOMBO, 10,187,203,8 188 | LTEXT "", IDC_HOTKEYS_MORE, 10,197,203,20 189 | END 190 | 191 | ///////////////////////////////////////////////////////////////////////////// 192 | IDD_ADVANCEDPAGE DIALOG DISCARDABLE 0, 0, 220, 225 193 | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_3DLOOK 194 | CAPTION "" // ADVANCED 195 | FONT 8, "Ms Shell Dlg" 196 | BEGIN 197 | GROUPBOX "", IDC_METRICS_BOX, 3,1,212,101 198 | LTEXT "", IDC_CENTERFRACTION_H, 10,12,130,8 199 | EDITTEXT IDC_CENTERFRACTION, 143, 10, 30, 12, ES_NUMBER 200 | LTEXT "/", IDC_STATIC, 175,12,7,8 201 | EDITTEXT IDC_SIDESFRACTION, 180, 10, 30, 12, ES_NUMBER 202 | 203 | LTEXT "", IDC_AEROHOFFSET_H, 10,25,90,8 204 | EDITTEXT IDC_AEROHOFFSET, 100, 23, 30, 12, ES_NUMBER 205 | RTEXT "", IDC_AEROVOFFSET_H, 132,25,45,8 206 | EDITTEXT IDC_AEROVOFFSET, 180, 23, 30, 12, ES_NUMBER 207 | 208 | LTEXT "", IDC_SNAPTHRESHOLD_H, 10,38,165,8 209 | EDITTEXT IDC_SNAPTHRESHOLD, 180, 36, 30, 12, ES_NUMBER 210 | LTEXT "", IDC_AEROTHRESHOLD_H, 10,51,165,8 211 | EDITTEXT IDC_AEROTHRESHOLD, 180, 49, 30, 12, ES_NUMBER 212 | LTEXT "", IDC_SNAPGAP_H, 10,64,165,8 213 | EDITTEXT IDC_SNAPGAP, 180, 62, 30, 12 214 | 215 | LTEXT "", IDC_AEROSPEED_H, 10,76,130,8 216 | EDITTEXT IDC_AEROSPEED, 140, 74, 30, 12, ES_NUMBER 217 | LTEXT "/", 0, 172,76,10,8 218 | LTEXT "", IDC_AEROSPEEDTAU, 178, 76, 20, 8, ES_READONLY 219 | LTEXT "ms", IDC_STATIC, 195,76,10,8 220 | 221 | LTEXT "", IDC_MOVETRANS_H, 10,90,100,8 222 | EDITTEXT IDC_MOVETRANS, 110, 88, 25, 12, ES_NUMBER 223 | 224 | DEFPUSHBUTTON "", IDC_TESTWINDOW, 138,88,73,12 225 | 226 | GROUPBOX "", IDC_BEHAVIOR_BOX, 3,103,212,122 227 | AUTOCHECKBOX "", IDC_MULTIPLEINSTANCES, 10,113,203,8 228 | AUTOCHECKBOX "", IDC_AUTOREMAXIMIZE, 10,123,203,8 229 | AUTOCHECKBOX "", IDC_AEROTOPMAXIMIZES, 10,133,203,8 230 | AUTOCHECKBOX "", IDC_AERODBCLICKSHIFT, 10,143,203,8 231 | AUTOCHECKBOX "", IDC_MAXWITHLCLICK, 10,153,203,8 232 | AUTOCHECKBOX "", IDC_RESTOREONCLICK, 10,163,203,8 233 | AUTOCHECKBOX "", IDC_FULLSCREEN, 10,173,203,8 234 | AUTOCHECKBOX "", IDC_BLMAXIMIZED, 10,183,203,8 235 | AUTOCHECKBOX "", IDC_FANCYZONE, 10,193,203,8 236 | AUTOCHECKBOX "", IDC_NORESTORE, 10,203,203,8 237 | AUTOCHECKBOX "", IDC_TOPMOSTINDICATOR, 10,213,203,8 238 | END 239 | 240 | ///////////////////////////////////////////////////////////////////////////// 241 | // Cursor 242 | IDI_FIND CURSOR DISCARDABLE "media/find.cur" 243 | 244 | ///////////////////////////////////////////////////////////////////////////// 245 | // Icon with lowest ID value placed first to ensure application icon 246 | // remains consistent on all systems. 247 | IDI_FIND ICON DISCARDABLE "media/find.ico" 248 | -------------------------------------------------------------------------------- /ziprelease.bat: -------------------------------------------------------------------------------- 1 | advzipNT -a4 -i 128 AltSnap_bin.zip AltSnap.txt AltSnap.exe hooks.dll AltSnap.ini AltSnap.xml License.txt Lang\* 2 | Deflopt AltSnap_bin.zip 3 | -------------------------------------------------------------------------------- /zones.c: -------------------------------------------------------------------------------- 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 | * (C) Raymond GILLIBERT * 3 | * Functions to handle Snap Layouts under AltSnap * 4 | * General Public License Version 3 or later (Free Software Foundation) * 5 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 6 | 7 | #include "hooks.h" 8 | static void MouseMove(POINT pt); 9 | static void ShowSnapLayoutPreview(unsigned char yep); 10 | 11 | enum { MAX_ZONES=2048, MAX_LAYOUTS=10 }; 12 | #define INVALID_ZONE_IDX 0xffffffffU 13 | 14 | RECT *Zones[MAX_LAYOUTS]; 15 | unsigned nzones[MAX_LAYOUTS]; 16 | DWORD Grids[MAX_LAYOUTS]; 17 | 18 | enum { ZONES_PREV_HIDE=0, ZONES_PREV_SHOW=1 }; 19 | 20 | 21 | static void freezones() 22 | { 23 | unsigned i; 24 | for (i=0; i MAX_ZONES) return 0; 30 | 31 | long *ZONE = (long *)zone; 32 | char zname[32]=""; 33 | TCHAR zaschii[128]; 34 | 35 | LPCTSTR txt = GetSectionOptionCStr(inisection, ZidxToZonestrA(laynum, idx, zname), NULL); 36 | if (!txt || !txt[0]) 37 | return 0; 38 | //LOGA("Zone(%u, %u) = %S", laynum, idx, txt); 39 | // Copy to modifyable buffer. 40 | lstrcpy_s(zaschii, ARR_SZ(zaschii), txt); 41 | TCHAR *oldptr, *newptr; 42 | oldptr = &zaschii[0]; 43 | UCHAR i; 44 | for (i=0; i < 4; i++) { 45 | newptr = lstrchr(oldptr, ','); 46 | if (!newptr) return 0; 47 | *newptr = '\0'; 48 | newptr++; 49 | if(!*oldptr) return 0; 50 | ZONE[i] = strtoi(oldptr); // 0 left, 1 top, 2 right, 3 bottom; 51 | oldptr = newptr; 52 | } 53 | return 1; 54 | } 55 | static void ReadZonesFromLayout(const TCHAR *inisection, unsigned laynum) 56 | { 57 | nzones[laynum] = 0; 58 | Zones[laynum] = NULL; 59 | RECT tmpzone; 60 | while (ReadRectFromini(&tmpzone, laynum, nzones[laynum], inisection)) { 61 | RECT *tmp = (RECT *)realloc( Zones[laynum], (nzones[laynum]+1) * sizeof(*tmp) ); 62 | if(!tmp) return; 63 | Zones[laynum] = tmp; 64 | CopyRect(&Zones[laynum][nzones[laynum]++], &tmpzone); 65 | } 66 | } 67 | // Load all zones from ini file 68 | static void ReadZones(const TCHAR *inisection) 69 | { 70 | UCHAR i; 71 | for(i=0; ileft+(( i ) * (mon->right - mon->left))/Nx; 103 | Zones[layout][nz].top = mon->top +(( j ) * (mon->bottom - mon->top))/Ny; 104 | Zones[layout][nz].right = mon->left+((i+1) * (mon->right - mon->left))/Nx; 105 | Zones[layout][nz].bottom= mon->top +((j+1) * (mon->bottom - mon->top))/Ny; 106 | nz++; 107 | } 108 | } 109 | } 110 | nzones[layout] = nz; 111 | } 112 | static void ReadGrids(const TCHAR *inisection) 113 | { 114 | UCHAR i; 115 | char gnamex[8]; 116 | char gnamey[8]; 117 | strcpy(gnamex, "GridNx"); 118 | strcpy(gnamey, "GridNy"); 119 | gnamex[7] = '\0'; 120 | gnamey[7] = '\0'; 121 | for (i=0; i < ARR_SZ(Grids); i++) { 122 | Grids[i] = 0; 123 | unsigned short GridNx = GetSectionOptionInt(inisection, gnamex, 0); 124 | unsigned short GridNy = GetSectionOptionInt(inisection, gnamey, 0); 125 | if (GridNx && GridNy && GridNx*GridNy <= MAX_ZONES) { 126 | Grids[i] = GridNx | GridNy << 16; // Store grid dimentions 127 | GenerateGridZones(i, GridNx, GridNy); 128 | } 129 | // GridNx1, GridNx2, GridNx3... 130 | gnamex[6] = '1' + i; 131 | gnamey[6] = '1' + i; 132 | } 133 | } 134 | // Recalculate the zones from the Grid info. 135 | // Needed in case resolution changes. 136 | static void RecalculateZonesFromGrids() 137 | { 138 | UCHAR i; 139 | for (i=0; i>1; 150 | long dy = (pt.y - Zpt.y)>>1; 151 | 152 | return dx*dx + dy*dy; 153 | } 154 | 155 | 156 | static xpure unsigned long ClacPtRectDist(const POINT pt, const RECT *zone) 157 | { 158 | POINT Zpt = { (zone->left+zone->right)/2, (zone->top+zone->bottom)/2 }; 159 | return PtDist2(pt, Zpt); 160 | } 161 | 162 | static unsigned GetNearestZoneDist(POINT pt, unsigned long *dist_) 163 | { 164 | RECT * const lZones = Zones[conf.LayoutNumber]; 165 | if(!lZones) return 0; 166 | unsigned long dist = 0xffffffff; 167 | unsigned idx = 0; 168 | unsigned i; 169 | for (i=0; i < nzones[conf.LayoutNumber]; i++) { 170 | unsigned long dst = ClacPtRectDist(pt, &lZones[i]); 171 | if ( dst < dist ) { 172 | dist = dst; 173 | idx = i; 174 | } 175 | } 176 | *dist_ = dist; 177 | return idx; 178 | } 179 | 180 | static unsigned GetZoneNearestFromPoint(POINT pt, RECT *urc, int extend) 181 | { 182 | 183 | RECT * const lZones = Zones[conf.LayoutNumber]; 184 | if(!lZones) return 0; 185 | unsigned i, ret=0; 186 | SetRectEmpty(urc); 187 | int iz = conf.InterZone; 188 | iz = (iz * iz) << 1; 189 | unsigned long mindist=0; 190 | 191 | i = GetNearestZoneDist(pt, &mindist); 192 | ret = mindist != 0xffffffff; 193 | if (!ret) return 0; 194 | CopyRect(urc, &lZones[i]); 195 | mindist += iz; // Add iz tolerance. 196 | for (i=0; i < nzones[conf.LayoutNumber]; i++) { 197 | 198 | BOOL inrect = mindist > ClacPtRectDist(pt, &lZones[i]); 199 | if ((state.ctrl||extend) && !inrect) 200 | inrect = mindist > ClacPtRectDist(extend?state.shiftpt:state.ctrlpt, &lZones[i]); 201 | 202 | if (inrect) { 203 | UnionRect(urc, urc, &lZones[i]); 204 | ret++; 205 | } 206 | } 207 | return ret; 208 | } 209 | 210 | static unsigned GetZoneContainingPoint(POINT pt, RECT *urc, int extend) 211 | { 212 | 213 | RECT * const lZones = Zones[conf.LayoutNumber]; 214 | if(!lZones) return 0; 215 | unsigned i, ret=0; 216 | SetRectEmpty(urc); 217 | int iz = conf.InterZone; 218 | for (i=0; i < nzones[conf.LayoutNumber]; i++) { 219 | if (iz) InflateRect(&lZones[i], iz, iz); 220 | 221 | int inrect=0; 222 | inrect = PtInRect(&lZones[i], pt); 223 | if ((state.ctrl||extend) && !inrect) 224 | inrect = PtInRect(&lZones[i], extend?state.shiftpt:state.ctrlpt); 225 | 226 | if (iz) InflateRect(&lZones[i], -iz, -iz); 227 | if (inrect) { 228 | UnionRect(urc, urc, &lZones[i]); 229 | ret++; 230 | } 231 | } 232 | return ret; 233 | } 234 | static unsigned GetZoneFromPoint(POINT pt, RECT *urc, int extend) 235 | { 236 | switch (conf.ZSnapMode) { 237 | case 0: return GetZoneContainingPoint(pt, urc, extend); 238 | case 1: return GetZoneNearestFromPoint(pt, urc, extend); 239 | } 240 | // Invalid Snap mode! 241 | return 0; 242 | } 243 | static int pure IsResizable(HWND hwnd); 244 | 245 | static void ActionToggleSnapToZoneMode() 246 | { 247 | if (conf.UseZones&1 && state.action == AC_MOVE) { 248 | state.usezones = !state.usezones; 249 | MouseMove(state.prevpt); 250 | } 251 | } 252 | static void MoveSnapToZone(POINT pt, int *posx, int *posy, int *width, int *height) 253 | { 254 | if(!(conf.UseZones&1) || state.mdiclient || !state.resizable) // Zones disabled 255 | return; 256 | 257 | static POINT oldpt; 258 | if(state.Speed > conf.AeroMaxSpeed) 259 | pt=oldpt; // do not move the window if speed is too high. 260 | else 261 | oldpt=pt; 262 | 263 | if (conf.UseZones&8 && state.snap != conf.AutoSnap) // Zones toggled by other click 264 | return; 265 | 266 | if (!state.usezones) { 267 | ShowSnapLayoutPreview(ZONES_PREV_HIDE); 268 | return; 269 | } 270 | 271 | ShowSnapLayoutPreview(ZONES_PREV_SHOW); 272 | RECT rc, bd; 273 | unsigned ret = GetZoneFromPoint(pt, &rc, conf.UseZones&4); 274 | if (!ret) return; // Outside of a rect 275 | 276 | LastWin.end = 0; 277 | FixDWMRect(state.hwnd, &bd); 278 | InflateRectBorder(&rc, &bd); 279 | 280 | SetRestoreData(state.hwnd, state.origin.width, state.origin.height, SNAPPED|SNZONE); 281 | *posx = rc.left; 282 | *posy = rc.top; 283 | *width = rc.right - rc.left; 284 | *height = rc.bottom - rc.top; 285 | } 286 | 287 | static xpure int IsPtInCone(POINT pt, POINT op, UCHAR direction) 288 | { 289 | const long dx = pt.x - op.x, dy = pt.y - op.y; 290 | switch (direction) { 291 | case 0: // LEFT 292 | return dx <= 0 && (dy <= -dx && dy > dx); 293 | 294 | case 1: // TOP 295 | return dy <= 0 && (dx <= -dy && dx > dy); 296 | 297 | case 2: // RIGHT 298 | return dx > 0 && (dy <= dx && dy > -dx); 299 | 300 | case 3: // BOTTOM 301 | return dy > 0 && (dx <= dy && dx > -dy); 302 | } 303 | return 0; 304 | } 305 | static unsigned GetNearestZoneFromPointInDirection(const RECT *rc, RECT *out, UCHAR direction) 306 | { 307 | unsigned idx = INVALID_ZONE_IDX; 308 | RECT * const lZones = Zones[conf.LayoutNumber]; 309 | unsigned nZones = nzones[conf.LayoutNumber]; 310 | if(!lZones) return 0; 311 | 312 | POINT opt = { (rc->left+rc->right)/2, (rc->top+rc->bottom)/2 }; 313 | 314 | unsigned long dist = 0xffffffff; 315 | for(unsigned i=0; i < nZones; i++) { 316 | const RECT *zrc = &lZones[i]; 317 | const POINT pt = { (zrc->left+zrc->right)/2, (zrc->top+zrc->bottom)/2 }; 318 | unsigned long dst = PtDist2(pt, opt); 319 | if (!EqualRect(rc, zrc) && dst < dist && IsPtInCone(pt, opt, direction)) { 320 | dist = dst; 321 | idx = i; 322 | } 323 | } 324 | 325 | if (idx != INVALID_ZONE_IDX) { 326 | CopyRect(out, &lZones[idx]); 327 | return 1; 328 | } 329 | 330 | return 0; 331 | } 332 | 333 | // 334 | //static void SnapToRect(HWND hwnd, RECT *fr) 335 | //{ 336 | // RECT bd; 337 | // LastWin.end = 0; 338 | // FixDWMRect(hwnd, &bd); 339 | // InflateRectBorder(fr, &bd); 340 | // 341 | // SetRestoreData(hwnd, state.origin.width, state.origin.height, SNAPPED|SNZONE); 342 | // MoveWindowAsync(hwnd, fr->left, fr->top, CLAMPW(fr->right-fr->left), CLAMPH(fr->bottom-fr->top)); 343 | //} 344 | 345 | static void SetOriginFromRestoreData(HWND hnwd, enum action action); 346 | static HMONITOR GetMonitorInfoFromWin(HWND hwnd, MONITORINFO *mi); 347 | static void MoveWindowToTouchingZone(HWND hwnd, UCHAR direction, UCHAR extend) 348 | { 349 | if(!(conf.UseZones&1) || state.mdiclient || !state.resizable) // Zones disabled 350 | return; 351 | 352 | SetOriginFromRestoreData(hwnd, AC_MOVE); 353 | // 1st get current window position. 354 | RECT rc; 355 | GetWindowRectL(hwnd, &rc); 356 | POINT pt; 357 | 358 | int offset = abs(conf.InterZone)+16; 359 | 360 | if (direction == 0) { // LEFT 361 | pt.x = rc.left - offset; // Mid Left segment 362 | pt.y = (rc.top+rc.bottom)/2; 363 | } else if (direction == 1) { // TOP 364 | pt.x = (rc.right+rc.left)/2; // Mid Top segment 365 | pt.y = rc.top - offset; 366 | } else if (direction == 2) { // RIGHT 367 | pt.x = rc.right + offset; // Mid Right segment 368 | pt.y = (rc.top+rc.bottom)/2; 369 | } else if (direction == 3) { // BOTTOM 370 | pt.x = (rc.right+rc.left)/2; // Mid Bottom segment 371 | pt.y = rc.bottom + offset; 372 | } 373 | if (IsZoomed(hwnd) && extend) return; 374 | 375 | // Clamp point inside monitor 376 | MONITORINFO mi; 377 | GetMonitorInfoFromWin(hwnd, &mi); 378 | ClampPointInRect(&mi.rcWork, &pt); 379 | 380 | RECT zrc; 381 | unsigned ret=0; 382 | switch (conf.ZSnapMode) { 383 | case 0: ret = GetZoneContainingPoint(pt, &zrc, 0); break; 384 | case 1: ret = GetNearestZoneFromPointInDirection(&rc, &zrc, direction); break; 385 | } 386 | if (!ret) return; // Outside of a rect 387 | 388 | RECT fr; // final rect... 389 | if (extend) { // extend the zone instead. 390 | UnionRect(&fr, &rc, &zrc); // Union of original and new rect 391 | } else { 392 | CopyRect(&fr, &zrc); 393 | } 394 | LastWin.end = 0; 395 | RECT bd; 396 | FixDWMRect(hwnd, &bd); 397 | InflateRectBorder(&fr, &bd); 398 | 399 | SetRestoreData(hwnd, state.origin.width, state.origin.height, SNAPPED|SNZONE); 400 | MoveWindowAsync(hwnd, fr.left, fr.top, CLAMPW(fr.right-fr.left), CLAMPH(fr.bottom-fr.top)); 401 | } 402 | // Sets urc as the union of all the rcs array or RECT, of length N 403 | static void UnionMultiRect(RECT *urc, const RECT *rcs, unsigned N) 404 | { 405 | CopyRect(urc, &rcs[0]); 406 | while (--N) { 407 | rcs++; 408 | urc->left = min(urc->left, rcs->left); 409 | urc->top = min(urc->top, rcs->top); 410 | urc->right = max(urc->right, rcs->right); 411 | urc->bottom = max(urc->bottom, rcs->bottom); 412 | } 413 | } 414 | static pure DWORD GetLayoutRez(int laynum) 415 | { 416 | laynum = CLAMP(0, laynum, ARR_SZ(Zones)-1); 417 | if (conf.UseZones&2) { 418 | // In Grid mode we return the grid dimentions! 419 | return Grids[laynum]; 420 | } 421 | unsigned nz = nzones[laynum]; 422 | const RECT *zone = Zones[laynum]; 423 | if (!zone || !nz) return 0; 424 | RECT urc; 425 | UnionMultiRect(&urc, zone, nz); 426 | return (urc.right-urc.left) | (urc.bottom-urc.top)<<16; 427 | } 428 | // Calculate the dimentions of union rectangle that contains all 429 | // the work area of every monitors. 430 | static DWORD GetFullMonitorsRez() 431 | { 432 | // Enumerate monitors 433 | EnumDisplayMonitors(NULL, NULL, EnumMonitorsProc, 0); 434 | if (!monitors || !nummonitors) 435 | return 0; // ERROR! do nothing 436 | RECT urc; 437 | UnionMultiRect(&urc, monitors, nummonitors); 438 | 439 | // Return dimentions width:height 440 | return (urc.right-urc.left) | (urc.bottom-urc.top)<<16; 441 | } 442 | 443 | // Return a layout number if its dimentions exactly fit 444 | // the display monitor. 445 | static int GetBestLayoutFromMonitors() 446 | { 447 | if (!(conf.UseZones&1)) 448 | return -1; 449 | if (conf.UseZones&2) { 450 | // Grid mode! Do not change Grid, just recalculate them all... 451 | RecalculateZonesFromGrids(); 452 | return -1; // DONE! 453 | } 454 | DWORD curRZ = GetLayoutRez(conf.LayoutNumber); 455 | 456 | // If the current rez is 0:0 we should not change it. 457 | // Because it can be used as a dummy mode, plus a user 458 | // might have selected it in advance to configure it 459 | // later for the new display settings, so selecting 460 | // an other one would bother him. 461 | if (!curRZ) 462 | return -1; 463 | 464 | // Check if the current Layout is good for the current monitor 465 | DWORD monRZ; 466 | if (nummonitors <= 1) { 467 | RECT mrc; 468 | SystemParametersInfo(SPI_GETWORKAREA, 0, &mrc, 0); 469 | monRZ = (mrc.right-mrc.left) | (mrc.bottom-mrc.top)<<16; 470 | // In Single monitor mode we use SPI_GETWORKAREA. 471 | // Because EnumDisplayMonitor often gives bad values. 472 | // I am unsure on how to properly handle multiple monitors... 473 | if(monRZ == curRZ) { 474 | return -1; // Current layout is good! 475 | } 476 | } else if ( (monRZ = GetFullMonitorsRez()) == curRZ ) { 477 | // GetFullMonitorsRez gives us the union of all monitors.rcWork 478 | return -1; // Current layout is good! 479 | } 480 | 481 | UCHAR i; 482 | for (i=0; ileft + rc->right - sz.cx) / 2 + opt.x; 526 | // int txtY = (rc->top + rc->bottom - sz.cy) / 2 + opt.y; 527 | // TextOut(ps.hdc, txtX, txtY, num, txtlen); 528 | Rectangle(ps.hdc, rc->left+opt.x, rc->top+opt.y, rc->right+opt.x, rc->bottom+opt.y); 529 | } 530 | } 531 | // SelectObject(ps.hdc, oldfont); // Restore old font 532 | SelectObject(ps.hdc, oldBrush); // Restore old pen 533 | SelectObject(ps.hdc, oldpen); // Restore old brush 534 | 535 | EndPaint(hwnd, &ps); 536 | 537 | // DeleteObject(font); 538 | } return 0; 539 | 540 | case WM_RBUTTONUP: 541 | case WM_MBUTTONUP: 542 | case WM_LBUTTONUP: 543 | ShowWindow(hwnd, SW_HIDE); 544 | break; 545 | 546 | case WM_DESTROY: { 547 | DeleteObject(pen); 548 | } break; 549 | } 550 | return DefWindowProc(hwnd, msg, wp, lp); 551 | } 552 | 553 | 554 | static void ShowSnapLayoutPreview(unsigned char yep) 555 | { 556 | if (g_zphwnd) { // Window was created 557 | if (!yep) { 558 | ShowWindow(g_zphwnd, SW_HIDE); 559 | } else if (!IsWindowVisible(g_zphwnd)) { 560 | ShowWindow(g_zphwnd, SW_SHOW); 561 | SetWindowLevel(g_zphwnd, state.hwnd); // Behind currently moving hwn 562 | } 563 | } 564 | } 565 | 566 | static void ZonesPrevResetRegion() 567 | { 568 | if (conf.ZonesPrevwOpacity != 0) 569 | return; 570 | POINT opt = { 0, 0 }; 571 | RECT wrc; 572 | GetWindowRect(g_zphwnd, &wrc); 573 | ScreenToClient(g_zphwnd, &opt); 574 | HRGN hregion = CreateRectRgn(0,0,0,0); 575 | if (Zones[conf.LayoutNumber]) { 576 | for (unsigned i=0; i < nzones[conf.LayoutNumber]; i++) { 577 | RECT rc; 578 | CopyRect(&rc, &Zones[conf.LayoutNumber][i]); 579 | OffsetRect(&rc, opt.x, opt.y); 580 | HRGN tmpr = CreateRectRgn(rc.left, rc.top, rc.right, rc.top+4); // top ^^^^ 581 | CombineRgn(hregion, hregion, tmpr, RGN_OR); 582 | DeleteObject(tmpr); 583 | tmpr = CreateRectRgn(rc.left, rc.bottom-4, rc.right, rc.bottom); // ____ bottom 584 | CombineRgn(hregion, hregion, tmpr, RGN_OR); 585 | DeleteObject(tmpr); 586 | tmpr = CreateRectRgn(rc.left, rc.top, rc.left+4, rc.bottom); // left |... 587 | CombineRgn(hregion, hregion, tmpr, RGN_OR); 588 | DeleteObject(tmpr); 589 | tmpr = CreateRectRgn(rc.right-4, rc.top, rc.right, rc.bottom); // ...| right 590 | CombineRgn(hregion, hregion, tmpr, RGN_OR); 591 | DeleteObject(tmpr); 592 | } 593 | } 594 | SetWindowRgn(g_zphwnd, hregion, FALSE); 595 | } 596 | 597 | static unsigned readhotkeys(const TCHAR *inisection, const char *name, const TCHAR *def, UCHAR *keys, unsigned MaxKeys); 598 | static void SnapLayoutPreviewCreateDestroy(const TCHAR *inisection) 599 | { 600 | if(!conf.ShowZonesPrevw) 601 | return; 602 | if (inisection) { 603 | int bgcol[2], bdcol[2]; 604 | readhotkeys(inisection, "ZonesPrevwBGCol", TEXT("FF FF FF"), (UCHAR *)&bgcol[0], 3); 605 | readhotkeys(inisection, "ZonesPrevwBDCol", TEXT("00 00 00"), (UCHAR *)&bdcol[0], 3); 606 | g_ZPrevBDCol = bdcol[0]; 607 | const UCHAR opacity = conf.ZonesPrevwOpacity; 608 | const UCHAR usetrans = opacity!=0 && opacity!=255; 609 | const WNDPROC wproc = opacity==0? DefWindowProc: SnapLayoutWinProc; 610 | const HBRUSH wbrush = opacity==0? CreateSolidBrush(bdcol[0]): CreateSolidBrush(bgcol[0]); 611 | const WNDCLASSEX wnd = { 612 | sizeof(WNDCLASSEX), 0 613 | , wproc 614 | , 0, 0, hinstDLL 615 | , NULL, NULL, wbrush 616 | , NULL, APP_NAME"-ZonesPreview", NULL }; 617 | RegisterClassEx(&wnd); 618 | 619 | int left=0, top=0, width, height; 620 | if(GetSystemMetrics(SM_CMONITORS) >= 1) { 621 | left = GetSystemMetrics(SM_XVIRTUALSCREEN); 622 | top = GetSystemMetrics(SM_YVIRTUALSCREEN); 623 | width = GetSystemMetrics(SM_CXVIRTUALSCREEN); 624 | height = GetSystemMetrics(SM_CYVIRTUALSCREEN); 625 | } else { // NT4... 626 | width = GetSystemMetrics(SM_CXFULLSCREEN)+256; 627 | height= GetSystemMetrics(SM_CYFULLSCREEN)+256; 628 | } 629 | g_zphwnd = CreateWindowEx(usetrans? WS_EX_TOOLWINDOW|WS_EX_LAYERED: WS_EX_TOOLWINDOW 630 | , wnd.lpszClassName, NULL, WS_POPUP 631 | , left, top, width, height, g_mainhwnd, NULL, hinstDLL, NULL); 632 | SetWindowLevel(g_zphwnd, state.hwnd); // Behind 633 | if (usetrans) 634 | SetLayeredWindowAttributesL(g_zphwnd, 0, opacity, LWA_ALPHA); 635 | 636 | // Set Window Region to only show outlines if needed... 637 | ZonesPrevResetRegion(); 638 | 639 | } else { 640 | if (g_zphwnd) DestroyWindow(g_zphwnd); 641 | UnregisterClass(APP_NAME"-ZonesPreview", hinstDLL); 642 | } 643 | } 644 | 645 | static void SetLayoutNumber(WPARAM number) 646 | { 647 | conf.LayoutNumber=CLAMP(0, number, 9); 648 | ZonesPrevResetRegion(); // re-calculate 649 | } 650 | -------------------------------------------------------------------------------- /zzip.bat: -------------------------------------------------------------------------------- 1 | advzipNT -a4 -i 16 AltSnap_src.zip AltSnap.txt AltSnap.ini AltSnap.xml altsnap.nsi License.txt altsnap.c altsnap.rc config.c hooks.c hooks.rc languages.c languages.h resource.h tray.c hooks.h unfuck.h nanolibc.h window.rc AltSnap.exe.manifest makefile media\* Lang\* 2 | 3 | Deflopt AltSnap_src.zip 4 | --------------------------------------------------------------------------------