📄 vnchooks.cpp
字号:
if (hKeyboardHook == NULL)
{
// save the window handle
hKeyboardPriorityWindow = hwnd;
// Start up the hook...
hKeyboardHook = SetWindowsHookEx(
WH_KEYBOARD, // Hook in before msg reaches app
(HOOKPROC) KeyboardPriorityProc,// Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hKeyboardHook == NULL)
return FALSE;
}
return TRUE;
} else {
if (hKeyboardHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hKeyboardHook))
return FALSE;
// reset the hook and window handle
hKeyboardPriorityWindow = NULL;
hKeyboardHook = NULL;
}
return TRUE;
}
}
// Routine to start and stop local mouse message filtering
DllExport BOOL SetMousePriorityHook(HWND hwnd, BOOL activate, UINT LocalMouseMsg)
{
LocalMouseMessage = LocalMouseMsg;
if (activate)
{
if (hMouseHook == NULL)
{
// save the window handle
hMousePriorityWindow = hwnd;
// Start up the hook...
hMouseHook = SetWindowsHookEx(
WH_MOUSE, // Hook in before msg reaches app
(HOOKPROC) MousePriorityProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
);
if (hMouseHook == NULL)
return FALSE;
}
return TRUE;
} else {
if (hMouseHook != NULL)
{
// Stop the hook...
if (!UnhookWindowsHookEx(hMouseHook))
return FALSE;
// reset the hook and window handle
hMousePriorityWindow = NULL;
hMouseHook = NULL;
}
return TRUE;
}
}
// Routine to get the window's client rectangle, in screen coordinates
inline BOOL GetAbsoluteClientRect(HWND hwnd, RECT *rect)
{
POINT topleft;
topleft.x = 0;
topleft.y = 0;
// Get the client rectangle size
if (!GetClientRect(hwnd, rect))
return FALSE;
// Get the client rectangle position
if (!ClientToScreen(hwnd, &topleft))
return FALSE;
// Now adjust the window rectangle
rect->left += topleft.x;
rect->top += topleft.y;
rect->right += topleft.x;
rect->bottom += topleft.y;
return TRUE;
}
// Routine to send a CopyRect message to WinVNC
inline void SendCopyWindowRect(HWND hWnd)
{
WPARAM vwParam;
// All we send back is the handle of the window to be moved
vwParam = (LPARAM) hWnd;
// Send the update to Veneto
PostMessage(
hVeneto,
CopyRectMessage,
vwParam,
0
);
}
// Routine to send an UpdateRect message to Veneto
inline void SendUpdateRect(SHORT x, SHORT y, SHORT x2, SHORT y2)
{
WPARAM vwParam;
LPARAM vlParam;
vwParam = MAKELONG(x, y);
vlParam = MAKELONG(x2, y2);
// Send the update to Veneto
PostMessage(
hVeneto,
UpdateRectMessage,
vwParam,
vlParam
);
}
// Send a window's position to Veneto
inline void SendWindowRect(HWND hWnd)
{
RECT wrect;
// Get the rectangle position
if (GetWindowRect(hWnd, &wrect) && IsWindowVisible(hWnd))
{
// Send the position
SendUpdateRect(
(SHORT) wrect.left,
(SHORT) wrect.top,
(SHORT) wrect.right,
(SHORT) wrect.bottom
);
}
}
// Send a deferred message into this Window's message queue, so that
// we'll intercept it again only after the message that triggered it has been
// handled
inline void SendDeferredUpdateRect(HWND hWnd, SHORT x, SHORT y, SHORT x2, SHORT y2)
{
WPARAM vwParam;
LPARAM vlParam;
vwParam = MAKELONG(x, y);
vlParam = MAKELONG(x2, y2);
if (prf_use_Deferral)
{
// Send the update back to the window
PostMessage(
hWnd,
VNC_DEFERRED_UPDATE,
vwParam,
vlParam
);
}
else
{
// Send the update to WinRFB
PostMessage(
hVeneto,
UpdateRectMessage,
vwParam,
vlParam
);
}
}
inline void SendDeferredWindowRect(HWND hWnd)
{
RECT wrect;
// Get the rectangle position
if (::GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
{
// Send the position
SendDeferredUpdateRect(
hWnd,
(SHORT) wrect.left,
(SHORT) wrect.top,
(SHORT) wrect.right,
(SHORT) wrect.bottom
);
}
}
inline void SendDeferredBorderRect(HWND hWnd)
{
RECT wrect;
RECT crect;
// Get the rectangle position
if (GetWindowRect(hWnd, &wrect) && ::IsWindowVisible(hWnd))
{
// 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);
}
}
}
// 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 WinRFB:
PostMessage(
hVeneto,
UpdateRectMessage,
wParam,
lParam
);
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:
SendDeferredBorderRect(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_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)
);
}
}
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;
////////////////////////////////////////////////////////////////
// WinRFB also wants to know about mouse movement
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
// Inform WinRFB that the mouse has moved and pass it the current cursor handle
PostMessage(
hVeneto,
MouseMoveMessage,
(ULONG) GetCursor(),
0
);
break;
////////////////////////////////////////////////////////////////
// VNCHOOKS PROPERTIES HANDLING WINDOWS
case WM_DESTROY:
RemoveProp(hWnd, (LPCTSTR) MAKEWORD(VNC_WINDOWPOS_ATOM, 0));
RemoveProp(hWnd, (LPCTSTR) MAKEWORD(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 Veneto window handle is valid
if (hVeneto != NULL)
{
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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -