├── .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 |
--------------------------------------------------------------------------------