forked from benbuck/rbtray
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RBHook.cpp
118 lines (109 loc) · 5.35 KB
/
RBHook.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// ****************************************************************************
//
// RBTray
// Copyright (C) 1998-2010 Nikolay Redko, J.D. Purcell
// Copyright (C) 2015 Benbuck Nason
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// ****************************************************************************
#include <windows.h>
#include <stdio.h>
#include "RBTray.h"
static HHOOK _hMouse = NULL;
static HHOOK _hWndProcRet = NULL;
static HWND _hLastHit = NULL;
//#define DEBUG_PRINTF(fmt, ...) do { char buf[1024]; snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); OutputDebugStringA(buf); } while (0)
// Works for 32-bit and 64-bit apps
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
//if ((wParam != WM_MOUSEMOVE) && (wParam != WM_NCMOUSEMOVE)) DEBUG_PRINTF("%s(%d): nCode %d, wParam %llx, lParam %llx\n", __FUNCTION__, __LINE__, nCode, (long long int)wParam, (long long int)lParam);
MOUSEHOOKSTRUCT * info = (MOUSEHOOKSTRUCT *)lParam;
//if ((wParam != WM_MOUSEMOVE) && (wParam != WM_NCMOUSEMOVE)) DEBUG_PRINTF("%s(%d): pt (%ld, %ld), hwnd %p, wHitTestCode %u, dwExtraInfo %llx\n", __FUNCTION__, __LINE__, info->pt.x, info->pt.y, info->hwnd, info->wHitTestCode, info->dwExtraInfo);
if ((wParam == WM_NCRBUTTONDOWN) || (wParam == WM_NCRBUTTONUP)) {
//DEBUG_PRINTF("%s(%d): button\n", __FUNCTION__, __LINE__);
if (info->wHitTestCode == HTCLIENT) {
//DEBUG_PRINTF("%s(%d): ignoring client hit test code for non-client message\n", __FUNCTION__, __LINE__);
} else {
BOOL shiftKeyDown = (GetKeyState(VK_SHIFT) & 0x8000) ? TRUE : FALSE;
BOOL isHit = (info->wHitTestCode == HTMINBUTTON) || ((info->wHitTestCode == HTCAPTION) && shiftKeyDown);
//DEBUG_PRINTF("%s(%d): shift %s, hit %s\n", __FUNCTION__, __LINE__, shiftKeyDown ? "yes" : "no", isHit ? "yes" : "no");
if ((wParam == WM_NCRBUTTONDOWN) && isHit) {
//DEBUG_PRINTF("%s(%d): down hit\n", __FUNCTION__, __LINE__);
_hLastHit = info->hwnd;
return 1;
} else if ((wParam == WM_NCRBUTTONUP) && isHit) {
//DEBUG_PRINTF("%s(%d): up hit\n", __FUNCTION__, __LINE__);
if (info->hwnd == _hLastHit) {
//DEBUG_PRINTF("%s(%d): up hit match\n", __FUNCTION__, __LINE__);
PostMessage(FindWindow(NAME, NAME), WM_ADDTRAY, 0, (LPARAM)info->hwnd);
}
_hLastHit = NULL;
return 1;
} else {
//DEBUG_PRINTF("%s(%d): miss\n", __FUNCTION__, __LINE__);
_hLastHit = NULL;
}
}
} else if ((wParam == WM_RBUTTONDOWN) || (wParam == WM_RBUTTONUP)) {
//DEBUG_PRINTF("%s(%d): not button\n", __FUNCTION__, __LINE__);
_hLastHit = NULL;
}
}
return CallNextHookEx(_hMouse, nCode, wParam, lParam);
}
// Only works for 32-bit apps or 64-bit apps depending on whether this is complied
// as 32-bit or 64-bit
LRESULT CALLBACK CallWndProcRet(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
CWPRETSTRUCT * msg = (CWPRETSTRUCT *)lParam;
if (((msg->message == WM_WINDOWPOSCHANGED) &&
(((WINDOWPOS *)msg->lParam)->flags & SWP_SHOWWINDOW) != 0) ||
(msg->message == WM_NCDESTROY))
{
PostMessage(FindWindow(NAME, NAME), WM_REFRTRAY, 0, (LPARAM)msg->hwnd);
}
//if ((msg->message == WM_SYSCOMMAND)) {// && (msg->wParam == SC_MINIMIZE)) {
// DEBUG_PRINTF("%s(%d): minimize\n", __FUNCTION__, __LINE__);
// WCHAR text[256];
// GetWindowText(msg->hwnd, text, sizeof(text) / sizeof(text[0]));
// if (wcsstr(text, L"Notepad")) {
// //PostMessage(FindWindow(NAME, NAME), WM_ADDTRAY, 0, (LPARAM)msg->hwnd);
// }
//}
}
return CallNextHookEx(_hWndProcRet, nCode, wParam, lParam);
}
BOOL DLLIMPORT RegisterHook(HMODULE hLib) {
//DEBUG_PRINTF("%s(%d): register hook\n", __FUNCTION__, __LINE__);
_hMouse = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, hLib, 0);
_hWndProcRet = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC)CallWndProcRet, hLib, 0);
if ((_hMouse == NULL) || (_hWndProcRet == NULL)) {
UnRegisterHook();
return FALSE;
}
return TRUE;
}
void DLLIMPORT UnRegisterHook() {
//DEBUG_PRINTF("%s(%d): unregister hook\n", __FUNCTION__, __LINE__);
if (_hMouse) {
UnhookWindowsHookEx(_hMouse);
_hMouse = NULL;
}
if (_hWndProcRet) {
UnhookWindowsHookEx(_hWndProcRet);
_hWndProcRet = NULL;
}
}