6~#l=qoTjFBe`@
z`Fg?hz#NFi-^K*p+xYWc^cS8hJg@Sl0^`N?z{a1_#=>+?X=?%Nhpk)O>yw3NRl)v0^Q~punzxaj?GH_}6nF
z$N!)D%kf_~uiDuEo|;#H|24bAZyS*>cuSwdn_^AjjnYPDegNC(6%*n=%@;7o?L6}-
zuSoW40ohB1Xn$a~L1}h`ecH8NP~H0XqUwOmd;xv{8wB$Ml;#V}4^Y~5IQOZ-(<;q>
znjg4XvXctt2PkbFptQAsW6eK3syaL->{_(Z5n$_v`GVsln^iEMlH;G_KXlQrTAC}Y
z|9cj&f7V+t+o!DUpEVlZExe<$_67I=AQk}Ts@XqfuULTjjqj-a2iL#{0Jd*-8`*yp
z3#`yNb}x1fu7lkJeKngUPUvO-bu3_hsP-vb2Oj{$0&tT!slt3fWdFD5IP*p32Po}Y
z=yG+zY@f1U``=5~fMvq;d$sC@%>|nWlphrSrty0z>of=
zVDpQ)VAra3eZJ&|%>~BaSgbl+FPNk7wy?Qs{+lr~T{Hd*3N{ZYSp&e<0ZNzJW{w(<;jI;9?aEeHW%(v-PSsrUtANrfQN*|h4^~I<^sNdc3~v`pRtD=|BY|_
zKcjK~M&SyTHt&d=z!V;AW3%&dRzTnORKG}Q$*EIia
z`opiCQaD+qVZH$SH@H{y1+NzHc~2C$Pka<$>xTJ(*^(Xa_<6P5cU5)lXM~Oam8zSs
zwfm>EIZ%(kjW6@yg91L={447oTqk;sKl9+?!b+9572a0~T+{XhcdE{M4mSSv9AMlH
z8-K2C-}VZY`LvV_;sz
z>8cy2sSc-#UcSKm0Og4lC#Vh<(@`E@VYZIUjHX1
zV75p;C0*g8X!`GIIHuz5gf>j0(Ag=iksYXReL)MIUP0hxV1OLh2}t@Tl<&p#u+Szs)4{MW4o
z8`JoIOXCjM_8SHEZD2lt()<8rFF$}kuyugad_lA(VE=~s0m@!}0DoZXz<9-kwhoL}
zOu!mom@hCtKxw`J`!}LBq4opVz8%xn|8K2xzFlBk-z?bp*K;5mf93&x0~mLMH2{Vi
z|9UNm#-Dj$Yk{o;l(rTOH~wQ06PPcsb)eo8)N8>Rx-VnC>c%|P;q;2rR0rljukmLd
z^csK0+~z<%{oBl&U}H}?t1y!NA7lMqVWmpL=0Y?N
zSQC29gE}s>b%64U3Y!Zy2PkbGP}*FuJwZJW>b1aP!i_aQz_{C7IZkyL?!W){86ES@
zLXLm8AE?)Y$(|n?&G>JrvEROcE&r`>gGw+TKxuw}(tN>aV?x#d!+e4H0ZQ`)ksrVx
zm@mNo4PrsV)`8*nhog-NZ5^0Q`2lR-){N<@!@g18&t&?13$bkhKmLz`jek7{qVXS#
zn4s7A*K2{T1NHdVYk`eDrL6_SjsJ#}A7Jb)mvDsY@FN@RsMO~<{{MW3XtXimWXTVW
zc>L=*p}9Z|{8Hfom2j6ZUoc*4fyITa2fcj3XxD9d+ZWj0u#O2QQ+}Y|@jpRx;MT&^Dq*#_u`m&_06qYsSa2+20gDSe
z`VM1#&kx}Df$=}Ru)9k5YA>6wKhv@MiNV7ADuMN2Re^cXYb~%nK^+rjeqj9HAF!NJ
zU4Bwy1)JAn+^eo*_Y;GK9RKdMfc4Rc)&h$IC@m(WTv%A3(l}Ff;|$edeub^$lxEY|
zw_$NUWj*dzAImmkRdz(4=~z<9-kHYX@;uKZE;eG8ka
zgiU(ceA8z-&wTzvs=rrwMCBa?8-GgM7i4~*`(3i(#vgy+{Xmm1h{hbBVgBPMs_z0#
z8vji+2VgH@{eN2Z4+?8k!YksL!jmdlFW|Alqbl(m
z@UXCT1-}9h3d=RzuR3cC+*5J4>Tstp|8tw_hOJ4=*_#VDsRSRhnvWtbg%#qO!c{7l
z7p_zZ~$eh&tyS;7aCY6#=lYIMRo^vTb)XN-
z3qY3_7O0zUFHjxOuVK1fBw3_ie4+V6i*ITjNBTWU=b&RCmj$L{^jzx~y~3a{{mxMR
z=mNTiBgGMg!&DwxI9MedB>q%5P^IyE)s5e&4!;q5I;(LYN
zRBm6GqH-<$jOj?u)%WH2Z`|X*ndZP2g&kDF&SHtS`16PJSG_;q
z)cHI4$01+P!oQBCZ{Gl~wY%(hf3ZYN8JMd7*T4M-2DaI19c$b9f2o1gKx!a0kQzu0
zqy|z0sez&ag~a^!bQ8gELbn$DM(uMA@EbORW2|mv{aZJaQJTD0X}_0iQ`&FsIF|d}
zO3;rHkE_n1@1GF-Hu2lyd*b`z2c@(+?R_fh_75fJ_q{(ZP_IG0Zw0>xrcG)5RCQxN
z)nWez4v-u;es96=AL+-GktjgN^LtHx=X{npr<4m+p6NJ4ZJ1xEe;-f%bcg+ID=X{Y
zc=J2@CQjC8a8kjyO>QNh^ZndA--VvP&_)M3j`5o&xOdJ!TcC%9qSk@$xAoQcslHeH
z?fQwj7MvjF2!6XhyD&>799KA2CCn6q;+Vn=m0-VTpRPJ^??9c;xi;tiS~UKxKz+ts
z$7VR5KA$fZm3puK+nCdTbWQ*5Zz3=rb)T)jb)T)Tbsqg9`_#{F6Wr+z0ynx!6>6*@I;C9h$bYHV-(5Il8~t
zw(h^$n+wMN3UPt3{%=S+U=HA8(9`y=|657Mx^umt?{J>5{`Z;(XX-exc`#XR0YAYU
zV!rL{`oE22zZ5HljsJ$G1Nx5*;G1`K{ohtH)`uHKN1y}KgUth*3r#+8vik%2&)UKI
zVHZ&bz_f6wZ|9>ZL75M*J2OEk%=+*x(s?Wa{w}}hIhNuJl|8x=A
zKmGrMxKmstY8|Xld$o98yd?d9;Jax*CRmGzDQAj7ag3NDSli}{yTyIt2Em#{zZrXC#-j!CxVL}$|3`6`
zxLDLW;2yaT`c5An70U(vuXS*h+T7#&g+HrA2XBcr!gTP0>Z8#C_rQ6~(FKD3*E*o@
zH;enlgW?{64(K;J!1tji;;$yn{|8m)9=HbM^RPe%_X+xq4uPem)&aVv&;KoI9dK@~gICqAbwHoF@7fmVf0GU#*Jt$qI8p0>
z`(bRjKXkx6xLZsU^qq2sh{pfRlK)9OATAZ?!1Ta;qu=j}*9Cn?KR!M{h7SHF{!{#y
z_`9%q!1?|71N20{(D^B1mZ)`rT`v*n7Jc3<=8NfqzEk2W@Ev~s)Bl6SL*g<~>tMOs
zH;PrIL@!GP{jYUE-E_e5fK6N{t`*mas|DA)Qd}XHiTe9E-+a%7svCSCed9Y$6(@?>
zqSgUzbih1VEa*G3qXm7Z92A@z_5WbW9~Rt?zo+`X>|Q!L&ie0df$v`=&Jkyev&2Gy
z-}<=r3(S4|MX&xpqR%fE8=?++_5UmC^PvLY!kk10ria=Vdd&ly3)m?
zIOZzM6Q_&Q1oIp_XHMg@0NZ8!PAJS#dAwkr*S5eo!=N}u(09sX1?T(uPyY`S_zknm
z4NV7w>KpzN-TD3RS0y`Ku;$dh2_4|C@MHK>;B)4L`6=@Ul+2G61WHyt3qU2r{O1k*un3-tdK
zLBAgmtHmvX?=(BG{&TD!|Lr6@QgH8AiCPD5sr^RbO_int`djOO^^VV87U&9I5|KZ+
zPjYl*x}v;8FxI96n+tr#yadL_bm09#N1vfj^u%~QCLR{Y3i?iok7(-uQTpr!akZ#*
z@V?rA7Vil3K);v+^uN}@Dz)Dg=;$>;-=7!f3$FvlhijoPj-g+SapV(Ul^mUNZ|H#j
zEfw^?)&aI=Izj$ZivM9QVCKa9>^r9DBcD
zzVMx^#D!v^@H*gL7|+)PI%Vw9&ncqT0W$81+GvLonC4
zXLMkCsBPg2$(M=sac!jUa|ERyf9pTG!)I@ZI-uVth^FyBMxU(_^uN|YZ41oXD@8pI
zm~-A1@CO$O<}~wliRg$6#QBBVA1s!Pxq6N`Tbv~#Td*}@o<2WaoF+~c-WKo&K0aXV
zoBF?_KAS1t6xWFjQ3v!Loka70s^rItw*`I}9he?A6kDM0%!_FL?tI8%1;(EB5S*&*T|;s&uH>VUDwPaYwLJpV-(
zlKoV?B#4`C6{d#`#TMv0>&8A}n|l09|M!%fwTT$uK0%zfq3D3Vvre*Jeo1^X=>N8o
z?vLV|
zm`wzFV*Y<1)(G_Rlwe*wCLR?Ji`C*G@u0Y0U^n-OyTx4s{jn#)pWGstPh6K=f$5X=
zg&5;%v0PYudAaJul@?1{9C?9c*y*`qkvLlrFD?*g2C&}!yZC(F&!)PLn)k~2OQ%VMYaY1V4uwc`c%Pi#hf
zGAND~)5SEwm>woryABrI?}6g?;uqpaVrTI=F{1x=kdEI>d`kR8a6RV45rXfd4ty`)
z`KJQk{YUYK0_Xi!{6_p*{7U>%aBn{s2Z;T}euDLf@A|RezJDn85sbt41!D-`E&Q9x
zZ;Nk=Z-~7Ld#Kz^>>#!gjAzqur#v-~8b}SK22um5fz-f8rvb%AWBTv^uG8RtR+c~O
zu;c%%lYi!ob>*hMTvFs4Yw7jzKkM}I8CULTdL64lgxc$8BxEcK!VSx@5PB
zi-q-pdwE$<@?Fd+zK1@XC%E^&i@%C~`|yyi!CE&{3<~=4U}3dN`e5q=YXIwGZNIy#
zeWzgkvOfG-^>@T80=;zv_e~%0QGEX2Vl4Xbh^}+I;J)d@EWsE8{a_rX3HspgpS5=n
z!7-N#>%;A;bN}cc-`Ww}H+=x+*I$Ic|2HJ#9OfP4#ynzerE%eKna{tE(
z`T%?v=X3werRjn`Ft<3?^w0h8DHx;6g!O@bSbeGL9l;!``#{~=+`~EIY|#{VoUYG^
zn@$yV>~wK#${;as)3Z|s?S
zZ@TY!`poXVzVEq`pD4J0=Ctnv_c|!J{~3ZlMEB1#)`!G0G1>dTczFGPLo#gW3SoVq
zAJ!M?Z{VqVqr=bLI{
zTg!#@;bzre5U+?EMcoJN0h`7zVPmWh^;}{;(f3CMHi}MsA1;*aLBTN{QTKs**44uL@K@FUBIpD6fxx{_b2lkBCcg|%DxM%vn-1qnY
z9m%){=7ja(0oCaP_rP4@{>`7#kJ|O2oI@Yc|CNIKUm&ax*Qx%xpnn$%
z^v`|M2jKg-_TvJ5*nJ4_&84yS
zt#kA}jDx>_^mMJ5?0vwt2St7Vd#nA5U`!`_A5PRgdi{S-GVFjKeKW@
z=mWORI%e}{it5{o_rwiiviIQ>-Q%HR?fsWM@F&&APvM7e6qC6R^K^gT6Cb_ns`_SP
zx_C$2CMIhiSR-%b<`d_P1kP#8raHC_
zo9MW;_pLI#=M<&}QUj@hk3$3UNo(EGNX!4t&3z4>iD7C^^Nt5>4f9r9%
zgbq~wdV{w5Yo+O7q>_q8?55KAn(AM7
z?5?)4hw89rVK0>iGOlgjVu%(b|CS)nL>#(65bK^Hh<7d4Jxz6DQucZrdy*hFC3gVC
zsB^^eVs>Gc%Hs+g!+vUq`peb+q9C8-V{N|QzMJpmJMH`Id$|6wVo+F2%y%3mEG|A&
z^@9bmF`p4X*ZXXaBOWIf=RVK@@jiMm9aubW{kHznSGxzU%RLa|*Y|L^+T4T1=iKji
z(SgcO3iNosI8UI1`W|c?#!?SQ>N|c_zJDv#>03vj1MXqG^?<&AQ++>uTq-(ZBJ{xA
zsK1}R3~t{0|D;xTcVu=zlpKJp!Wwp!dT?iRO;Tg0kTQol(sr_3(!8{7kW;JarCn}45D
zo$uj0xChh2c+Q7Gea|n8{`r3P{L94U!t`MCp(B~;!RAB1{(*U6-~VaV>GPF>dq9s5
zi>rj)1G-^8FelAFa4)oP5ZsUX2hKtN3j{uDjzIq_1mip?m>0h&{pb6+KHtYZFu&du
z+ynE0>yc|=PBQ1rKXAQQ#Pb5ZnV)<=WfM4Stm=o9v*W|ld5A6Ftqxu!%YQa75
z9oz$Yu=&88ME0OKUvLlT>SghmSR&38+yme7qTs&q)pG^Ma$o3bmY6MmUi#1X^S$)v
zno_s17_a%jnAG3T_g*Ww2h)Sy!+6-m3Dx&+t@?F>xkNb;dSFa`R`kE6>hv9d#XU@f
z9!}Et?92D_Pj&RMS};E*LJ!#ENB?aZ)wdOoi~GcQ>)~{L#~;NW7r-xiC;QfV2ASrF(Tu9yujvWilfBdLOZp!v}C?|+nm
zSTZoMsbH_vH(ZD7{g1Bezl=PE(h_TP6(8j(v@@BEzbDhZPZ6vapA*gwHEANvW_@dL!#X9|48se(0{7{UAm@xd|TXfa*jtN7mU3jE9>u~3{L@MZP+b}r`~
zAr39&4k~{tI)d0?B-c1x$K!Jj5coS{3)W_0hWEu9@tk;4JR_bJ3j}?mAp#Sc}hCkI)C#m?1d-Hv+%Q`5en}oJU_S5cCUuP@)sA!TI=IeB~bm
z_xz^d8bDt-{$6pbK&SKp8M-ExB39%41H}r#HERFgQJdqNbUH_$?Ibw=dNI;#u!fkA
zXMG&$HPGYQ^+x5_#jL`hN}DH#sLuWUUi?b@O#DQAUwnG)1pb)+4>N)#VfLos=5(x`
G_x}Npn&E>0
literal 0
HcmV?d00001
diff --git a/Switchy/main.c b/Switchy/main.c
new file mode 100644
index 0000000..ef9c24e
--- /dev/null
+++ b/Switchy/main.c
@@ -0,0 +1,253 @@
+#include
+#include
+#include
+#include "resource.h"
+
+#pragma comment(lib, "comctl32.lib")
+#pragma comment(lib, "user32.lib")
+#pragma comment(lib, "shell32.lib")
+
+#pragma comment(linker, \
+ "\"/manifestdependency:type='win32' " \
+ "name='Microsoft.Windows.Common-Controls' " \
+ "version='6.0.0.0' " \
+ "processorArchitecture='*' " \
+ "publicKeyToken='6595b64144ccf1df' " \
+ "language='*'\"")
+
+#define WM_TRAYNOTIFY (WM_USER + 100)
+#define ID_TRAYICON 1
+#define IDM_EXIT 1001
+#define IDM_TOGGLE 1002
+#define IDM_ABOUT 1003
+
+HHOOK hHook = NULL;
+HWND hWndHidden = NULL;
+NOTIFYICONDATA nid = { 0 };
+BOOL enabled = TRUE;
+BOOL keystrokeRightAltProcessed = FALSE;
+
+HINSTANCE g_hInstance = NULL;
+
+LPCTSTR LoadStr(UINT id)
+{
+ static TCHAR buf[1024];
+ buf[0] = TEXT('\0');
+ LoadString(g_hInstance, id, buf, _countof(buf));
+ return buf;
+}
+
+void ShowError(UINT id)
+{
+ MessageBox(NULL, LoadStr(id), TEXT("SwitchyAlt"), MB_OK | MB_ICONERROR);
+}
+
+void SwitchLayout()
+{
+ HWND hwndForeground = GetForegroundWindow();
+ if (!hwndForeground) return;
+
+ char className[256];
+ GetClassNameA(hwndForeground, className, sizeof(className));
+
+ BOOL isRDP = (strstr(className, "TscShellContainerClass") != NULL);
+ BOOL isConsole = (strstr(className, "ConsoleWindowClass") != NULL);
+
+ if (isRDP || isConsole)
+ {
+ INPUT inputs[4] = { 0 };
+ for (int i = 0; i < 4; i++) inputs[i].type = INPUT_KEYBOARD;
+ inputs[0].ki.wVk = VK_MENU; inputs[0].ki.wScan = 0x38;
+ inputs[1].ki.wVk = VK_SHIFT; inputs[1].ki.wScan = 0x2A;
+ inputs[2].ki.wVk = VK_SHIFT; inputs[2].ki.wScan = 0x2A; inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
+ inputs[3].ki.wVk = VK_MENU; inputs[3].ki.wScan = 0x38; inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
+ SendInput(4, inputs, sizeof(INPUT));
+ }
+ else
+ {
+ GUITHREADINFO gti = { sizeof(GUITHREADINFO) };
+ HWND targetWnd = hwndForeground;
+
+ if (GetGUIThreadInfo(0, >i) && gti.hwndFocus != NULL)
+ {
+ targetWnd = gti.hwndFocus;
+ }
+
+ PostMessage(targetWnd, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)HKL_NEXT);
+ }
+}
+
+LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ if (nCode != HC_ACTION)
+ return CallNextHookEx(hHook, nCode, wParam, lParam);
+
+ KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
+
+ if (p->flags & LLKHF_INJECTED)
+ return CallNextHookEx(hHook, nCode, wParam, lParam);
+
+ if (p->vkCode == VK_RMENU)
+ {
+ if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
+ {
+ if (!keystrokeRightAltProcessed)
+ {
+ keystrokeRightAltProcessed = TRUE;
+
+ if (GetAsyncKeyState(VK_LMENU) & 0x8000)
+ {
+ enabled = !enabled;
+ return 1;
+ }
+
+ if (enabled)
+ {
+ SwitchLayout();
+ }
+ }
+ return 1;
+ }
+
+ if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
+ {
+ keystrokeRightAltProcessed = FALSE;
+ return 1;
+ }
+ }
+
+ return CallNextHookEx(hHook, nCode, wParam, lParam);
+}
+
+INT_PTR CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, IDC_INFO, LoadStr(IDS_ABOUT_TEXT));
+ SetDlgItemText(hDlg, IDC_STATIC_APPINFO, LoadStr(IDS_APPINFO));
+ SetDlgItemText(hDlg, IDC_STATIC_BASEDON, LoadStr(IDS_BASEDON));
+ return (INT_PTR)TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
+ {
+ EndDialog(hDlg, LOWORD(wParam));
+ return (INT_PTR)TRUE;
+ }
+ break;
+ }
+ return (INT_PTR)FALSE;
+}
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_TRAYNOTIFY:
+ if (lParam == WM_RBUTTONUP)
+ {
+ POINT pt;
+ GetCursorPos(&pt);
+
+ HMENU hMenu = CreatePopupMenu();
+ if (hMenu)
+ {
+ AppendMenu(hMenu, MF_STRING, IDM_TOGGLE,
+ enabled ? LoadStr(IDS_MENU_PAUSE) : LoadStr(IDS_MENU_RESUME));
+
+ AppendMenu(hMenu, MF_STRING, IDM_ABOUT, LoadStr(IDS_MENU_ABOUT));
+ AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
+ AppendMenu(hMenu, MF_STRING, IDM_EXIT, LoadStr(IDS_MENU_EXIT));
+
+ SetForegroundWindow(hwnd);
+ UINT cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, 0, hwnd, NULL);
+ DestroyMenu(hMenu);
+
+ if (cmd == IDM_TOGGLE) enabled = !enabled;
+ if (cmd == IDM_ABOUT)
+ DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutDlgProc);
+ if (cmd == IDM_EXIT)
+ PostQuitMessage(0);
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+ return 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
+{
+ g_hInstance = hInstance;
+
+ HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("SwitchyAltUnique"));
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ ShowError(IDS_APP_MUTEX_ERROR);
+ return 1;
+ }
+
+ WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
+ wc.lpfnWndProc = WndProc;
+ wc.hInstance = hInstance;
+ wc.lpszClassName = TEXT("SwitchyHiddenClass");
+
+ if (!RegisterClassEx(&wc))
+ {
+ ShowError(IDS_ERROR_REG_CLASS);
+ return 1;
+ }
+
+ hWndHidden = CreateWindowEx(0, wc.lpszClassName, TEXT("SwitchyAlt"),
+ 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
+
+ if (!hWndHidden)
+ {
+ ShowError(IDS_ERROR_CREATE_WINDOW);
+ return 1;
+ }
+
+ InitCommonControls();
+
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWndHidden;
+ nid.uID = ID_TRAYICON;
+ nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ nid.uCallbackMessage = WM_TRAYNOTIFY;
+ nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
+ lstrcpy(nid.szTip, LoadStr(IDS_TRAY_TOOLTIP));
+
+ if (!Shell_NotifyIcon(NIM_ADD, &nid))
+ {
+ ShowError(IDS_ERROR_TRAY_ICON);
+ }
+
+ hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
+ if (!hHook)
+ {
+ ShowError(IDS_ERROR_SETHOOK);
+ Shell_NotifyIcon(NIM_DELETE, &nid);
+ DestroyWindow(hWndHidden);
+ return 1;
+ }
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ UnhookWindowsHookEx(hHook);
+ Shell_NotifyIcon(NIM_DELETE, &nid);
+ DestroyWindow(hWndHidden);
+
+ return (int)msg.wParam;
+}
\ No newline at end of file
diff --git a/Switchy/resource.h b/Switchy/resource.h
new file mode 100644
index 0000000..70d00e9
--- /dev/null
+++ b/Switchy/resource.h
@@ -0,0 +1,36 @@
+//{{NO_DEPENDENCIES}}
+// , Microsoft Visual C++.
+// Switchy.rc
+//
+#define IDI_ICON1 102
+#define IDD_ABOUTBOX 104
+#define IDS_ABOUT_TEXT 106
+#define IDS_APP_MUTEX_ERROR 107
+#define IDS_APP_ALREADY_RUNNING 108
+#define IDS_ERROR_REG_CLASS 109
+#define IDS_ERROR_CREATE_WINDOW 110
+#define IDS_ERROR_TRAY_ICON 111
+#define IDS_ERROR_SETHOOK 112
+#define IDS_MENU_PAUSE 113
+#define IDS_MENU_RESUME 114
+#define IDS_MENU_ABOUT 115
+#define IDS_MENU_EXIT 116
+#define IDS_TRAY_TOOLTIP 117
+#define IDS_ABOUT_TITLE 118
+#define IDS_BASEDON 119
+#define IDS_APPINFO 120
+#define IDC_CUSTOM1 1002
+#define IDC_INFO 1004
+#define IDC_STATIC_BASEDON 1005
+#define IDC_STATIC_APPINFO 1007
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 121
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/SwitchyAlt.sln b/SwitchyAlt.sln
new file mode 100644
index 0000000..69c7922
--- /dev/null
+++ b/SwitchyAlt.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29306.81
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Switchy", "Switchy\Switchy.vcxproj", "{16A46215-C3FC-4F84-966D-22B97CADE8C0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Debug|x64.ActiveCfg = Debug|x64
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Debug|x64.Build.0 = Debug|x64
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Debug|x86.ActiveCfg = Debug|Win32
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Debug|x86.Build.0 = Debug|Win32
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Release|x64.ActiveCfg = Release|x64
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Release|x64.Build.0 = Release|x64
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Release|x86.ActiveCfg = Release|Win32
+ {16A46215-C3FC-4F84-966D-22B97CADE8C0}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {3A751753-9F42-4929-A0D8-8B9011CE60FB}
+ EndGlobalSection
+EndGlobal