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> Windows,<br> UCallBacks in 'UCallBacks.pas';<br><br>{$R *.RES}<br><br><br>exports <br> SetHook index 1 Name 'SetHook', <br> UnSetHook index 2 Name 'UnSetHook', <br> SetKeyboardFilterHook Index 3 Name 'SetKeyboardFilterHook', <br> SetMouseFilterHook Index 4 Name 'SetMouseFilterHook'; <br><br><br>procedure DllEntryPoint(dwReason: DWord); <br>begin <br> case dwReason of<br> Dll_Process_Attach: InitInstance;<br> Dll_Process_Detach: ExitInstance; <br> end; <br>end; <br>begin <br> DLLProc := @DllEntryPoint; <br> 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> hVeneto: HWND = 0;<br> UpdateRectMessage: UINT = 0;<br> CopyRectMessage: UINT = 0;<br> MouseMoveMessage: UINT = 0;<br> hCallWndHook: HHOOK = 0; // Handle to the CallWnd hook<br> hGetMsgHook: HHOOK = 0; // Handle to the GetMsg hook<br> hDialogMsgHook: HHOOK = 0; // Handle to the DialogMsg hook<br> hLLKeyboardHook: HHOOK = 0; // Handle to LowLevel kbd hook<br> hLLMouseHook: HHOOK = 0; // Handle to LowLevel mouse hook<br><br><br>///////////////////////////////////////////////////////////////////////////-/<br> // Per-instance DLL variables<br> // const<br> // char sPrefSegment[] = "Application_Prefs//";<br>var<br> sModulePrefs: PChar = nil; // Name of the module that created us<br> prf_use_GetUpdateRect: Boolean = False; // Use the GetUpdateRect paint mode<br> prf_use_Timer: Boolean = False; // Use Timer events to trigger updates<br> prf_use_KeyPress: Boolean = False; // Use keyboard events<br> prf_use_LButtonUp: Boolean = True; // Use left mouse button up events<br> prf_use_MButtonUp: Boolean = False; // Use middle mouse button up events<br> prf_use_RButtonUp: Boolean = False; // Use right mouse button up events<br> prf_use_Deferral: Boolean = False; // Use deferred updates<br><br><br> hModuleKey: HKEY = 0; // Key used to save settings<br> // hInstance: HINSTANCE = NULL; // This instance of the DLL<br> HookMaster: Boolean = False; // Is this instance veneto itself?<br><br><br> appHookedOK: Boolean = False; // Did InitInstance succeed?<br><br><br>///////////////////////////////////////////////////////////////////////////-/<br><br> // Registered messages & atoms to be used by VNCHooks.DLL<br><br><br> // Messages<br>var<br> VNC_DEFERRED_UPDATE: UINT = 0;<br><br><br> // Atoms<br> VNC_WINDOWPOS_ATOMNAME: TAtom = 0;<br> VNC_POPUPSELN_ATOMNAME: TAtom = 0;<br> VNC_WINDOWPOS_ATOM: TAtom = 0;<br> VNC_POPUPSELN_ATOM: TAtom = 0;<br><br><br> // Forward definition of hook procedures<br><br><br>function HookHandle(Msg: LongWord; Wnd: HWND; wParam: Longint; lParam:<br> Longint): BOOL; stdcall;<br>function CallWndProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> LRESULT; stdcall;<br>function GetMessageProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> LRESULT; stdcall;<br>function DialogMessageProc(nCode: Integer; wParam: Longint; lParam:<br> Longint): LRESULT; stdcall;<br>function LowLevelKeyboardFilterProc(nCode: Integer; wParam: Longint; lParam:<br> Longint): LRESULT; stdcall;<br>function LowLevelMouseFilterProc(nCode: Integer; wParam: Longint; lParam:<br> Longint): LRESULT; stdcall;<br><br><br>function SetHook(Wnd: HWND; UpdateMsg: LongWord; CopyMsg: LongWord;<br> 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> Integer): BOOL; stdcall;<br>begin<br> // Find out why we're being called<br> case (ul_reason_for_call) of<br> DLL_PROCESS_ATTACH:<br> begin<br> // Call the initialisation function<br> appHookedOK := InitInstance();<br> // ALWAYS return TRUE to avoid breaking unhookable applications!!!<br> Result := True;<br> end;<br> DLL_PROCESS_DETACH:<br> begin<br> // Call the exit function<br> // If the app failed to hook OK, ExitInstance will still operate OK (hopefully...)<br> ExitInstance();<br> Result := TRUE;<br> end;<br> else<br> Result := TRUE;<br> 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> if (Activate) then<br> begin<br> if (hLLKeyboardHook = 0) then<br> begin<br> // Start up the hook...<br> hLLKeyboardHook := SetWindowsHookEx(<br> WH_KEYBOARD, // Hook in before msg reaches app<br> LowLevelKeyboardFilterProc, // Hook procedure<br> hInstance, // This DLL instance<br> 0 // Hook in to all apps<br> <br> if (hLLKeyboardHook = 0) then<br> Result := False<br> else<br> Result := TRUE;<br> end<br> else<br> Result := true;<br> end<br> else<br> begin<br> if (hLLKeyboardHook <> 0) then<br> begin<br> // Stop the hook...<br> Result := (UnhookWindowsHookEx(hLLKeyboardHook));<br> hLLKeyboardHook := 0;<br> end<br> else<br> Result := True;<br> 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> if (Activate) then<br> begin<br> Result := (hLLMouseHook = 0);<br> if Result then<br> begin<br> // Start up the hook...<br> hLLMouseHook := SetWindowsHookEx(<br> WH_MOUSE, // Hook in before msg reaches app<br> LowLevelMouseFilterProc, // Hook procedure<br> hInstance, // This DLL instance<br> 0 // Hook in to all apps<br> <br> if (hLLMouseHook = 0) then Result := False;<br> end;<br> end<br> else<br> begin<br> if (hLLMouseHook <> 0) then<br> Result := (UnhookWindowsHookEx(hLLMouseHook)) // Stop the hook...<br> else<br> Result := True;<br> hLLMouseHook := 0;<br> end;<br>end;<br><br><br>// Add the new hook<br><br><br>function SetHook(Wnd: HWND; UpdateMsg: LongWord; CopyMsg: LongWord;<br> MouseMsg: LongWord): BOOL stdcall;<br>begin<br><br><br> // Don't add the hook if the window ID is NULL<br> if (Wnd = 0) then<br> begin<br> Result := False;<br> exit;<br> end;<br><br><br> // Don't add a hook if there is already one added<br> if (hVeneto <> 0) then<br> begin<br> Result := False;<br> exit;<br> end;<br><br><br> // Add the CallWnd hook<br> hCallWndHook := SetWindowsHookEx(<br> WH_CALLWNDPROC, // Hook in before msg reaches app<br> CallWndProc, // Hook procedure<br> hInstance, // This DLL instance<br> 0 // Hook in to all apps<br> // GetWindowThreadProcessId(Wnd, nil) // DEBUG : HOOK ONLY WinVNC<br> <br><br><br> // Add the GetMessage hook<br> hGetMsgHook := SetWindowsHookEx(<br> WH_GETMESSAGE, // Hook in before msg reaches app<br> GetMessageProc, // Hook procedure<br> hInstance, // This DLL instance<br> 0 // Hook in to all apps<br> // GetWindowThreadProcessId(Wnd, nil) // DEBUG : HOOK ONLY WinVNC<br> <br><br><br> // Add the GetMessage hook<br> hDialogMsgHook := SetWindowsHookEx(<br> WH_SYSMSGFILTER, // Hook in dialogs, menus and scrollbars<br> DialogMessageProc, // Hook procedure<br> hInstance, // This DLL instance<br> 0 // Hook in to all apps<br> <br><br><br> // Check that it worked<br> if ((hCallWndHook <> 0) and (hGetMsgHook <> 0) and (hDialogMsgHook <> 0))<br> then<br> begin<br> hVeneto := Wnd; // Save the WinRFB window handle<br> UpdateRectMessage := UpdateMsg; // Save the message ID to use for rectangle updates<br> CopyRectMessage := CopyMsg; // Save the message ID to use for copyrect<br> MouseMoveMessage := MouseMsg; // Save the message ID to send when mouse moves<br> HookMaster := TRUE; // Set the HookMaster flag for this instance<br><br><br> Result := True;<br> end<br> else<br> begin<br> // Stop the keyboard hook<br> SetKeyboardFilterHook(FALSE);<br> SetMouseFilterHook(FALSE);<br><br><br> // Kill the main hooks<br> if (hCallWndHook <> 0) then<br> UnhookWindowsHookEx(hCallWndHook);<br> if (hGetMsgHook <> 0) then<br> UnhookWindowsHookEx(hGetMsgHook);<br> if (hDialogMsgHook <> 0) then<br> UnhookWindowsHookEx(hDialogMsgHook);<br> hCallWndHook := 0;<br> hGetMsgHook := 0;<br> hDialogMsgHook := 0;<br><br><br> // The hook failed, so return an error code<br> Result := True;<br> 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> function KillPropsProc(Wnd: HWND; lParam: Longint): BOOL; stdcall;<br> begin<br> // Remove our custom property...<br> RemoveProp(Wnd, PChar(MAKEWORD(VNC_WINDOWPOS_ATOM, 0)));<br> RemoveProp(Wnd, PChar(MAKEWORD(VNC_POPUPSELN_ATOM, 0)));<br> Result := True;<br> end;<br><br><br>var<br> unHooked: BOOL;<br>begin<br> unHooked := True;<br><br><br> // Remove the extra property value from all local windows<br> EnumWindows(@KillPropsProc, 0);<br><br><br> // Stop the keyboard & mouse hooks<br> unHooked := unHooked and SetKeyboardFilterHook(FALSE);<br> unHooked := unHooked and SetMouseFilterHook(FALSE);<br><br><br> // Is the window handle valid?<br> if (Wnd = 0) then<br> MessageBox(GetDesktopWindow, 'Window pointer is null', nil, MB_OK);<br><br><br> // Is the correct application calling UnSetHook?<br> if (Wnd <> hVeneto) then<br> Result := False;<br><br><br> // Unhook the procs<br> if (hCallWndHook <> 0) then<br> begin<br> unHooked := unHooked and UnhookWindowsHookEx(hCallWndHook);<br> hCallWndHook := 0;<br> end;<br><br><br> if (hGetMsgHook <> 0) then<br> begin<br> unHooked := unHooked and UnhookWindowsHookEx(hGetMsgHook);<br> hGetMsgHook := 0;<br> end;<br><br><br> if (hDialogMsgHook <> 0) then<br> begin<br> unHooked := unHooked and UnhookWindowsHookEx(hDialogMsgHook);<br> hDialogMsgHook := 0;<br> end;<br><br><br> // If we managed to unhook then reset<br> if (unHooked) then<br> begin<br> hVeneto := 0;<br> HookMaster := False;<br> end;<br><br><br> 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> topleft: TPoint;<br>begin<br> topleft.x := 0;<br> topleft.y := 0;<br><br><br> Result := (GetClientRect(Wnd, Rect)); // Get the client rectangle size<br> if Result then<br> Result := (ClientToScreen(Wnd, topleft)); // Get the client rectangle position<br> if Result then<br> begin<br> // Now adjust the window rectangle<br> rect.Left := rect.Left + topleft.x;<br> rect.Top := rect.Top + topleft.y;<br> rect.Right := rect.Right + topleft.x;<br> rect.Bottom := rect.Bottom + topleft.y;<br> 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> hVeneto,<br> CopyRectMessage,<br> vwParam,<br> 0<br> <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> vwParam: Longint;<br> vlParam: Longint;<br>begin<br><br> OutputDebugString(PChar(IntToStr(x) + ',' + IntToStr + ',' + IntToStr(x2) + ',' + IntToStr(y2)));<br> vwParam := MAKELONG(x, y);<br> vlParam := MAKELONG(x2, y2);<br><br><br> // Send the update to Veneto<br> PostMessage(<br> hVeneto,<br> UpdateRectMessage,<br> vwParam,<br> vlParam<br> <br><br><br>end;<br><br><br>// Send a window's position to Veneto<br><br><br>procedure SendWindowRect(Wnd: HWND);<br>var<br> wrect: TRect;<br>begin<br> // Get the rectangle position<br> if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> // Send the position<br> SendUpdateRect(<br> wrect.Left,<br> wrect.Top,<br> wrect.Right,<br> wrect.Bottom<br> <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> vwParam: Longint;<br> vlParam: Longint;<br>begin<br><br> OutputDebugString(PChar(IntToStr(x) + ',' + IntToStr + ',' + IntToStr(x2) + ',' + IntToStr(y2)));<br><br> vwParam := MAKELONG(x, y);<br> vlParam := MAKELONG(x2, y2);<br><br><br> if (prf_use_Deferral) then<br> // Send the update back to the window<br> PostMessage(<br> Wnd,<br> VNC_DEFERRED_UPDATE,<br> vwParam,<br> vlParam<br>  <br> else<br> // Send the update to WinRFB<br> PostMessage(<br> hVeneto,<br> UpdateRectMessage,<br> vwParam,<br> vlParam<br> <br>end;<br><br><br>procedure SendDeferredWindowRect(Wnd: HWND);<br>var<br> wrect: TRect;<br>begin<br> // Get the rectangle position<br> if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> // Send the position<br> SendDeferredUpdateRect(<br> Wnd,<br> wrect.left,<br> wrect.top,<br> wrect.right,<br> wrect.bottom<br> <br>end;<br><br><br>procedure SendDeferredBorderRect(Wnd: HWND);<br>var<br> wrect: TRect;<br> crect: TRect;<br>begin<br> // Get the rectangle position<br> if (GetWindowRect(Wnd, wrect) and IsWindowVisible(Wnd)) then<br> // Get the client rectangle position<br> if (GetAbsoluteClientRect(Wnd, crect)) then<br> begin<br> // Send the four border rectangles<br> SendDeferredUpdateRect(Wnd, wrect.left, wrect.top, wrect.right,<br> crect.top);<br> SendDeferredUpdateRect(Wnd, wrect.left, wrect.top, crect.left,<br> wrect.bottom);<br> SendDeferredUpdateRect(Wnd, wrect.left, crect.bottom, wrect.right,<br> wrect.bottom);<br> SendDeferredUpdateRect(Wnd, crect.right, wrect.top, wrect.right,<br> wrect.bottom);<br> end;<br>end;<br><br><br>// Generic hook-handler<br><br><br>function HookHandle(Msg: LongWord; Wnd: HWND; wParam: Longint; lParam:<br> Longint): BOOL; stdcall;<br>var<br> Prop: HWnd;<br> region: HRGN;<br> buffsize: Integer;<br> x: Longint;<br> buff: PRgnData;<br> TopLeft: Tpoint;<br> uRect: PRect;<br>begin<br> Result := True;<br> ////////////////////////////////////////////////////////////////<br> // *** HANDLE DEFERRED UPDATES ***<br><br><br> // Is this a deferred-update message?<br> if (Msg = VNC_DEFERRED_UPDATE) then<br> begin<br> // NOTE : NEVER use the SendDeferred- routines to send updates<br> // from here, or you'll get an infinite loop....!<br><br><br> // NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage,<br> // so just send the exact same message data to WinRFB:<br> PostMessage(<br> hVeneto,<br> UpdateRectMessage,<br> wParam,<br> lParam<br> <br> Result := False;<br> end;<br><br><br> // *** Could use WM_COPYDATA to send data to WinVNC<br><br><br>(**********************************************<br> if (GetClassLong(hWnd, GCW_ATOM) = = 32768)<br> {<br> _RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d,<br>w=%d)/n",<br> hWnd, MessageId, lParam, wParam);<br><br><br>}<br><br><br> * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *<br>* * * * * * * * * * * * * * * * * * * * * )<br>**********************************************)<br><br>////////////////////////////////////////////////////////////////<br>// *** UPDATE-TRIGGERING MESSAGES ***<br>// Do something dependent upon message type<br> case Msg of<br> ////////////////////////////////////////////////////////////////<br> // Messages indicating only a border repaint.<br> WM_NCPAINT: Result := True;<br> WM_NCACTIVATE:<br> begin<br> SendDeferredBorderRect(Wnd);<br> Exit;<br> end;<br> ////////////////////////////////////////////////////////////////<br> // Messages indicating a client area repaint<br> WM_CHAR: Result := True;<br> WM_KEYUP: // Handle key-presses<br> begin<br> if (prf_use_KeyPress) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_LBUTTONUP: // Handle LMB clicks<br> begin<br> if (prf_use_LButtonUp) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_MBUTTONUP: // Handle MMB clicks<br> begin<br> if (prf_use_MButtonUp) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_RBUTTONUP: // Handle RMB clicks<br> begin<br> if (prf_use_RButtonUp) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_TIMER:<br> begin<br> if (prf_use_Timer) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_HSCROLL: Result := True;<br> WM_VSCROLL:<br> begin<br> if ((LOWORD(wParam) = SB_THUMBTRACK) and not (LOWORD(wParam) =<br> SB_ENDSCROLL)) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> 485: // HACK to handle popup menus<br> begin<br> // Get the old popup menu selection value<br> Prop := GetProp(Wnd, PChar(MAKELONG(VNC_POPUPSELN_ATOM, 0)));<br> if (prop <> Cardinal(wParam)) then<br> begin<br> // It did, so update the menu & the selection value<br> SendDeferredWindowRect(Wnd);<br> SetProp(Wnd,<br> PChar(MAKELONG(VNC_POPUPSELN_ATOM, 0)),<br> wParam);<br> end;<br> Exit;<br> end;<br><br><br> ////////////////////////////////////////////////////////////////<br> // Messages indicating a full window update<br> WM_SYSCOLORCHANGE: Result := True;<br> WM_PALETTECHANGED: Result := True;<br> WM_SETTEXT: Result := True;<br> WM_ENABLE: Result := True;<br> BM_SETCHECK: Result := True;<br> BM_SETSTATE: Result := True;<br> EM_SETSEL:<br> begin<br> //case WM_MENUSELECT:<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br> ////////////////////////////////////////////////////////////////<br> // Messages indicating that an area of the window needs updating<br> // Uses GetUpdateRect to find out which<br> WM_PAINT:<br> begin<br> if (prf_use_GetUpdateRect) then<br> begin<br> region := CreateRectRgn(0, 0, 0, 0);<br> // Get the affected region<br> if (GetUpdateRgn(Wnd, region, FALSE) <> ERROR) then<br> begin<br> // Get the top-left point of the client area<br> TopLeft.x := 0;<br> TopLeft.y := 0;<br> if (ClientToScreen(Wnd, TopLeft)) then<br> begin<br> // Get the size of buffer required<br> buffsize := GetRegionData(region, 0, nil);<br> if (buffsize <> 0) then<br> begin<br> // Now get the region data<br> GetMem(buff, buffsize);<br> if (GetRegionData(region, buffsize, buff) <> ERROR) then<br> begin<br> for x := 0 to buff.rdh.nCount do<br> begin<br> // Obtain the rectangles from the list<br> uRect := PRect(Integer(buff) + SizeOf(TRgnDataHeader) +<br> (x * SizeOf(TRect)));<br> SendDeferredUpdateRect(<br> Wnd,<br> (TopLeft.x + urect.Left),<br> (TopLeft.y + urect.Top),<br> (TopLeft.x + urect.Right),<br> (TopLeft.y + urect.Bottom)<br> <br> end;<br> end;<br> FreeMem(buff);<br> end;<br> end;<br> end;<br><br><br> // Now free the region<br> if (region <> 0) then DeleteObject(region);<br> end<br> else<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br> ////////////////////////////////////////////////////////////////<br> // Messages indicating full repaint of this and a different window<br> // Send the new position of the window<br> WM_WINDOWPOSCHANGING:<br> begin<br> if IsWindowVisible(Wnd) then<br> SendWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> WM_WINDOWPOSCHANGED:<br> begin<br> if IsWindowVisible(Wnd) then<br> SendDeferredWindowRect(Wnd);<br> Exit;<br> end;<br><br><br> ////////////////////////////////////////////////////////////////<br> // WinRFB also wants to know about mouse movement<br> WM_NCMOUSEMOVE: Result := True;<br> WM_MOUSEMOVE:<br> begin<br> // Inform WinRFB that the mouse has moved and pass it the current cursor handle<br> PostMessage(<br> hVeneto,<br> MouseMoveMessage,<br> GetCursor(),<br> 0<br> <br> Exit;<br> end;<br><br><br> ////////////////////////////////////////////////////////////////<br> // VNCHOOKS PROPERTIES HANDLING WINDOWS<br> WM_DESTROY:<br> begin<br> RemoveProp(Wnd, PChar(MAKEWORD(VNC_WINDOWPOS_ATOM, 0)));<br> RemoveProp(Wnd, PChar(MAKEWORD(VNC_POPUPSELN_ATOM, 0)));<br> Exit;<br> end;<br> end;<br>end;<br><br><br>// Hook procedure for CallWindow hook<br><br><br>function CallWndProc(nCode: Integer; wParam: Longint; lParam: Longint):<br> LRESULT; stdcall;<br>var<br> cwpStruct: PCwpStruct;<br>begin<br> // Do we have to handle this message?<br> if (nCode = HC_ACTION) then<br> if (hVeneto <> 0) then // Process the hook if the Veneto window handle is valid<br> begin<br> cwpStruct := PCwpStruct(lParam);<br> HookHandle(cwpStruct.message, cwpStruct.hwnd, cwpStruct.wParam,<br> cwpStruct.lParam);<br> end;<br><br><br> // Call the next handler in the chain<br> 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> LRESULT; stdcall;<br>var<br> Msg: PMsg;<br>begin<br> // Do we have to handle this message?<br> if (nCode = HC_ACTION) then<br> if (hVeneto <> 0) then // Process the hook only if the Veneto window is valid<br> begin<br> Msg := PMsg(lParam);<br> if (wParam = PM_REMOVE) then // Only handle application messages if they're being removed:<br> HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the message<br> end;<br><br><br> // Call the next handler in the chain<br> 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> Longint): LRESULT; stdcall;<br>var<br> Msg: PMsg;<br>begin<br> // Do we have to handle this message?<br> if (nCode >= 0) then<br> if (hVeneto <> 0) then // Process the hook only if the Veneto window is valid<br> begin<br> Msg := PMsg(lParam);<br> HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the message<br> end;<br><br><br> // Call the next handler in the chain<br> 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> Longint): LRESULT; stdcall;<br>var<br> Msg: PMsg;<br>begin<br> // Are we expected to handle this callback?<br> if (nCode = HC_ACTION) then<br> begin<br> Msg := PMsg(lParam);<br> HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the message<br> end;<br><br><br> // Otherwise, pass on the message<br> 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> Longint): LRESULT; stdcall;<br>var<br> Msg: PMsg;<br>begin<br> // Are we expected to handle this callback?<br> if (nCode = HC_ACTION) then<br> begin<br> Msg := PMsg(lParam);<br> HookHandle(Msg.message, Msg.hwnd, Msg.wParam, Msg.lParam); // Handle the message<br> end;<br><br><br> // Otherwise, pass on the message<br> Result := CallNextHookEx(hLLMouseHook, nCode, wParam, lParam);<br>end;<br><br><br>function StrLen(const Str: PChar): Cardinal; assembler;<br>asm<br> MOV EDX,EDI<br> MOV EDI,EAX<br> MOV ECX,0FFFFFFFFH<br> XOR AL,AL<br> REPNE SCASB<br> MOV EAX,0FFFFFFFEH<br> SUB EAX,ECX<br> MOV EDI,EDX<br>end;<br><br><br>function NameFromPath(const path: PChar): PChar;<br>var<br> x: Integer;<br> l: Integer;<br>begin<br> l := strlen(path);<br> Result := nil;<br> // Find the file part of a filename<br> for x := (l - 1) downto 0 do<br> if (path[x] = '/') then<br> begin<br> Result := PChar(Copy(string(path), x + 1, l));<br> Break;<br> end;<br><br><br> // If we didn't fine a / then just return a copy of the original<br> if (Result = nil) then<br> Result := path;<br>end;<br><br><br>const<br> szSoftware = 'Software';<br> szCompany = 'Levin';<br> szProfile = 'HTHooks';<br><br><br>function GetRegistryKey(): HKEY;<br>var<br> hAppKey: HKEY;<br> hSoftKey: HKEY;<br> hCompanyKey: HKEY;<br> dw: PDWORD;<br>begin<br> hAppKey := 0;<br> hSoftKey := 0;<br> hCompanyKey := 0;<br><br><br> GetMem(dw, SizeOf(DWORD));<br><br><br> if (RegOpenKeyEx(HKEY_CURRENT_USER, szSoftware, 0, KEY_WRITE or KEY_READ,<br> hSoftKey) = ERROR_SUCCESS) then<br> begin<br> if (RegCreateKeyEx(hSoftKey, szCompany, 0, nil,<br> REG_OPTION_NON_VOLATILE, KEY_WRITE or KEY_READ, nil,<br> hCompanyKey, dw) = ERROR_SUCCESS) then<br> RegCreateKeyEx(hCompanyKey, szProfile, 0, nil,<br> REG_OPTION_NON_VOLATILE, KEY_WRITE or KEY_READ, nil,<br> hAppKey, dw);<br> end;<br> if (hSoftKey <> 0) then<br> RegCloseKey(hSoftKey);<br> if (hCompanyKey <> 0) then<br> RegCloseKey(hCompanyKey);<br><br><br> FreeMem(dw);<br><br><br> Result := hAppKey;<br>end;<br><br><br>function GetModuleKey(const proc_name: PChar): HKEY;<br>var<br> hModule: HKEY;<br> hAppKey: HKEY;<br> FileName: PChar;<br> dw: PDWORD;<br>begin<br> hModule := 0;<br><br> // Work out the registry key to save this under<br>// sModulePrefs := malloc(strlen(sPrefSegment) + strlen(proc_name) + 1);<br> sModulePrefs := PChar('Software/HowTo/HookUsage/' + proc_name);<br> // if (sModulePrefs = nil) then Result := 0;<br> // sprintf(sModulePrefs, "%s%s", sPrefSegment, proc_name);<br><br><br> // Check whether the library's entry exists!<br> hAppKey := GetRegistryKey();<br> // if (hAppKey = 0) then Result := 0;<br><br><br> // Attempt to open the section for this application<br> if (RegOpenKeyEx(hAppKey,<br> sModulePrefs,<br> 0, KEY_WRITE or KEY_READ,<br> hModule<br>   <> ERROR_SUCCESS) then<br> begin<br> // Cut off the app directory and just use the name<br> FileName := NameFromPath(proc_name);<br><br><br> if (FileName = nil) then<br> RegCloseKey(hAppKey);<br><br><br> // Adjust the moduleprefs name<br>// sprintf(sModulePrefs, "%s%s", sPrefSegment, file_name);<br> sModulePrefs := PChar('Software/HowTo/HookUsage/' + FileName);<br><br>{ if FileName <> nil then<br> begin<br> Dec(FileName, SizeOf(Cardinal));<br> FreeMem(FileName, Cardinal(Pointer(FileName)^));<br> end;<br>}<br> GetMem(dw, SizeOf(DWORD));<br><br><br> // Now get the module key again<br> if (RegCreateKeyEx(hAppKey,<br> sModulePrefs,<br> 0, nil, REG_OPTION_NON_VOLATILE,<br> KEY_WRITE or KEY_READ,<br> nil,<br> hModule,<br> dw) <> ERROR_SUCCESS) then<br> RegCloseKey(hAppKey); // Couldn't find/create the key - fail!<br><br><br> FreeMem(dw);<br> end;<br><br><br> // Close the application registry key<br> RegCloseKey(hAppKey);<br><br><br> Result := hModule;<br>end;<br><br><br>procedure WriteProfileInt(key: PChar; Value: Integer);<br>begin<br> RegSetValueEx(<br> hModuleKey,<br> key,<br> 0,<br> REG_DWORD,<br> @Value,<br> sizeof(Value));<br>end;<br><br><br>function InitInstance(): BOOL;<br>var<br> proc_name: array[0..MAX_PATH] of Char;<br> Size: DWORD;<br>begin<br> // Create the global atoms<br> VNC_WINDOWPOS_ATOM := GlobalAddAtom(PChar(VNC_WINDOWPOS_ATOMNAME));<br> if (VNC_WINDOWPOS_ATOM = 0) then Result := False;<br><br><br> VNC_POPUPSELN_ATOM := GlobalAddAtom(PChar(VNC_POPUPSELN_ATOMNAME));<br> if (VNC_POPUPSELN_ATOM = 0) then Result := False;<br><br><br> // Attempt to get the program/module name<br> size := GetModuleFileName(<br> HInstance,<br> @proc_name,<br> MAX_PATH);<br> if Size = 0 then Result := False;<br><br><br> // Get the key for the module<br> hModuleKey := GetModuleKey(proc_name);<br> // if (hModuleKey = 0) then Result := False;<br><br><br> // Read in the prefs<br> prf_use_GetUpdateRect := BOOL(GetProfileInt(proc_name,<br> 'use_GetUpdateRect',<br> Integer(True)));<br><br><br> prf_use_Timer := BOOL(GetProfileInt(proc_name,<br> 'use_Timer',<br> Integer(FALSE)));<br> prf_use_KeyPress := BOOL(GetProfileInt(proc_name,<br> 'use_KeyPress',<br> Integer(TRUE)));<br><br><br> prf_use_LButtonUp := BOOL(GetProfileInt(proc_name,<br> 'use_LButtonUp',<br> Integer(TRUE)));<br><br><br> prf_use_MButtonUp := BOOL(GetProfileInt(proc_name,<br> 'use_MButtonUp',<br> Integer(TRUE)));<br><br><br> prf_use_RButtonUp := BOOL(GetProfileInt(proc_name,<br> 'use_RButtonUp',<br> Integer(TRUE)));<br><br><br> prf_use_Deferral := BOOL(GetProfileInt(proc_name,<br> 'use_Deferral',<br> Integer(TRUE)));<br><br><br> Result := True;<br>end;<br><br><br>function ExitInstance(): BOOL;<br>begin<br><br><br> // Free the created atoms<br> if (VNC_WINDOWPOS_ATOM <> 0) then<br> begin<br> GlobalDeleteAtom(VNC_WINDOWPOS_ATOM);<br> VNC_WINDOWPOS_ATOM := 0;<br> end;<br><br><br> if (VNC_POPUPSELN_ATOM <> 0) then<br> begin<br> GlobalDeleteAtom(VNC_POPUPSELN_ATOM);<br> VNC_POPUPSELN_ATOM := 0;<br> end;<br><br><br> // Write the module settings to disk<br> if (sModulePrefs <> nil) then<br> begin<br><br><br> WriteProfileInt(<br> 'use_GetUpdateRect',<br> Integer(prf_use_GetUpdateRect)<br> <br><br><br> WriteProfileInt(<br> 'use_Timer',<br> Integer(prf_use_Timer)<br> <br><br><br> WriteProfileInt(<br> 'use_KeyPress',<br> Integer(prf_use_KeyPress)<br> <br><br><br> WriteProfileInt(<br> 'use_LButtonUp',<br> Integer(prf_use_LButtonUp)<br> <br><br><br> WriteProfileInt(<br> 'use_MButtonUp',<br> Integer(prf_use_MButtonUp)<br> <br><br><br> WriteProfileInt(<br> 'use_RButtonUp',<br> Integer(prf_use_RButtonUp)<br> <br><br><br> WriteProfileInt(<br> 'use_Deferral',<br> Integer(prf_use_Deferral)<br> <br><br> {<br> if sModulePrefs <> nil then<br> begin<br> Dec(sModulePrefs, SizeOf(Cardinal));<br> FreeMem(sModulePrefs, Cardinal(Pointer(sModulePrefs)^));<br> end;<br> }<br> sModulePrefs := nil;<br> end;<br><br><br> // Close the registry key for this module<br> if (hModuleKey <> 0) then<br> RegCloseKey(hModuleKey);<br><br><br> Result := True;<br>end;<br><br><br>initialization<br> DisableThreadLibraryCalls(HInstance);<br> VNC_DEFERRED_UPDATE :=<br> RegisterWindowMessage('HTHooks.Deferred.UpdateMessage');<br> VNC_WINDOWPOS_ATOMNAME :=<br> GlobalAddAtom(PChar('HTHooks.CopyRect.WindowPos'));<br> VNC_POPUPSELN_ATOMNAME :=<br> GlobalAddAtom(PChar('HTHooks.PopUpMenu.Selected'));<br><br><br>finalization<br>// Just saw this now, upsssss...<br>// GlobalDeleteAtom(VNC_DEFERRED_UPDATE);<br><br><br>end.