📜 ⬆️ ⬇️

A little trick to quickly switch between applications.


It so happened that I have long used Logitech mice - MX300 and MX310. They have an extra button above the wheel, on which you can hang various functions. In the old drivers (MouseWare), among these functions was the “Recall Application”, which was switched over to the previous active window - about the same as what happens if you press Alt + Tab once. I immediately liked this opportunity: often there is a situation when you need to switch to some window, do something there (for example, copy a line) and go back (respectively, to paste this copied line). Alt + Tab in this case is less convenient (because the left hand should be removed from the combination Ctrl + C, and then returned to its previous position to press Ctrl + V).

But here I set myself Windows XP x64, and it turned out that MouseWare for 64-bit systems is inaccessible. For the MX310, a more modern SetPoint utility was found, but the “Recall Application” function is no longer there. Fortunately, we managed to adjust the sending of the Alt + Tab shortcut to the desired button, but the flashing of the task list window at the time of switching was a bit annoying. So, having overcome laziness, I was honored to write a small utility that helped eliminate this drawback.


In fact, only one thing was required of the utility: hang in the background and, upon receiving a signal to press a button, switch to the “neighboring” window. The problem was not so trivial, as I assumed at first. The signal to press the button directly cannot be obtained, since the list of available actions in SetPoint does not contain such an action “send a signal to press the sixth button”. So I had to cheat a little bit: by pressing a button, emulate some keyboard shortcut, and the program has already caught this combination. Naturally, you need to choose something that is not used in normal work; I chose Ctrl + Alt + Shift + Z.

The second difficulty was choosing the right window. You can navigate through the Z-stack of applications by calling GetWindow (hwnd, GW_HWNDNEXT), but among these windows there are a large number of those that do not need to be switched. For example, invisible. Even if you leave only visible windows, there are many other top-level windows that are not in the regular Alt + Tab list. Here I could not find a satisfactory solution. One option was able to google Stack overflow , but I didn’t get it right with the enumeration of windows. There are also TaskSwitchXP source files , but the attempt to adapt the code to my needs failed (extra windows appeared in the list). I couldn’t figure it out completely in the code, so either I did something wrong, or the code was not originally designed for such inappropriate use. (However, I will continue to deal with it.) In the end, I conducted my own research and determined the empirical conditions for choosing the “right” windows (I will list these conditions at the end). The resulting program code fit on one page:
int WinMainCRTStartup(void) { if (!RegisterHotKey(NULL, 0, MOD_CONTROL | MOD_SHIFT | MOD_ALT, 'Z')) return 1; MSG msg = {0}; while (GetMessage(&msg, NULL, 0, 0)) { if (msg.message == WM_HOTKEY) { HWND current_wnd = GetForegroundWindow(); if (current_wnd == NULL) continue; // Find top-level owner of the current window HWND owner = current_wnd; do { current_wnd = owner; owner = GetWindow(current_wnd, GW_OWNER); } while ((owner != NULL) && IsWindowVisible(owner)); // Find next window in Z-stack to switch to do { current_wnd = GetWindow(current_wnd, GW_HWNDNEXT); if (current_wnd == NULL) break; owner = GetWindow(current_wnd, GW_OWNER); } while (!IsWindowVisible(current_wnd) || ((GetWindowLongPtr(current_wnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) != 0) || ((owner != NULL) && IsWindowVisible(owner))); if (current_wnd != NULL) SetForegroundWindow(current_wnd); } } UnregisterHotKey(NULL, 0); return 0; } 

Small technical comments

Source: https://habr.com/ru/post/105312/

All Articles