【300分】VNCHook For Delphi源码(300分)

  • 主题发起人 主题发起人 xzhifei
  • 开始时间 开始时间
X

xzhifei

Unregistered / Unconfirmed
GUEST, unregistred user!
大名鼎鼎的WinVNC远程控制软件几年前就公开了VC源码,不过一直没有DELPHI的源码,最近终于从网上搜索到的,对比VC的源码,基本上是直接转过来的,不过有点问题,只能截获到当前EXE主窗口的消息,很奇怪,大家看看,哪里有问题,希望能解决这个问题<br>全部文件下载:<br>http://www.xplan.cn/VNC.rar<br>源码部分:<br>//***********************************<br>//DLL部分<br>library hthooks;<br><br><br>uses<br> &nbsp;Windows,<br> &nbsp;UCallBacks in 'UCallBacks.pas';<br><br>{$R *.RES}<br><br><br>exports <br> &nbsp;SetHook index 1 Name 'SetHook', <br> &nbsp;UnSetHook index 2 Name 'UnSetHook', <br> &nbsp;SetKeyboardFilterHook Index 3 Name 'SetKeyboardFilterHook', <br> &nbsp;SetMouseFilterHook Index 4 Name 'SetMouseFilterHook'; <br><br><br>procedure DllEntryPoint(dwReason: DWord); <br>begin <br> &nbsp;case dwReason of<br> &nbsp; &nbsp;Dll_Process_Attach: InitInstance;<br> &nbsp; &nbsp;Dll_Process_Detach: ExitInstance; <br> &nbsp;end; <br>end; <br>begin <br> &nbsp;DLLProc := @DllEntryPoint; <br> &nbsp;DllEntryPoint(Dll_Process_Attach) <br>end. <br><br>//*********************************<br>unit UCallBacks;<br><br><br>interface<br><br><br>uses Windows, Messages, SysUtils;<br><br><br>///////////////////////////////////////////////////////////////////////////-/<br>// Storage for the global data in the DLL<br>var<br> &nbsp;hVeneto: HWND = 0;<br> &nbsp;UpdateRectMessage: UINT = 0;<br> &nbsp;CopyRectMessage: UINT = 0;<br> &nbsp;MouseMoveMessage: UINT = 0;<br> &nbsp;hCallWndHook: HHOOK = 0; // Handle to the CallWnd hook<br> &nbsp;hGetMsgHook: HHOOK = 0; // Handle to the GetMsg hook<br> &nbsp;hDialogMsgHook: HHOOK = 0; // Handle to the DialogMsg hook<br> &nbsp;hLLKeyboardHook: HHOOK = 0; // Handle to LowLevel kbd hook<br> &nbsp;hLLMouseHook: HHOOK = 0; // Handle to LowLevel mouse hook<br><br><br>///////////////////////////////////////////////////////////////////////////-/<br> &nbsp;// Per-instance DLL variables<br> &nbsp;// &nbsp;const<br> &nbsp;// &nbsp;char sPrefSegment[] = &quot;Application_Prefs//&quot;;<br>var<br> &nbsp;sModulePrefs: PChar = nil; // Name of the module that created us<br> &nbsp;prf_use_GetUpdateRect: Boolean = False; // Use the GetUpdateRect paint &nbsp;mode<br> &nbsp;prf_use_Timer: Boolean = False; // Use Timer events to trigger updates<br> &nbsp;prf_use_KeyPress: Boolean = False; // Use keyboard events<br> &nbsp;prf_use_LButtonUp: Boolean = True; // Use left mouse button up events<br> &nbsp;prf_use_MButtonUp: Boolean = False; // Use middle mouse button up events<br> &nbsp;prf_use_RButtonUp: Boolean = False; // Use right mouse button up events<br> &nbsp;prf_use_Deferral: Boolean = False; // Use deferred updates<br><br><br> &nbsp;hModuleKey: HKEY = 0; // Key used to save settings<br> &nbsp;// &nbsp;hInstance: HINSTANCE = NULL; // This instance of the DLL<br> &nbsp;HookMaster: Boolean = False; // Is this instance veneto itself?<br><br><br> &nbsp;appHookedOK: Boolean = False; // Did InitInstance succeed?<br><br><br>///////////////////////////////////////////////////////////////////////////-/<br><br> &nbsp;// Registered messages & atoms to be used by VNCHooks.DLL<br><br><br> &nbsp;// Messages<br>var<br> &nbsp;VNC_DEFERRED_UPDATE: UINT = 0;<br><br><br> &nbsp;// Atoms<br> &nbsp;VNC_WINDOWPOS_ATOMNAME: TAtom = 0;<br> &nbsp;VNC_POPUPSELN_ATOMNAME: TAtom = 0;<br> &nbsp;VNC_WINDOWPOS_ATOM: TAtom = 0;<br> &nbsp;VNC_POPUPSELN_ATOM: TAtom = 0;<br><br><br> &nbsp;// Forward definition of hook procedures<br><br><br>function HookHandle(Msg: LongWord; Wnd: HWND; wParam: Longint; lParam:<br> &nbsp;Longint): BOOL; stdcall;<br>function CallWndProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> &nbsp;LRESULT; stdcall;<br>function GetMessageProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> &nbsp;LRESULT; stdcall;<br>function DialogMessageProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br>function LowLevelKeyboardFilterProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br>function LowLevelMouseFilterProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br><br><br>function SetHook(Wnd: HWND; UpdateMsg: LongWord; CopyMsg: LongWord;<br> &nbsp;MouseMsg: LongWord): BOOL; stdcall; export;<br>function UnSetHook(Wnd: HWND): BOOL; stdcall; export;<br>function SetKeyboardFilterHook(Activate: BOOL): BOOL; stdcall; export;<br>function SetMouseFilterHook(Activate: BOOL): BOOL; stdcall; export;<br><br><br>// Forward definition of setup and shutdown procedures<br>function InitInstance(): BOOL;<br>function ExitInstance(): BOOL;<br><br><br>implementation<br><br><br>function DllMain(hInst: HWND; ul_reason_for_call: ULONG; lpReserved:<br> &nbsp;Integer): BOOL; stdcall;<br>begin<br> &nbsp;// Find out why we're being called<br> &nbsp;case (ul_reason_for_call) of<br> &nbsp; &nbsp;DLL_PROCESS_ATTACH:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;// Call the initialisation function<br> &nbsp; &nbsp; &nbsp; &nbsp;appHookedOK := InitInstance();<br> &nbsp; &nbsp; &nbsp; &nbsp;// ALWAYS return TRUE to avoid breaking unhookable applications!!!<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;DLL_PROCESS_DETACH:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;// Call the exit function<br> &nbsp; &nbsp; &nbsp; &nbsp;// If the app failed to hook OK, ExitInstance will still operate OK &nbsp; &nbsp; &nbsp; &nbsp;(hopefully...)<br> &nbsp; &nbsp; &nbsp; &nbsp;ExitInstance();<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := TRUE;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp;else<br> &nbsp; &nbsp;Result := TRUE;<br> &nbsp;end;<br>end;<br><br><br>// Routine to start and stop local keyboard message filtering<br><br><br>function SetKeyboardFilterHook(Activate: BOOL): BOOL; stdcall;<br>begin<br> &nbsp;if (Activate) then<br> &nbsp;begin<br> &nbsp; &nbsp;if (hLLKeyboardHook = 0) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;// Start up the hook...<br> &nbsp; &nbsp; &nbsp;hLLKeyboardHook := SetWindowsHookEx(<br> &nbsp; &nbsp; &nbsp; &nbsp;WH_KEYBOARD, // Hook in before msg reaches app<br> &nbsp; &nbsp; &nbsp; &nbsp;LowLevelKeyboardFilterProc, // Hook procedure<br> &nbsp; &nbsp; &nbsp; &nbsp;hInstance, // This DLL instance<br> &nbsp; &nbsp; &nbsp; &nbsp;0 // Hook in to all apps<br> &nbsp; &nbsp; &nbsp; &nbsp;);<br> &nbsp; &nbsp; &nbsp;if (hLLKeyboardHook = 0) then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := False<br> &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := TRUE;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := true;<br> &nbsp;end<br> &nbsp;else<br> &nbsp;begin<br> &nbsp; &nbsp;if (hLLKeyboardHook &lt;&gt; 0) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;// Stop the hook...<br> &nbsp; &nbsp; &nbsp;Result := (UnhookWindowsHookEx(hLLKeyboardHook));<br> &nbsp; &nbsp; &nbsp;hLLKeyboardHook := 0;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := True;<br> &nbsp;end;<br>end;<br><br><br>// Routine to start and stop local mouse message filtering<br><br><br>function SetMouseFilterHook(Activate: BOOL): BOOL; stdcall;<br>begin<br> &nbsp;if (Activate) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := (hLLMouseHook = 0);<br> &nbsp; &nbsp;if Result then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;// Start up the hook...<br> &nbsp; &nbsp; &nbsp;hLLMouseHook := SetWindowsHookEx(<br> &nbsp; &nbsp; &nbsp; &nbsp;WH_MOUSE, // Hook in before msg reaches app<br> &nbsp; &nbsp; &nbsp; &nbsp;LowLevelMouseFilterProc, // Hook procedure<br> &nbsp; &nbsp; &nbsp; &nbsp;hInstance, // This DLL instance<br> &nbsp; &nbsp; &nbsp; &nbsp;0 // Hook in to all apps<br> &nbsp; &nbsp; &nbsp; &nbsp;);<br> &nbsp; &nbsp; &nbsp;if (hLLMouseHook = 0) then Result := False;<br> &nbsp; &nbsp;end;<br> &nbsp;end<br> &nbsp;else<br> &nbsp;begin<br> &nbsp; &nbsp;if (hLLMouseHook &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp;Result := (UnhookWindowsHookEx(hLLMouseHook)) // Stop the hook...<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := True;<br> &nbsp; &nbsp;hLLMouseHook := 0;<br> &nbsp;end;<br>end;<br><br><br>// Add the new hook<br><br><br>function SetHook(Wnd: HWND; UpdateMsg: LongWord; CopyMsg: LongWord;<br> &nbsp;MouseMsg: LongWord): BOOL stdcall;<br>begin<br><br><br> &nbsp;// Don't add the hook if the window ID is NULL<br> &nbsp;if (Wnd = 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := False;<br> &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br><br> &nbsp;// Don't add a hook if there is already one added<br> &nbsp;if (hVeneto &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := False;<br> &nbsp; &nbsp;exit;<br> &nbsp;end;<br><br><br> &nbsp;// Add the CallWnd hook<br> &nbsp;hCallWndHook := SetWindowsHookEx(<br> &nbsp; &nbsp;WH_CALLWNDPROC, // Hook in before msg reaches app<br> &nbsp; &nbsp;CallWndProc, // Hook procedure<br> &nbsp; &nbsp;hInstance, // This DLL instance<br> &nbsp; &nbsp;0 // Hook in to all apps<br> &nbsp; &nbsp;// &nbsp;GetWindowThreadProcessId(Wnd, nil) // DEBUG : HOOK ONLY WinVNC<br> &nbsp; &nbsp;);<br><br><br> &nbsp;// Add the GetMessage hook<br> &nbsp;hGetMsgHook := SetWindowsHookEx(<br> &nbsp; &nbsp;WH_GETMESSAGE, // Hook in before msg reaches app<br> &nbsp; &nbsp;GetMessageProc, // Hook procedure<br> &nbsp; &nbsp;hInstance, // This DLL instance<br> &nbsp; &nbsp;0 // Hook in to all apps<br> &nbsp; &nbsp;// &nbsp;GetWindowThreadProcessId(Wnd, nil) &nbsp;// DEBUG : HOOK ONLY WinVNC<br> &nbsp; &nbsp;);<br><br><br> &nbsp;// Add the GetMessage hook<br> &nbsp;hDialogMsgHook := SetWindowsHookEx(<br> &nbsp; &nbsp;WH_SYSMSGFILTER, // Hook in dialogs, menus and scrollbars<br> &nbsp; &nbsp;DialogMessageProc, // Hook procedure<br> &nbsp; &nbsp;hInstance, // This DLL instance<br> &nbsp; &nbsp;0 // Hook in to all apps<br> &nbsp; &nbsp;);<br><br><br> &nbsp;// Check that it worked<br> &nbsp;if ((hCallWndHook &lt;&gt; 0) and (hGetMsgHook &lt;&gt; 0) and (hDialogMsgHook &lt;&gt; 0))<br> &nbsp; &nbsp;then<br> &nbsp;begin<br> &nbsp; &nbsp;hVeneto := Wnd; // Save the WinRFB window handle<br> &nbsp; &nbsp;UpdateRectMessage := UpdateMsg; // Save the message ID to use for &nbsp; &nbsp;rectangle updates<br> &nbsp; &nbsp;CopyRectMessage := CopyMsg; // Save the message ID to use for copyrect<br> &nbsp; &nbsp;MouseMoveMessage := MouseMsg; // Save the message ID to send when mouse &nbsp; &nbsp;moves<br> &nbsp; &nbsp;HookMaster := TRUE; // Set the HookMaster flag for this instance<br><br><br> &nbsp; &nbsp;Result := True;<br> &nbsp;end<br> &nbsp;else<br> &nbsp;begin<br> &nbsp; &nbsp;// Stop the keyboard hook<br> &nbsp; &nbsp;SetKeyboardFilterHook(FALSE);<br> &nbsp; &nbsp;SetMouseFilterHook(FALSE);<br><br><br> &nbsp; &nbsp;// Kill the main hooks<br> &nbsp; &nbsp;if (hCallWndHook &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(hCallWndHook);<br> &nbsp; &nbsp;if (hGetMsgHook &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(hGetMsgHook);<br> &nbsp; &nbsp;if (hDialogMsgHook &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(hDialogMsgHook);<br> &nbsp; &nbsp;hCallWndHook := 0;<br> &nbsp; &nbsp;hGetMsgHook := 0;<br> &nbsp; &nbsp;hDialogMsgHook := 0;<br><br><br> &nbsp; &nbsp;// The hook failed, so return an error code<br> &nbsp; &nbsp;Result := True;<br> &nbsp;end;<br>end;<br><br><br>// Remove the hook from the system<br><br><br>function UnSetHook(Wnd: HWND): BOOL; stdcall;<br><br><br>// EnumWindows procedure to remove the extra property we added<br><br><br> &nbsp;function KillPropsProc(Wnd: HWND; lParam: Longint): BOOL; stdcall;<br> &nbsp;begin<br> &nbsp; &nbsp;// Remove our custom property...<br> &nbsp; &nbsp;RemoveProp(Wnd, PChar(MAKEWORD(VNC_WINDOWPOS_ATOM, 0)));<br> &nbsp; &nbsp;RemoveProp(Wnd, PChar(MAKEWORD(VNC_POPUPSELN_ATOM, 0)));<br> &nbsp; &nbsp;Result := True;<br> &nbsp;end;<br><br><br>var<br> &nbsp;unHooked: BOOL;<br>begin<br> &nbsp;unHooked := True;<br><br><br> &nbsp;// Remove the extra property value from all local windows<br> &nbsp;EnumWindows(@KillPropsProc, 0);<br><br><br> &nbsp;// Stop the keyboard & mouse hooks<br> &nbsp;unHooked := unHooked and SetKeyboardFilterHook(FALSE);<br> &nbsp;unHooked := unHooked and SetMouseFilterHook(FALSE);<br><br><br> &nbsp;// Is the window handle valid?<br> &nbsp;if (Wnd = 0) then<br> &nbsp; &nbsp;MessageBox(GetDesktopWindow, 'Window pointer is null', nil, MB_OK);<br><br><br> &nbsp;// Is the correct application calling UnSetHook?<br> &nbsp;if (Wnd &lt;&gt; hVeneto) then<br> &nbsp; &nbsp;Result := False;<br><br><br> &nbsp;// Unhook the procs<br> &nbsp;if (hCallWndHook &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;unHooked := unHooked and UnhookWindowsHookEx(hCallWndHook);<br> &nbsp; &nbsp;hCallWndHook := 0;<br> &nbsp;end;<br><br><br> &nbsp;if (hGetMsgHook &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;unHooked := unHooked and UnhookWindowsHookEx(hGetMsgHook);<br> &nbsp; &nbsp;hGetMsgHook := 0;<br> &nbsp;end;<br><br><br> &nbsp;if (hDialogMsgHook &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;unHooked := unHooked and UnhookWindowsHookEx(hDialogMsgHook);<br> &nbsp; &nbsp;hDialogMsgHook := 0;<br> &nbsp;end;<br><br><br> &nbsp;// If we managed to unhook then reset<br> &nbsp;if (unHooked) then<br> &nbsp;begin<br> &nbsp; &nbsp;hVeneto := 0;<br> &nbsp; &nbsp;HookMaster := False;<br> &nbsp;end;<br><br><br> &nbsp;Result := unHooked;<br>end;<br><br><br>// Routine to get the window's client rectangle, in screen coordinates<br><br><br>function GetAbsoluteClientRect(Wnd: HWnd; var Rect: TRect): BOOL;<br>var<br> &nbsp;topleft: TPoint;<br>begin<br> &nbsp;topleft.x := 0;<br> &nbsp;topleft.y := 0;<br><br><br> &nbsp;Result := (GetClientRect(Wnd, Rect)); // Get the client rectangle size<br> &nbsp;if Result then<br> &nbsp; &nbsp;Result := (ClientToScreen(Wnd, topleft)); // Get the client rectangle &nbsp;position<br> &nbsp;if Result then<br> &nbsp;begin<br> &nbsp; &nbsp;// Now adjust the window rectangle<br> &nbsp; &nbsp;rect.Left := rect.Left + topleft.x;<br> &nbsp; &nbsp;rect.Top := rect.Top + topleft.y;<br> &nbsp; &nbsp;rect.Right := rect.Right + topleft.x;<br> &nbsp; &nbsp;rect.Bottom := rect.Bottom + topleft.y;<br> &nbsp;end;<br>end;<br><br><br>(******************************************************************<br>// Routine to send a CopyRect message to WinVNC<br>inline void SendCopyWindowRect(HWND hWnd)<br>{<br> WPARAM vwParam;<br><br><br> // All we send back is the handle of the window to be moved<br> vwParam = (LPARAM) hWnd;<br><br><br> // Send the update to Veneto<br> PostMessage(<br> &nbsp;hVeneto,<br> &nbsp;CopyRectMessage,<br> &nbsp;vwParam,<br> &nbsp;0<br> &nbsp;);<br><br><br>}<br><br><br>**********************************************)<br><br>// Routine to send an UpdateRect message to Veneto<br><br><br>//procedure SendUpdateRect(x, y, x2, y2: ShortInt);<br><br>procedure SendUpdateRect(x, y, x2, y2: Smallint);<br>var<br> &nbsp;vwParam: Longint;<br> &nbsp;vlParam: Longint;<br>begin<br><br> &nbsp;OutputDebugString(PChar(IntToStr(x) + ',' + IntToStr(y) + ',' + IntToStr(x2) + ',' + IntToStr(y2)));<br> &nbsp;vwParam := MAKELONG(x, y);<br> &nbsp;vlParam := MAKELONG(x2, y2);<br><br><br> &nbsp;// Send the update to Veneto<br> &nbsp;PostMessage(<br> &nbsp; &nbsp;hVeneto,<br> &nbsp; &nbsp;UpdateRectMessage,<br> &nbsp; &nbsp;vwParam,<br> &nbsp; &nbsp;vlParam<br> &nbsp; &nbsp;);<br><br><br>end;<br><br><br>// Send a window's position to Veneto<br><br><br>procedure SendWindowRect(Wnd: HWND);<br>var<br> &nbsp;wrect: TRect;<br>begin<br> &nbsp;// Get the rectangle position<br> &nbsp;if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> &nbsp; &nbsp;// Send the position<br> &nbsp; &nbsp;SendUpdateRect(<br> &nbsp; &nbsp; &nbsp;wrect.Left,<br> &nbsp; &nbsp; &nbsp;wrect.Top,<br> &nbsp; &nbsp; &nbsp;wrect.Right,<br> &nbsp; &nbsp; &nbsp;wrect.Bottom<br> &nbsp; &nbsp; &nbsp;);<br>end;<br><br><br>// Send a deferred message into this Window's message queue, so that<br>// we'll intercept it again only after the message that triggered it hasbeen<br>// handled<br><br><br>//procedure SendDeferredUpdateRect(Wnd: HWND; x, y, x2, y2: ShortInt);<br><br>procedure SendDeferredUpdateRect(Wnd: HWND; x, y, x2, y2: Smallint);<br>var<br> &nbsp;vwParam: Longint;<br> &nbsp;vlParam: Longint;<br>begin<br><br> &nbsp;OutputDebugString(PChar(IntToStr(x) + ',' + IntToStr(y) + ',' + IntToStr(x2) + ',' + IntToStr(y2)));<br><br> &nbsp;vwParam := MAKELONG(x, y);<br> &nbsp;vlParam := MAKELONG(x2, y2);<br><br><br> &nbsp;if (prf_use_Deferral) then<br> &nbsp; &nbsp;// Send the update back to the window<br> &nbsp; &nbsp;PostMessage(<br> &nbsp; &nbsp; &nbsp;Wnd,<br> &nbsp; &nbsp; &nbsp;VNC_DEFERRED_UPDATE,<br> &nbsp; &nbsp; &nbsp;vwParam,<br> &nbsp; &nbsp; &nbsp;vlParam<br> &nbsp; &nbsp; &nbsp;)<br> &nbsp;else<br> &nbsp; &nbsp;// Send the update to WinRFB<br> &nbsp; &nbsp;PostMessage(<br> &nbsp; &nbsp; &nbsp;hVeneto,<br> &nbsp; &nbsp; &nbsp;UpdateRectMessage,<br> &nbsp; &nbsp; &nbsp;vwParam,<br> &nbsp; &nbsp; &nbsp;vlParam<br> &nbsp; &nbsp; &nbsp;);<br>end;<br><br><br>procedure SendDeferredWindowRect(Wnd: HWND);<br>var<br> &nbsp;wrect: TRect;<br>begin<br> &nbsp;// Get the rectangle position<br> &nbsp;if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> &nbsp; &nbsp;// Send the position<br> &nbsp; &nbsp;SendDeferredUpdateRect(<br> &nbsp; &nbsp; &nbsp;Wnd,<br> &nbsp; &nbsp; &nbsp;wrect.left,<br> &nbsp; &nbsp; &nbsp;wrect.top,<br> &nbsp; &nbsp; &nbsp;wrect.right,<br> &nbsp; &nbsp; &nbsp;wrect.bottom<br> &nbsp; &nbsp; &nbsp;);<br>end;<br><br><br>procedure SendDeferredBorderRect(Wnd: HWND);<br>var<br> &nbsp;wrect: TRect;<br> &nbsp;crect: TRect;<br>begin<br> &nbsp;// Get the rectangle position<br> &nbsp;if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> &nbsp; &nbsp;// Get the client rectangle position<br> &nbsp; &nbsp;if (GetAbsoluteClientRect(Wnd, crect)) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;// Send the four border rectangles<br> &nbsp; &nbsp; &nbsp;SendDeferredUpdateRect(Wnd, wrect.left, wrect.top, wrect.right,<br> &nbsp; &nbsp; &nbsp; &nbsp;crect.top);<br> &nbsp; &nbsp; &nbsp;SendDeferredUpdateRect(Wnd, wrect.left, wrect.top, crect.left,<br> &nbsp; &nbsp; &nbsp; &nbsp;wrect.bottom);<br> &nbsp; &nbsp; &nbsp;SendDeferredUpdateRect(Wnd, wrect.left, crect.bottom, wrect.right,<br> &nbsp; &nbsp; &nbsp; &nbsp;wrect.bottom);<br> &nbsp; &nbsp; &nbsp;SendDeferredUpdateRect(Wnd, crect.right, wrect.top, wrect.right,<br> &nbsp; &nbsp; &nbsp; &nbsp;wrect.bottom);<br> &nbsp; &nbsp;end;<br>end;<br><br><br>// Generic hook-handler<br><br><br>function HookHandle(Msg: LongWord; Wnd: HWND; wParam: Longint; lParam:<br> &nbsp;Longint): BOOL; stdcall;<br>var<br> &nbsp;Prop: HWnd;<br> &nbsp;region: HRGN;<br> &nbsp;buffsize: Integer;<br> &nbsp;x: Longint;<br> &nbsp;buff: PRgnData;<br> &nbsp;TopLeft: Tpoint;<br> &nbsp;uRect: PRect;<br>begin<br> &nbsp;Result := True;<br> &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp;// *** HANDLE DEFERRED UPDATES ***<br><br><br> &nbsp;// Is this a deferred-update message?<br> &nbsp;if (Msg = VNC_DEFERRED_UPDATE) then<br> &nbsp;begin<br> &nbsp; &nbsp;// NOTE : NEVER use the SendDeferred- routines to send updates<br> &nbsp; &nbsp;// &nbsp;from here, or you'll get an infinite loop....!<br><br><br> &nbsp; &nbsp;// NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,<br> &nbsp; &nbsp;// &nbsp;so just send the exact same message data to WinRFB:<br> &nbsp; &nbsp;PostMessage(<br> &nbsp; &nbsp; &nbsp;hVeneto,<br> &nbsp; &nbsp; &nbsp;UpdateRectMessage,<br> &nbsp; &nbsp; &nbsp;wParam,<br> &nbsp; &nbsp; &nbsp;lParam<br> &nbsp; &nbsp; &nbsp;);<br> &nbsp; &nbsp;Result := False;<br> &nbsp;end;<br><br><br> &nbsp;// *** Could use WM_COPYDATA to send data to WinVNC<br><br><br>(**********************************************<br> &nbsp;if (GetClassLong(hWnd, GCW_ATOM) = = 32768)<br> &nbsp; &nbsp;{<br> _RPT4(_CRT_WARN, &quot;DBG : popup menu message (hwnd=%d, msg=%d, l=%d,<br>w=%d)/n&quot;,<br> hWnd, MessageId, lParam, wParam);<br><br><br>}<br><br><br> &nbsp;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *<br>* * * * * * * * * * * * * * * * * * * * * )<br>**********************************************)<br><br>////////////////////////////////////////////////////////////////<br>// *** UPDATE-TRIGGERING MESSAGES ***<br>// Do something dependent upon message type<br> &nbsp;case Msg of<br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// Messages indicating only a border repaint.<br> &nbsp; &nbsp;WM_NCPAINT: Result := True;<br> &nbsp; &nbsp;WM_NCACTIVATE:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredBorderRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// Messages indicating a client area repaint<br> &nbsp; &nbsp;WM_CHAR: Result := True;<br> &nbsp; &nbsp;WM_KEYUP: // Handle key-presses<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_KeyPress) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_LBUTTONUP: // Handle LMB clicks<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_LButtonUp) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_MBUTTONUP: // Handle MMB clicks<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_MButtonUp) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_RBUTTONUP: // Handle RMB clicks<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_RButtonUp) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_TIMER:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_Timer) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_HSCROLL: Result := True;<br> &nbsp; &nbsp;WM_VSCROLL:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if ((LOWORD(wParam) = SB_THUMBTRACK) and not (LOWORD(wParam) =<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SB_ENDSCROLL)) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;485: // HACK to handle popup menus<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;// Get the old popup menu selection value<br> &nbsp; &nbsp; &nbsp; &nbsp;Prop := GetProp(Wnd, PChar(MAKELONG(VNC_POPUPSELN_ATOM, 0)));<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prop &lt;&gt; Cardinal(wParam)) then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// It did, so update the menu & the selection value<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SetProp(Wnd,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PChar(MAKELONG(VNC_POPUPSELN_ATOM, 0)),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wParam);<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// Messages indicating a full window update<br> &nbsp; &nbsp;WM_SYSCOLORCHANGE: Result := True;<br> &nbsp; &nbsp;WM_PALETTECHANGED: Result := True;<br> &nbsp; &nbsp;WM_SETTEXT: Result := True;<br> &nbsp; &nbsp;WM_ENABLE: Result := True;<br> &nbsp; &nbsp;BM_SETCHECK: Result := True;<br> &nbsp; &nbsp;BM_SETSTATE: Result := True;<br> &nbsp; &nbsp;EM_SETSEL:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;//case WM_MENUSELECT:<br> &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// Messages indicating that an area of the window needs updating<br> &nbsp; &nbsp;// Uses GetUpdateRect to find out which<br> &nbsp; &nbsp;WM_PAINT:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if (prf_use_GetUpdateRect) then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;region := CreateRectRgn(0, 0, 0, 0);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Get the affected region<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (GetUpdateRgn(Wnd, region, FALSE) &lt;&gt; ERROR) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Get the top-left point of the client area<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TopLeft.x := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TopLeft.y := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (ClientToScreen(Wnd, TopLeft)) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Get the size of buffer required<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;buffsize := GetRegionData(region, 0, nil);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (buffsize &lt;&gt; 0) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Now get the region data<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetMem(buff, buffsize);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (GetRegionData(region, buffsize, buff) &lt;&gt; ERROR) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for x := 0 to buff.rdh.nCount do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Obtain the rectangles from the list<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uRect := PRect(Integer(buff) + SizeOf(TRgnDataHeader) +<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(x * SizeOf(TRect)));<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredUpdateRect(<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Wnd,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(TopLeft.x + urect.Left),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(TopLeft.y + urect.Top),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(TopLeft.x + urect.Right),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(TopLeft.y + urect.Bottom)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeMem(buff);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Now free the region<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (region &lt;&gt; 0) then DeleteObject(region);<br> &nbsp; &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// Messages indicating full repaint of this and a different window<br> &nbsp; &nbsp;// Send the new position of the window<br> &nbsp; &nbsp;WM_WINDOWPOSCHANGING:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if IsWindowVisible(Wnd) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;WM_WINDOWPOSCHANGED:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;if IsWindowVisible(Wnd) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SendDeferredWindowRect(Wnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// WinRFB also wants to know about mouse movement<br> &nbsp; &nbsp;WM_NCMOUSEMOVE: Result := True;<br> &nbsp; &nbsp;WM_MOUSEMOVE:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;// Inform WinRFB that the mouse has moved and pass it the current &nbsp; &nbsp; &nbsp; &nbsp;cursor handle<br> &nbsp; &nbsp; &nbsp; &nbsp;PostMessage(<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hVeneto,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MouseMoveMessage,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetCursor(),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br><br> &nbsp; &nbsp;////////////////////////////////////////////////////////////////<br> &nbsp; &nbsp;// VNCHOOKS PROPERTIES HANDLING WINDOWS<br> &nbsp; &nbsp;WM_DESTROY:<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;RemoveProp(Wnd, PChar(MAKEWORD(VNC_WINDOWPOS_ATOM, 0)));<br> &nbsp; &nbsp; &nbsp; &nbsp;RemoveProp(Wnd, PChar(MAKEWORD(VNC_POPUPSELN_ATOM, 0)));<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp;end;<br>end;<br><br><br>// Hook procedure for CallWindow hook<br><br><br>function CallWndProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> &nbsp;LRESULT; stdcall;<br>var<br> &nbsp;cwpStruct: PCwpStruct;<br>begin<br> &nbsp;// Do we have to handle this message?<br> &nbsp;if (nCode = HC_ACTION) then<br> &nbsp; &nbsp;if (hVeneto &lt;&gt; 0) then // Process the hook if the Veneto window handle &nbsp; &nbsp; &nbsp;is valid<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;cwpStruct := PCwpStruct(lParam);<br> &nbsp; &nbsp; &nbsp;HookHandle(cwpStruct.message, cwpStruct.hwnd, cwpStruct.wParam,<br> &nbsp; &nbsp; &nbsp; &nbsp;cwpStruct.lParam);<br> &nbsp; &nbsp;end;<br><br><br> &nbsp;// Call the next handler in the chain<br> &nbsp;Result := CallNextHookEx(hCallWndHook, nCode, wParam, lParam);<br>end;<br><br><br>// Hook procedure for GetMessageProc hook<br><br><br>function GetMessageProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> &nbsp;LRESULT; stdcall;<br>var<br> &nbsp;Msg: PMsg;<br>begin<br> &nbsp;// Do we have to handle this message?<br> &nbsp;if (nCode = HC_ACTION) then<br> &nbsp; &nbsp;if (hVeneto &lt;&gt; 0) then // Process the hook only if the Veneto window is &nbsp; &nbsp; &nbsp;valid<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Msg := PMsg(lParam);<br> &nbsp; &nbsp; &nbsp;if (wParam = PM_REMOVE) then // Only handle application messages if &nbsp;they're being removed:<br> &nbsp; &nbsp; &nbsp; &nbsp;HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle &nbsp; &nbsp; &nbsp;the message<br> &nbsp; &nbsp;end;<br><br><br> &nbsp;// Call the next handler in the chain<br> &nbsp;Result := CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);<br>end;<br><br><br>// Hook procedure for DialogMessageProc hook<br><br><br>function DialogMessageProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br>var<br> &nbsp;Msg: PMsg;<br>begin<br> &nbsp;// Do we have to handle this message?<br> &nbsp;if (nCode &gt;= 0) then<br> &nbsp; &nbsp;if (hVeneto &lt;&gt; 0) then // Process the hook only if the Veneto window is &nbsp; &nbsp; &nbsp;valid<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Msg := PMsg(lParam);<br> &nbsp; &nbsp; &nbsp;HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle &nbsp; &nbsp; &nbsp; the message<br> &nbsp; &nbsp;end;<br><br><br> &nbsp;// Call the next handler in the chain<br> &nbsp;Result := CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);<br>end;<br><br><br>// Hook procedure for LowLevel Keyboard filtering<br><br><br>function LowLevelKeyboardFilterProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br>var<br> &nbsp;Msg: PMsg;<br>begin<br> &nbsp;// Are we expected to handle this callback?<br> &nbsp;if (nCode = HC_ACTION) then<br> &nbsp;begin<br> &nbsp; &nbsp;Msg := PMsg(lParam);<br> &nbsp; &nbsp;HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the &nbsp; &nbsp;message<br> &nbsp;end;<br><br><br> &nbsp;// Otherwise, pass on the message<br> &nbsp;Result := CallNextHookEx(hLLKeyboardHook, nCode, wParam, lParam);<br>end;<br><br><br>// Hook procedure for LowLevel Mouse filtering<br><br><br>function LowLevelMouseFilterProc(nCode: Integer; wParam: Longint; lParam:<br> &nbsp;Longint): LRESULT; stdcall;<br>var<br> &nbsp;Msg: PMsg;<br>begin<br> &nbsp;// Are we expected to handle this callback?<br> &nbsp;if (nCode = HC_ACTION) then<br> &nbsp;begin<br> &nbsp; &nbsp;Msg := PMsg(lParam);<br> &nbsp; &nbsp;HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the &nbsp; &nbsp;message<br> &nbsp;end;<br><br><br> &nbsp;// Otherwise, pass on the message<br> &nbsp;Result := CallNextHookEx(hLLMouseHook, nCode, wParam, lParam);<br>end;<br><br><br>function StrLen(const Str: PChar): Cardinal; assembler;<br>asm<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDX,EDI<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,EAX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; ECX,0FFFFFFFFH<br> &nbsp; &nbsp; &nbsp; &nbsp;XOR &nbsp; &nbsp; AL,AL<br> &nbsp; &nbsp; &nbsp; &nbsp;REPNE &nbsp; SCASB<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EAX,0FFFFFFFEH<br> &nbsp; &nbsp; &nbsp; &nbsp;SUB &nbsp; &nbsp; EAX,ECX<br> &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; EDI,EDX<br>end;<br><br><br>function NameFromPath(const path: PChar): PChar;<br>var<br> &nbsp;x: Integer;<br> &nbsp;l: Integer;<br>begin<br> &nbsp;l := strlen(path);<br> &nbsp;Result := nil;<br> &nbsp;// Find the file part of a filename<br> &nbsp;for x := (l - 1) downto 0 do<br> &nbsp; &nbsp;if (path[x] = '/') then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Result := PChar(Copy(string(path), x + 1, l));<br> &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp;end;<br><br><br> &nbsp;// If we didn't fine a / then just return a copy of the original<br> &nbsp;if (Result = nil) then<br> &nbsp; &nbsp;Result := path;<br>end;<br><br><br>const<br> &nbsp;szSoftware = 'Software';<br> &nbsp;szCompany = 'Levin';<br> &nbsp;szProfile = 'HTHooks';<br><br><br>function GetRegistryKey(): HKEY;<br>var<br> &nbsp;hAppKey: HKEY;<br> &nbsp;hSoftKey: HKEY;<br> &nbsp;hCompanyKey: HKEY;<br> &nbsp;dw: PDWORD;<br>begin<br> &nbsp;hAppKey := 0;<br> &nbsp;hSoftKey := 0;<br> &nbsp;hCompanyKey := 0;<br><br><br> &nbsp;GetMem(dw, SizeOf(DWORD));<br><br><br> &nbsp;if (RegOpenKeyEx(HKEY_CURRENT_USER, szSoftware, 0, KEY_WRITE or KEY_READ,<br> &nbsp; &nbsp;hSoftKey) = ERROR_SUCCESS) then<br> &nbsp;begin<br> &nbsp; &nbsp;if (RegCreateKeyEx(hSoftKey, szCompany, 0, nil,<br> &nbsp; &nbsp; &nbsp;REG_OPTION_NON_VOLATILE, KEY_WRITE or KEY_READ, nil,<br> &nbsp; &nbsp; &nbsp;hCompanyKey, dw) = ERROR_SUCCESS) then<br> &nbsp; &nbsp; &nbsp;RegCreateKeyEx(hCompanyKey, szProfile, 0, nil,<br> &nbsp; &nbsp; &nbsp; &nbsp;REG_OPTION_NON_VOLATILE, KEY_WRITE or KEY_READ, nil,<br> &nbsp; &nbsp; &nbsp; &nbsp;hAppKey, dw);<br> &nbsp;end;<br> &nbsp;if (hSoftKey &lt;&gt; 0) then<br> &nbsp; &nbsp;RegCloseKey(hSoftKey);<br> &nbsp;if (hCompanyKey &lt;&gt; 0) then<br> &nbsp; &nbsp;RegCloseKey(hCompanyKey);<br><br><br> &nbsp;FreeMem(dw);<br><br><br> &nbsp;Result := hAppKey;<br>end;<br><br><br>function GetModuleKey(const proc_name: PChar): HKEY;<br>var<br> &nbsp;hModule: HKEY;<br> &nbsp;hAppKey: HKEY;<br> &nbsp;FileName: PChar;<br> &nbsp;dw: PDWORD;<br>begin<br> &nbsp;hModule := 0;<br><br> &nbsp;// Work out the registry key to save this under<br>// &nbsp;sModulePrefs := malloc(strlen(sPrefSegment) + strlen(proc_name) + 1);<br> &nbsp;sModulePrefs := PChar('Software/HowTo/HookUsage/' + proc_name);<br> &nbsp;// &nbsp;if (sModulePrefs = nil) then Result := 0;<br> &nbsp; &nbsp;// &nbsp;sprintf(sModulePrefs, &quot;%s%s&quot;, sPrefSegment, proc_name);<br><br><br> &nbsp; &nbsp; &nbsp;// Check whether the library's entry exists!<br> &nbsp;hAppKey := GetRegistryKey();<br> &nbsp;// &nbsp;if (hAppKey = 0) then Result := 0;<br><br><br> &nbsp; &nbsp;// Attempt to open the section for this application<br> &nbsp;if (RegOpenKeyEx(hAppKey,<br> &nbsp; &nbsp;sModulePrefs,<br> &nbsp; &nbsp;0, KEY_WRITE or KEY_READ,<br> &nbsp; &nbsp;hModule<br> &nbsp; &nbsp;) &lt;&gt; ERROR_SUCCESS) then<br> &nbsp;begin<br> &nbsp; &nbsp;// Cut off the app directory and just use the name<br> &nbsp; &nbsp;FileName := NameFromPath(proc_name);<br><br><br> &nbsp; &nbsp;if (FileName = nil) then<br> &nbsp; &nbsp; &nbsp;RegCloseKey(hAppKey);<br><br><br> &nbsp; &nbsp;// Adjust the moduleprefs name<br>// &nbsp; &nbsp;sprintf(sModulePrefs, &quot;%s%s&quot;, sPrefSegment, file_name);<br> &nbsp; &nbsp;sModulePrefs := PChar('Software/HowTo/HookUsage/' + FileName);<br><br>{ &nbsp; &nbsp;if FileName &lt;&gt; nil then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Dec(FileName, SizeOf(Cardinal));<br> &nbsp; &nbsp; &nbsp;FreeMem(FileName, Cardinal(Pointer(FileName)^));<br> &nbsp; &nbsp;end;<br>}<br> &nbsp; &nbsp;GetMem(dw, SizeOf(DWORD));<br><br><br> &nbsp; &nbsp;// Now get the module key again<br> &nbsp; &nbsp;if (RegCreateKeyEx(hAppKey,<br> &nbsp; &nbsp; &nbsp;sModulePrefs,<br> &nbsp; &nbsp; &nbsp;0, nil, REG_OPTION_NON_VOLATILE,<br> &nbsp; &nbsp; &nbsp;KEY_WRITE or KEY_READ,<br> &nbsp; &nbsp; &nbsp;nil,<br> &nbsp; &nbsp; &nbsp;hModule,<br> &nbsp; &nbsp; &nbsp;dw) &lt;&gt; ERROR_SUCCESS) then<br> &nbsp; &nbsp; &nbsp;RegCloseKey(hAppKey); // Couldn't find/create the key - fail!<br><br><br> &nbsp; &nbsp;FreeMem(dw);<br> &nbsp;end;<br><br><br> &nbsp;// Close the application registry key<br> &nbsp;RegCloseKey(hAppKey);<br><br><br> &nbsp;Result := hModule;<br>end;<br><br><br>procedure WriteProfileInt(key: PChar; Value: Integer);<br>begin<br> &nbsp;RegSetValueEx(<br> &nbsp; &nbsp;hModuleKey,<br> &nbsp; &nbsp;key,<br> &nbsp; &nbsp;0,<br> &nbsp; &nbsp;REG_DWORD,<br> &nbsp; &nbsp;@Value,<br> &nbsp; &nbsp;sizeof(Value));<br>end;<br><br><br>function InitInstance(): BOOL;<br>var<br> &nbsp;proc_name: array[0..MAX_PATH] of Char;<br> &nbsp;Size: DWORD;<br>begin<br> &nbsp;// Create the global atoms<br> &nbsp;VNC_WINDOWPOS_ATOM := GlobalAddAtom(PChar(VNC_WINDOWPOS_ATOMNAME));<br> &nbsp;if (VNC_WINDOWPOS_ATOM = 0) then Result := False;<br><br><br> &nbsp;VNC_POPUPSELN_ATOM := GlobalAddAtom(PChar(VNC_POPUPSELN_ATOMNAME));<br> &nbsp;if (VNC_POPUPSELN_ATOM = 0) then Result := False;<br><br><br> &nbsp;// Attempt to get the program/module name<br> &nbsp;size := GetModuleFileName(<br> &nbsp; &nbsp;HInstance,<br> &nbsp; &nbsp;@proc_name,<br> &nbsp; &nbsp;MAX_PATH);<br> &nbsp;if Size = 0 then Result := False;<br><br><br> &nbsp;// Get the key for the module<br> &nbsp;hModuleKey := GetModuleKey(proc_name);<br> &nbsp;// &nbsp;if (hModuleKey = 0) then Result := False;<br><br><br> &nbsp; &nbsp;// Read in the prefs<br> &nbsp;prf_use_GetUpdateRect := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_GetUpdateRect',<br> &nbsp; &nbsp;Integer(True)));<br><br><br> &nbsp;prf_use_Timer := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_Timer',<br> &nbsp; &nbsp;Integer(FALSE)));<br> &nbsp;prf_use_KeyPress := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_KeyPress',<br> &nbsp; &nbsp;Integer(TRUE)));<br><br><br> &nbsp;prf_use_LButtonUp := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_LButtonUp',<br> &nbsp; &nbsp;Integer(TRUE)));<br><br><br> &nbsp;prf_use_MButtonUp := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_MButtonUp',<br> &nbsp; &nbsp;Integer(TRUE)));<br><br><br> &nbsp;prf_use_RButtonUp := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_RButtonUp',<br> &nbsp; &nbsp;Integer(TRUE)));<br><br><br> &nbsp;prf_use_Deferral := BOOL(GetProfileInt(proc_name,<br> &nbsp; &nbsp;'use_Deferral',<br> &nbsp; &nbsp;Integer(TRUE)));<br><br><br> &nbsp;Result := True;<br>end;<br><br><br>function ExitInstance(): BOOL;<br>begin<br><br><br> &nbsp;// Free the created atoms<br> &nbsp;if (VNC_WINDOWPOS_ATOM &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;GlobalDeleteAtom(VNC_WINDOWPOS_ATOM);<br> &nbsp; &nbsp;VNC_WINDOWPOS_ATOM := 0;<br> &nbsp;end;<br><br><br> &nbsp;if (VNC_POPUPSELN_ATOM &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;GlobalDeleteAtom(VNC_POPUPSELN_ATOM);<br> &nbsp; &nbsp;VNC_POPUPSELN_ATOM := 0;<br> &nbsp;end;<br><br><br> &nbsp;// Write the module settings to disk<br> &nbsp;if (sModulePrefs &lt;&gt; nil) then<br> &nbsp;begin<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_GetUpdateRect',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_GetUpdateRect)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_Timer',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_Timer)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_KeyPress',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_KeyPress)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_LButtonUp',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_LButtonUp)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_MButtonUp',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_MButtonUp)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_RButtonUp',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_RButtonUp)<br> &nbsp; &nbsp; &nbsp;);<br><br><br> &nbsp; &nbsp;WriteProfileInt(<br> &nbsp; &nbsp; &nbsp;'use_Deferral',<br> &nbsp; &nbsp; &nbsp;Integer(prf_use_Deferral)<br> &nbsp; &nbsp; &nbsp;);<br><br> &nbsp; &nbsp; {<br> &nbsp; &nbsp;if sModulePrefs &lt;&gt; nil then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Dec(sModulePrefs, SizeOf(Cardinal));<br> &nbsp; &nbsp; &nbsp;FreeMem(sModulePrefs, Cardinal(Pointer(sModulePrefs)^));<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;}<br> &nbsp; &nbsp;sModulePrefs := nil;<br> &nbsp;end;<br><br><br> &nbsp;// Close the registry key for this module<br> &nbsp;if (hModuleKey &lt;&gt; 0) then<br> &nbsp; &nbsp;RegCloseKey(hModuleKey);<br><br><br> &nbsp;Result := True;<br>end;<br><br><br>initialization<br> &nbsp;DisableThreadLibraryCalls(HInstance);<br> &nbsp;VNC_DEFERRED_UPDATE :=<br> &nbsp; &nbsp;RegisterWindowMessage('HTHooks.Deferred.UpdateMessage');<br> &nbsp;VNC_WINDOWPOS_ATOMNAME :=<br> &nbsp; &nbsp;GlobalAddAtom(PChar('HTHooks.CopyRect.WindowPos'));<br> &nbsp;VNC_POPUPSELN_ATOMNAME :=<br> &nbsp; &nbsp;GlobalAddAtom(PChar('HTHooks.PopUpMenu.Selected'));<br><br><br>finalization<br>// &nbsp;Just saw this now, upsssss...<br>// &nbsp;GlobalDeleteAtom(VNC_DEFERRED_UPDATE);<br><br><br>end.
 
//***************************<br>//测试部分代码<br>unit Unitest;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ULibImport,<br> &nbsp;Dialogs, StdCtrls, AppEvnts;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Label1: TLabel;<br> &nbsp; &nbsp;Label2: TLabel;<br> &nbsp; &nbsp;Button2: TButton;<br> &nbsp; &nbsp;ApplicationEvents1: TApplicationEvents;<br> &nbsp; &nbsp;procedure ApplicationEvents1Message(var Msg: tagMSG;<br> &nbsp; &nbsp; &nbsp;var Handled: Boolean);<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure Button2Click(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br><br>{$R *.dfm}<br><br>procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;<br> &nbsp;var Handled: Boolean);<br>var<br>{ Mouse }<br> &nbsp;p: TPoint;<br><br>{ Screen }<br> &nbsp;l, t, r, b: integer;<br> &nbsp;rt: TRect;<br>begin<br>// &nbsp;caption := IntToStr(Msg.message);<br> &nbsp;if (Msg.message = RFB_MOUSE_UPDATE) then<br> &nbsp;begin<br> &nbsp; &nbsp;GetCursorPos(p);<br> &nbsp; &nbsp;Label1.Caption :=<br> &nbsp; &nbsp; &nbsp;'x:' + IntToStr(P.x) + #13#10 +<br> &nbsp; &nbsp; &nbsp;'y:' + IntToStr(P.Y);<br> &nbsp;end<br> &nbsp;else<br> &nbsp; &nbsp;if (Msg.message = RFB_SCREEN_UPDATE) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;l := Short(LOWORD(Msg.wParam));<br> &nbsp; &nbsp; &nbsp;t := Short(HIWORD(Msg.wParam));<br> &nbsp; &nbsp; &nbsp;r := Short(LOWORD(Msg.lParam));<br> &nbsp; &nbsp; &nbsp;b := Short(HIWORD(Msg.lParam));<br> &nbsp; &nbsp; &nbsp;Label2.Caption :=<br> &nbsp; &nbsp; &nbsp; &nbsp;'l:' + IntToStr(l) + #13#10 +<br> &nbsp; &nbsp; &nbsp; &nbsp;'t:' + IntToStr(t) + #13#10 +<br> &nbsp; &nbsp; &nbsp; &nbsp;'r:' + IntToStr(r) + #13#10 +<br> &nbsp; &nbsp; &nbsp; &nbsp;'b:' + IntToStr(b);<br><br> &nbsp; &nbsp;end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;if not dll_loaded then<br> &nbsp;begin<br> &nbsp; &nbsp;WNDHandle := Handle;<br> &nbsp; &nbsp;LoadDll;<br> &nbsp; &nbsp;if not SetHooks then<br> &nbsp; &nbsp; &nbsp;Application.MessageBox('装载DLL时失败!', '错误');<br> &nbsp;end;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br> &nbsp;if dll_loaded then<br> &nbsp;begin<br> &nbsp; &nbsp;UnSetHooks;<br> &nbsp; &nbsp;UnLoadDll;<br>// &nbsp; &nbsp;sen.Terminate;<br>// &nbsp; &nbsp;DoStop;<br> &nbsp;end;<br><br>end;<br><br><br>end.<br><br>//*****************************<br>unit ULibImport;<br><br>interface<br><br>uses Windows, Messages, Classes, SysUtils, Forms;<br><br>type<br>{ functions in vnchooks.dll }<br>// &nbsp;T_SetHook = function(wh: HWND; UpdateMsg, CopyMsg, MouseMsg: UINT): BOOL; &nbsp;cdecl;<br>// &nbsp;T_UnSetHook = function(wh: HWND): BOOL; cdecl;<br> &nbsp;T_SetHook = function(thread_id:WORD; UpdateMsg, CopyMsg, MouseMsg: UINT): BOOL; &nbsp;cdecl;<br> &nbsp;T_UnSetHook = function(thread_id:WORD): BOOL; cdecl;<br> &nbsp;T_SetMouseFilterHook = function(activate: BOOL): BOOL; cdecl;<br> &nbsp;T_SetKeyboardFilterHook = function(activate: BOOL): BOOL; cdecl;<br><br>function LoadDll: boolean;<br>function UnLoadDll: boolean;<br>function GetEntryPoints: boolean;<br><br>function SetHooks: boolean;<br>function UnSetHooks: boolean;<br>function MyPath: string;<br><br>const<br>// &nbsp;dllname = 'VNCHooks.dll';<br> &nbsp;dllname = 'hthooks.dll';<br><br>var<br> &nbsp;VNCHOOKS_HANDLE: THandle;<br> &nbsp;ProcAddr: FarProc;<br> &nbsp;SetHook: T_SetHook;<br> &nbsp;UnSetHook: T_UnSetHook;<br> &nbsp;SetMouseFilterHook: T_SetMouseFilterHook;<br> &nbsp;SetKeyboardFilterHook: T_SetKeyboardFilterHook;<br> &nbsp;dll_loaded: boolean;<br><br> &nbsp;RFB_SCREEN_UPDATE,<br> &nbsp; &nbsp;RFB_COPYRECT_UPDATE,<br> &nbsp; &nbsp;RFB_MOUSE_UPDATE: UINT;<br><br> &nbsp;WNDHandle:HWND;<br>implementation<br><br>function MyPath: string;<br>begin<br> &nbsp;Result := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName));<br>end;<br><br>function SetHooks: boolean;<br>begin<br> &nbsp;result := false;<br> &nbsp;if dll_loaded then begin<br> &nbsp; &nbsp;RFB_SCREEN_UPDATE := RegisterWindowMessage('WinVNC.Update.DrawRect');<br> &nbsp; &nbsp;RFB_COPYRECT_UPDATE := RegisterWindowMessage('WinVNC.Update.CopyRect');<br> &nbsp; &nbsp;RFB_MOUSE_UPDATE := RegisterWindowMessage('WinVNC.Update.Mouse');<br>// &nbsp; &nbsp;result := SetHook(Application.Handle, RFB_SCREEN_UPDATE,<br>// &nbsp; &nbsp; &nbsp;RFB_COPYRECT_UPDATE, RFB_MOUSE_UPDATE);<br> &nbsp; &nbsp;result := SetHook(WNDHandle, RFB_SCREEN_UPDATE,<br> &nbsp; &nbsp; &nbsp;RFB_COPYRECT_UPDATE, RFB_MOUSE_UPDATE);<br> &nbsp;end;<br>end;<br><br>function UnSetHooks: boolean;<br>begin<br> &nbsp;result := true;<br> &nbsp;if dll_loaded then begin<br>// &nbsp; &nbsp;if UnSetHook(Application.Handle) then begin<br> &nbsp; &nbsp;if UnSetHook(GetCurrentThreadId) then begin<br> &nbsp; &nbsp; &nbsp;RFB_SCREEN_UPDATE := 0;<br> &nbsp; &nbsp; &nbsp;RFB_COPYRECT_UPDATE := 0;<br> &nbsp; &nbsp; &nbsp;RFB_MOUSE_UPDATE := 0;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br>end;<br><br>function LoadDll: boolean;<br>begin<br> &nbsp;result := false;<br> &nbsp;VNCHOOKS_HANDLE := LoadLibrary(PChar(MyPath+dllname));<br> &nbsp;if VNCHOOKS_HANDLE &lt;&gt; 0 then begin<br> &nbsp; &nbsp;dll_loaded := GetEntryPoints;<br> &nbsp; &nbsp;if not dll_loaded then<br> &nbsp; &nbsp; &nbsp;FreeLibrary(VNCHOOKS_HANDLE)<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;result := true;<br> &nbsp;end;<br>end;<br><br>function UnLoadDll: boolean;<br>begin<br> &nbsp;result := true;<br> &nbsp;if dll_loaded then begin<br> &nbsp; &nbsp;SetHook := nil;<br> &nbsp; &nbsp;UnSetHook := nil;<br> &nbsp; &nbsp;SetMouseFilterHook := nil;<br> &nbsp; &nbsp;SetKeyboardFilterHook := nil;<br> &nbsp; &nbsp;dll_loaded := false;<br> &nbsp; &nbsp;if not FreeLibrary(VNCHOOKS_HANDLE) then<br> &nbsp; &nbsp; &nbsp;result := false;<br> &nbsp; &nbsp;VNCHOOKS_HANDLE := 0;<br> &nbsp;end;<br>end;<br><br>function GetEntryPoints: boolean;<br>begin<br> &nbsp;result := true;<br>{ Register SetHook }<br> &nbsp;ProcAddr := GetProcAddress(VNCHOOKS_HANDLE, 'SetHook');<br> &nbsp;if ProcAddr &lt;&gt; nil then SetHook := ProcAddr<br> &nbsp;else result := false;<br>{ Register UnSetHook }<br> &nbsp;ProcAddr := GetProcAddress(VNCHOOKS_HANDLE, 'UnSetHook');<br> &nbsp;if ProcAddr &lt;&gt; nil then UnSetHook := ProcAddr<br> &nbsp;else result := false;<br>{ Register SetMouseFilterHook }<br> &nbsp;ProcAddr := GetProcAddress(VNCHOOKS_HANDLE, 'SetMouseFilterHook');<br> &nbsp;if ProcAddr &lt;&gt; nil then SetMouseFilterHook := ProcAddr<br> &nbsp;else result := false;<br>{ Register SetKeyboardFilterHook }<br> &nbsp;ProcAddr := GetProcAddress(VNCHOOKS_HANDLE, 'SetKeyboardFilterHook');<br> &nbsp;if ProcAddr &lt;&gt; nil then SetKeyboardFilterHook := ProcAddr<br> &nbsp;else result := false;<br>end;<br><br>initialization<br> &nbsp;dll_loaded := false;<br><br>end.
 
我也看过一个,不知道是不是我那个,回头找找,不在公司
 
期待中。。。
 
哪儿有VNC的DELPHI的源码,如果只是用HOOK的话,也不能完全得到变化的区域,另外,个人觉得可以直接调用VC写的那个DLL
 
去看了一下,发现VNC的源码N多,连.NET、J2ME的都有<br>http://sourceforge.net/projects/delphivnc
 
在DLL和测试端都的工程文件中加上一个单元sharemem试一下
 
这不是指针的问题
 
http://sourceforge.net/ 上的DELPHI源码只是一个客户端连接!!!
 
把DLL中的 cdecl &nbsp;修试改成stdcall能成功调用
 
但是好那两个按钮的重绘消息有问题
 
加入学习中
 
测试端的ONMESSAGE里面加 &nbsp; &nbsp;Dispatch( Msg)就可以了
 
大家有空帮小弟看一下我的问题<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=3395061<br>多谢
 
感谢meigreat,我试试看
 
meigreat 没有说到关键的地方!<br><br>晚上看了下代码,错误很多,感觉很难修改,因为你一堆东西很杂乱的堆在一起,<br>简单的修改你的错误:<br><br>&gt;&gt;只能截获到当前EXE主窗口的消息<br>最简单,可以如下修改:<br>// &nbsp;PostMessage(<br>// &nbsp; &nbsp;hVeneto,<br>// &nbsp; &nbsp;UpdateRectMessage,<br>// &nbsp; &nbsp;vwParam,<br>// &nbsp; &nbsp;vlParam<br>// &nbsp; &nbsp;);<br><br> &nbsp;PostMessage(<br> &nbsp; &nbsp;HWND_BROADCAST,<br> &nbsp; &nbsp;UpdateRectMessage,<br> &nbsp; &nbsp;vwParam,<br> &nbsp; &nbsp;vlParam<br> &nbsp; &nbsp;);<br><br>hVeneto 改为 HWND_BROADCAST<br><br>还有几种其它的改法, 代码不是直接修改你的,有点小区别,但原理是一样的,如:<br>library hthooks;<br><br>function StartHook(hForm: THandle): Integer; stdcall;<br>begin<br> ....<br> &nbsp; &nbsp;hMemFile := CreateFileMapping(MAXDWORD, nil, PAGE_READWRITE, 0,<br> &nbsp; &nbsp; &nbsp;SizeOf(THandle), memFileName);<br> &nbsp; &nbsp;pFormHnd := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);<br> &nbsp; &nbsp;if pFormHnd = nil then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Result := 4;<br> &nbsp; &nbsp; &nbsp;UnhookWindowsHookEx(hMouseHook);<br> &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp;end else<br> &nbsp; &nbsp; &nbsp;pFormHnd^ := hForm;<br><br>begin<br> &nbsp;DLLProc := @EntryProc;<br> &nbsp;hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, memFileName);<br> &nbsp;if hMemFile &lt;&gt; 0 then<br> &nbsp; &nbsp;pFormHnd := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);<br>end.<br><br><br>全局HOOK, 在不同的程序,对应的 hVeneto 的值是不同的,这点如果你明白了,你的问题所在就很清楚了。<br><br>另外,一些声明错了,如stdcall, cdecl &nbsp;<br>另外,label1, label2 的取值有些问题,<br>dll中的消息处理,也是一塌糊涂的感觉!<br><br>另外,你的代码可能HOOK到 paint 之类的,然后,你又给刷新 label1, label2, 这样可能有问题,这部分,我没细看
 
多人接受答案了。
 
后退
顶部