📄 vnchooks.cpp
字号:
(SHORT) wrect.bottom
);
}
}
inline void SendDeferredBorderRect(HWND hWnd)
{
RECT wrect;
RECT crect;
// Get the rectangle position
if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, &wrect))
{
// Get the client rectangle position
if (GetAbsoluteClientRect(hWnd, &crect))
{
// Send the four border rectangles
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) crect.top);
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) crect.left, (SHORT) wrect.bottom);
SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) crect.bottom, (SHORT) wrect.right, (SHORT) wrect.bottom);
SendDeferredUpdateRect(hWnd, (SHORT) crect.right, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) wrect.bottom);
}
}
}
// ddihook, we only need the mouse info
inline BOOL HookHandleddi(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch (MessageId)
{
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
// Inform WinVNC that the mouse has moved and pass it the current cursor handle
{
ULONG new_cursor = (ULONG)GetCursor();
if (new_cursor != old_cursor) {
PostThreadMessage(
vnc_thread_id,
MouseMoveMessage,
(ULONG) new_cursor, 0);
old_cursor=new_cursor;
}
}
break;
}
return TRUE;
}
// Generic hook-handler
inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam)
{
////////////////////////////////////////////////////////////////
// HANDLE DEFERRED UPDATES
// Is this a deferred-update message?
if (MessageId == VNC_DEFERRED_UPDATE)
{
// NOTE : NEVER use the SendDeferred- routines to send updates
// from here, or you'll get an infinite loop....!
// NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,
// so just send the exact same message data to WinVNC
PostThreadMessage(
vnc_thread_id,
UpdateRectMessage,
wParam,
lParam
);
return FALSE;
}
else if(MessageId == VNC_DEFERRED_PAINTBORDER)
{
PaintBorder(hWnd);
return FALSE;
}
// *** Could use WM_COPYDATA to send data to WinVNC
/*
if (GetClassLong(hWnd, GCW_ATOM) == 32768)
{
_RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n",
hWnd, MessageId, lParam, wParam);
}
*/
////////////////////////////////////////////////////////////////
// UPDATE-TRIGGERING MESSAGES
// Do something dependent upon message type
switch (MessageId)
{
////////////////////////////////////////////////////////////////
// Messages indicating only a border repaint.
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_SIZE:
SendDeferredBorderRect(hWnd);
if(hWnd == hSingleWindow) // if the window is the choosen single window then color its border
{
PostMessage(
hWnd,
VNC_DEFERRED_PAINTBORDER,
0,
0
);
}
old_cursor = NULL;
break;
case WM_ACTIVATE: // if the window is the choosen single window then color its border
if(hWnd == hSingleWindow)
PaintBorder(hWnd);
break;
////////////////////////////////////////////////////////////////
// Messages indicating a client area repaint
case WM_CHAR:
case WM_KEYUP: // Handle key-presses
if (prf_use_KeyPress)
SendDeferredWindowRect(hWnd);
break;
case WM_KEYDOWN:
PostThreadMessage(
vnc_thread_id,
KeyMessage,
wParam,
lParam
);
break;
case WM_LBUTTONUP: // Handle LMB clicks
if (prf_use_LButtonUp)
SendDeferredWindowRect(hWnd);
break;
case WM_MBUTTONUP: // Handle MMB clicks
if (prf_use_MButtonUp)
SendDeferredWindowRect(hWnd);
break;
case WM_RBUTTONUP: // Handle RMB clicks
if (prf_use_RButtonUp)
SendDeferredWindowRect(hWnd);
break;
case WM_TIMER:
if (prf_use_Timer)
SendDeferredWindowRect(hWnd);
break;
case WM_HSCROLL:
case WM_VSCROLL:
if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL))
SendDeferredWindowRect(hWnd);
break;
case 485: // HACK to handle popup menus
{
// Get the old popup menu selection value
HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0));
if (prop != (HANDLE) wParam)
{
// It did, so update the menu & the selection value
SendDeferredWindowRect(hWnd);
SetProp(hWnd,
(LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0),
(HANDLE) wParam);
}
}
break;
////////////////////////////////////////////////////////////////
// Messages indicating a full window update
case WM_SYSCOLORCHANGE:
case WM_PALETTECHANGED:
case WM_SETTEXT:
case WM_ENABLE:
case BM_SETCHECK:
case BM_SETSTATE:
case EM_SETSEL:
//case WM_MENUSELECT:
SendDeferredWindowRect(hWnd);
break;
////////////////////////////////////////////////////////////////
// Messages indicating that an area of the window needs updating
// Uses GetUpdateRect to find out which
case WM_PAINT:
if (prf_use_GetUpdateRect)
{
HRGN region;
region = CreateRectRgn(0, 0, 0, 0);
// Get the affected region
if (GetUpdateRgn(hWnd, region, FALSE) != ERROR)
{
int buffsize;
UINT x;
RGNDATA *buff;
POINT TopLeft;
// Get the top-left point of the client area
TopLeft.x = 0;
TopLeft.y = 0;
if (!ClientToScreen(hWnd, &TopLeft))
break;
// Get the size of buffer required
buffsize = GetRegionData(region, 0, 0);
if (buffsize != 0)
{
buff = (RGNDATA *) new BYTE [buffsize];
if (buff == NULL)
break;
// Now get the region data
if(GetRegionData(region, buffsize, buff))
{
for (x=0; x<(buff->rdh.nCount); x++)
{
// Obtain the rectangles from the list
RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT)));
SendDeferredUpdateRect(
hWnd,
(SHORT) (TopLeft.x + urect->left),
(SHORT) (TopLeft.y + urect->top),
(SHORT) (TopLeft.x + urect->right),
(SHORT) (TopLeft.y + urect->bottom)
);
// Modified by mws for VNC ver. 3.3.6
// We yield this thread so our PostMessages and socket commands
// can complete, otherwise this hook can suck up too many
// timeslices before it returns
Sleep (0);
}
}
delete [] buff;
}
}
// Now free the region
if (region != NULL)
DeleteObject(region);
}
else
SendDeferredWindowRect(hWnd);
break;
////////////////////////////////////////////////////////////////
// Messages indicating full repaint of this and a different window
// Send the new position of the window
case WM_WINDOWPOSCHANGING:
if (IsWindowVisible(hWnd))
SendWindowRect(hWnd);
break;
case WM_WINDOWPOSCHANGED:
if (IsWindowVisible(hWnd))
SendDeferredWindowRect(hWnd);
break;
////////////////////////////////////////////////////////////////
// WinVNC also wants to know about mouse movement
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
// Inform WinVNC that the mouse has moved and pass it the current cursor handle
{
ULONG new_cursor = (ULONG)GetCursor();
if (new_cursor != old_cursor) {
PostThreadMessage(
vnc_thread_id,
MouseMoveMessage,
(ULONG) new_cursor, 0);
old_cursor=new_cursor;
}
}
break;
// RealVNC 335
case WM_MOUSEWHEEL: // Handle mousewheel events
SendDeferredWindowRect(hWnd);
break;
////////////////////////////////////////////////////////////////
// VNCHOOKS PROPERTIES HANDLING WINDOWS
case WM_DESTROY:
RemoveProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0));
break;
}
return TRUE;
}
// Hook procedure for CallWindow hook
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Do we have to handle this message?
if (nCode == HC_ACTION)
{
// Process the hook if the WinVNC thread ID is valid
if (vnc_thread_id)
{
CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam;
HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam);
}
}
// Call the next handler in the chain
return CallNextHookEx (hCallWndHook, nCode, wParam, lParam);
}
// Hook procedure for GetMessageProc hook
LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Do we have to handle this message?
if (nCode == HC_ACTION)
{
// Process the hook only if the WinVNC thread id is valid
if (vnc_thread_id)
{
MSG *msg = (MSG *) lParam;
// Only handle application messages if they're being removed:
if (wParam & PM_REMOVE)
{
// Handle the message
if (m_ddihook)
HookHandleddi(msg->message, msg->hwnd, msg->wParam, msg->lParam);
else
HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
}
}
}
// Call the next handler in the chain
return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam);
}
// Hook procedure for DialogMessageProc hook
LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Do we have to handle this message?
if (nCode >= 0)
{
// Process the hook only if the WinVNC thread ID is valid
if (vnc_thread_id)
{
MSG *msg = (MSG *) lParam;
// Handle the message
HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam);
}
}
// Call the next handler in the chain
return CallNextHookEx (hDialogMsgHook, nCode, wParam, lParam);
}
// Hook procedure for LowLevel Keyboard filtering
#ifdef WH_KEYBOARD_LL
LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Are we expected to handle this callback?
if (nCode == HC_ACTION)
{
// Is this keyboard event "real" or "injected"
// i.e. hardware or software-produced?
KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*)lParam;
if (!(hookStruct->flags & LLKHF_INJECTED)) {
// Message was not injected - reject it!
return TRUE;
}
}
// Otherwise, pass on the message
return CallNextHookEx(hLLKeyboardHook, nCode, wParam, lParam);
}
#endif
// Hook procedure for LowLevel Mouse filtering
#ifdef WH_MOUSE_LL
LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Are we expected to handle this callback?
if (nCode == HC_ACTION)
{
// Is this mouse event "real" or "injected"
// i.e. hardware or software-produced?
MSLLHOOKSTRUCT *hookStruct = (MSLLHOOKSTRUCT*)lParam;
if (!(hookStruct->flags & LLMHF_INJECTED)) {
// Message was not injected - reject it!
return TRUE;
}
}
// Otherwise, pass on the message
return CallNextHookEx(hLLMouseHook, nCode, wParam, lParam);
}
#endif
/////////////////////////////////////////////////////////////////////////////
// Initialise / Exit routines.
BOOL InitInstance()
{
// Create the global atoms
VNC_POPUPSELN_ATOM = GlobalAddAtom(VNC_POPUPSELN_ATOMNAME);
if (VNC_POPUPSELN_ATOM == NULL)
return FALSE;
return TRUE;
}
BOOL ExitInstance()
{
// Free the created atoms
if (VNC_POPUPSELN_ATOM != NULL)
{
// GlobalDeleteAtom(VNC_POPUPSELN_ATOM);
VNC_POPUPSELN_ATOM = NULL;
}
return TRUE;
}
DllExport BOOL SetSingleWindow(HWND hwnd)
{
hSingleWindow = hwnd;
return TRUE;
}
void PaintBorder(HWND hWnd)
{
HDC hWindowDC = NULL; // The DC of the found window.
HPEN hRectanglePen = NULL; // paint the border with a new color
HGDIOBJ hPrevPen = NULL; // Handle of the existing pen in the DC of the found window.
HGDIOBJ hPrevBrush = NULL; // Handle of the existing brush in the DC of the found window.
RECT rect; // Rectangle area of the found window.
// Get the window DC of the found window.
hWindowDC = GetWindowDC(hWnd);
if (hWindowDC)
{
GetWindowRect(hWnd, &rect);
// Create and select a new pen into the DC and backup the previous pen.
hRectanglePen = CreatePen (PS_SOLID, 8, RGB(119, 190, 29));
if(hRectanglePen)
{
hPrevPen = SelectObject(hWindowDC, hRectanglePen);
// Get the screen coordinates of the rectangle of the found window.
// Select a transparent brush into the DC and backup the previous brush.
hPrevBrush = SelectObject(hWindowDC, GetStockObject(HOLLOW_BRUSH));
// Draw a rectangle in the DC covering the entire window area of the found window.
Rectangle(hWindowDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
// Reinsert the previous pen and brush into the found window's DC.
SelectObject(hWindowDC, hPrevBrush);
SelectObject(hWindowDC, hPrevPen);
DeleteObject(hRectanglePen);
}
// Finally release the DC.
ReleaseDC(hWnd, hWindowDC);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -