想念Linux下compiz的热角(鼠标移动到或点击屏幕左上角即可触发多桌面预览),基于 taviso/hotcorner 改写了一个超级小的hotcorner应用,体积只有37k,长时间运行占用也足够低:
运行后,鼠标点击屏幕左上角即可切换任务视图(taviso/hotcorner的版本是移动到左上角即触发),原理是添加鼠标hook发送“Super+Tab”组合键。Ctrl+Alt+C退出。要开机启动放到如下文件夹即可:
"%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"
由于用的是鼠标点击事件,所以逻辑和代码很简单:
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <windows.h>
#pragma comment(lib, "USER32")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#define KEYDOWN(k) ((k) & 0x80)
// based on https://github.com/taviso/hotcorner
// It just works. dylanchu 2020-02-07
static const RECT kHotCorner = {
.top = 0,
.left = 0,
.right = +1,
.bottom = +1,
};
// Input to inject when corner activated (Win+Tab by default).
static const INPUT kCornerInput[] = {
{ INPUT_KEYBOARD, .ki = { VK_LWIN, .dwFlags = 0 }},
{ INPUT_KEYBOARD, .ki = { VK_TAB, .dwFlags = 0 }},
{ INPUT_KEYBOARD, .ki = { VK_TAB, .dwFlags = KEYEVENTF_KEYUP }},
{ INPUT_KEYBOARD, .ki = { VK_LWIN, .dwFlags = KEYEVENTF_KEYUP }},
};
// You can exit the application using the hot key CTRL+ALT+C by default, if it
// interferes with some application you\'re using (e.g. a full screen game).
static const DWORD kHotKeyModifiers = MOD_CONTROL | MOD_ALT;
static const DWORD kHotKey = \'C\';
static HANDLE CornerThread = INVALID_HANDLE_VALUE;
static DWORD WINAPI CornerHotFunc(LPVOID lpParameter)
{
BYTE KeyState[256];
POINT Point;
// Check if any modifier keys are pressed.
if (GetKeyboardState(KeyState)) {
if (KEYDOWN(KeyState[VK_SHIFT]) || KEYDOWN(KeyState[VK_CONTROL])
|| KEYDOWN(KeyState[VK_MENU]) || KEYDOWN(KeyState[VK_LWIN])
|| KEYDOWN(KeyState[VK_RWIN])) {
return 0;
}
}
#pragma warning(suppress : 4090)
if (SendInput(_countof(kCornerInput), kCornerInput, sizeof(INPUT)) != _countof(kCornerInput)) {
return 1;
}
return 0;
}
static LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
MSLLHOOKSTRUCT *evt = (MSLLHOOKSTRUCT *) lParam;
// If the mouse hasn\'t been clicked, we\'re done.
if (wParam == WM_LBUTTONDOWN && PtInRect(&kHotCorner, evt->pt)) {
CornerThread = CreateThread(NULL, 0, CornerHotFunc, NULL, 0, NULL);
return 1; // 消息不再继续传递
} else if (wParam == WM_LBUTTONUP && CornerThread != INVALID_HANDLE_VALUE) {
CornerThread = INVALID_HANDLE_VALUE;
return 1;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HHOOK MouseHook;
if (!(MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, NULL, 0)))
return 1;
RegisterHotKey(NULL, 1, kHotKeyModifiers, kHotKey);
while (GetMessage(&Msg, NULL, 0, 0)) {
if (Msg.message == WM_HOTKEY) {
break;
}
DispatchMessage(&Msg);
}
UnhookWindowsHookEx(MouseHook);
return Msg.wParam;
}