c#

位置:IT落伍者 >> c# >> 浏览文章

C#中使用钩子控制鼠标实现代码


发布日期:2020年07月31日
 
C#中使用钩子控制鼠标实现代码
工作中有这样的需求某个控件panel的子控件textbox要实现只留鼠标右键copy注意同时还不能影响其它panel的子控件textbox怎么办?

答案是只有用钩子在codeporject上找到这么一个钩子

如图所示第一个文本框只有copy功能

UserActivityHookcs

using System;

using SystemRuntimeInteropServices;

using SystemReflection;

using SystemThreading;

using SystemWindowsForms;

using SystemComponentModel;

namespace gmaSystemWindows

{

/// <summary>

/// This class allows you to tap keyboard and mouse and / or to detect their activity even when an

/// application runes in background or does not have any user interface at all This class raises

/// common NET events with KeyEventArgs and MouseEventArgs so you can easily retrieve any information you need

/// </summary>

public class UserActivityHook

{

#region Windows structure definitions

/// <summary>

/// The POINT structure defines the x and y coordinates of a point

/// </summary>

/// <remarks>

/// ?url=/library/enus/gdi/rectangl_tiqasp

/// </remarks>

[StructLayout(LayoutKindSequential)]

private class POINT

{

/// <summary>

/// Specifies the xcoordinate of the point

/// </summary>

public int x;

/// <summary>

/// Specifies the ycoordinate of the point

/// </summary>

public int y;

}

/// <summary>

/// The MOUSEHOOKSTRUCT structure contains information about a mouse event passed to a WH_MOUSE hook procedure MouseProc

/// </summary>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookstructures/cwpstructasp

/// </remarks>

[StructLayout(LayoutKindSequential)]

private class MouseHookStruct

{

/// <summary>

/// Specifies a POINT structure that contains the x and ycoordinates of the cursor in screen coordinates

/// </summary>

public POINT pt;

/// <summary>

/// Handle to the window that will receive the mouse message corresponding to the mouse event [Page]

/// </summary>

public int hwnd;

/// <summary>

/// Specifies the hittest value For a list of hittest values see the description of the WM_NCHITTEST message

/// </summary>

public int wHitTestCode;

/// <summary>

/// Specifies extra information associated with the message

/// </summary>

public int dwExtraInfo;

}

/// <summary>

/// The MSLLHOOKSTRUCT structure contains information about a lowlevel keyboard input event

/// </summary>

[StructLayout(LayoutKindSequential)]

private class MouseLLHookStruct

{

/// <summary>

/// Specifies a POINT structure that contains the x and ycoordinates of the cursor in screen coordinates

/// </summary>

public POINT pt;

/// <summary>

/// If the message is WM_MOUSEWHEEL the highorder word of this member is the wheel delta

/// The loworder word is reserved A positive value indicates that the wheel was rotated forward

/// away from the user; a negative value indicates that the wheel was rotated backward toward the user

/// One wheel click is defined as WHEEL_DELTA which is

///If the message is WM_XBUTTONDOWN WM_XBUTTONUP WM_XBUTTONDBLCLK WM_NCXBUTTONDOWN WM_NCXBUTTONUP

/// or WM_NCXBUTTONDBLCLK the highorder word specifies which X button was pressed or released

/// and the loworder word is reserved This value can be one or more of the following values Otherwise mouseData is not used

///XBUTTON

///The first X button was pressed or released

///XBUTTON

///The second X button was pressed or released

/// </summary>

public int mouseData;

/// <summary>

/// Specifies the eventinjected flag An application can use the following value to test the mouse flags Value Purpose

///LLMHF_INJECTED Test the eventinjected flag

///

///Specifies whether the event was injected The value is if the event was injected; otherwise it is [Page]

///

///Reserved

/// </summary>

public int flags;

/// <summary>

/// Specifies the time stamp for this message

/// </summary>

public int time;

/// <summary>

/// Specifies extra information associated with the message

/// </summary>

public int dwExtraInfo;

}

/// <summary>

/// The KBDLLHOOKSTRUCT structure contains information about a lowlevel keyboard input event

/// </summary>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookstructures/cwpstructasp

/// </remarks>

[StructLayout(LayoutKindSequential)]

private class KeyboardHookStruct

{

/// <summary>

/// Specifies a virtualkey code The code must be a value in the range to

/// </summary>

public int vkCode;

/// <summary>

/// Specifies a hardware scan code for the key

/// </summary>

public int scanCode;

/// <summary>

/// Specifies the extendedkey flag eventinjected flag context code and transitionstate flag

/// </summary>

public int flags;

/// <summary>

/// Specifies the time stamp for this message

/// </summary>

public int time;

/// <summary>

/// Specifies extra information associated with the message

/// </summary>

public int dwExtraInfo;

}

#endregion

#region Windows function imports

/// <summary>

/// The SetWindowsHookEx function installs an applicationdefined hook procedure into a hook chain

/// You would install a hook procedure to monitor the system for certain types of events These events

/// are associated either with a specific thread or with all threads in the same desktop as the calling thread

/// </summary>[Page]

/// <param name=\idHook\>

/// [in] Specifies the type of hook procedure to be installed This parameter can be one of the following values

/// </param>

/// <param name=\lpfn\>

/// [in] Pointer to the hook procedure If the dwThreadId parameter is zero or specifies the identifier of a

/// thread created by a different process the lpfn parameter must point to a hook procedure in a dynamiclink

/// library (DLL) Otherwise lpfn can point to a hook procedure in the code associated with the current process

/// </param>

/// <param name=\hMod\>

/// [in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter

/// The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by

/// the current process and if the hook procedure is within the code associated with the current process

/// </param>

/// <param name=\dwThreadId\>

/// [in] Specifies the identifier of the thread with which the hook procedure is to be associated

/// If this parameter is zero the hook procedure is associated with all existing threads running in the

/// same desktop as the calling thread

/// </param>

/// <returns>

/// If the function succeeds the return value is the handle to the hook procedure

/// If the function fails the return value is NULL To get extended error information call GetLastError

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindowshookexasp

/// </remarks>

[DllImport(\userdll\ CharSet = CharSetAuto

CallingConvention = CallingConventionStdCall SetLastError = true)]

private static extern int SetWindowsHookEx(

int idHook

HookProc lpfn

IntPtr hMod

int dwThreadId);

/// <summary>

/// The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function

/// </summary>

/// <param name=\idHook\>

/// [in] Handle to the hook to be removed This parameter is a hook handle obtained by a previous call to SetWindowsHookEx [Page]

/// </param>

/// <returns>

/// If the function succeeds the return value is nonzero

/// If the function fails the return value is zero To get extended error information call GetLastError

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindowshookexasp

/// </remarks>

[DllImport(\userdll\ CharSet = CharSetAuto

CallingConvention = CallingConventionStdCall SetLastError = true)]

private static extern int UnhookWindowsHookEx(int idHook);

/// <summary>

/// The CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain

/// A hook procedure can call this function either before or after processing the hook information

/// </summary>

/// <param name=\idHook\>Ignored</param>

/// <param name=\nCode\>

/// [in] Specifies the hook code passed to the current hook procedure

/// The next hook procedure uses this code to determine how to process the hook information

/// </param>

/// <param name=\wParam\>

/// [in] Specifies the wParam value passed to the current hook procedure

/// The meaning of this parameter depends on the type of hook associated with the current hook chain

/// </param>

/// <param name=\lParam\>

/// [in] Specifies the lParam value passed to the current hook procedure

/// The meaning of this parameter depends on the type of hook associated with the current hook chain

/// </param>

/// <returns>

/// This value is returned by the next hook procedure in the chain

/// The current hook procedure must also return this value The meaning of the return value depends on the hook type

/// For more information see the descriptions of the individual hook procedures

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindowshookexasp

/// </remarks>[Page]

[DllImport(\userdll\ CharSet = CharSetAuto

CallingConvention = CallingConventionStdCall)]

private static extern int CallNextHookEx(

int idHook

int nCode

int wParam

IntPtr lParam);

/// <summary>

/// The CallWndProc hook procedure is an applicationdefined or librarydefined callback

/// function used with the SetWindowsHookEx function The HOOKPROC type defines a pointer

/// to this callback function CallWndProc is a placeholder for the applicationdefined

/// or librarydefined function name

/// </summary>

/// <param name=\nCode\>

/// [in] Specifies whether the hook procedure must process the message

/// If nCode is HC_ACTION the hook procedure must process the message

/// If nCode is less than zero the hook procedure must pass the message to the

/// CallNextHookEx function without further processing and must return the

/// value returned by CallNextHookEx

/// </param>

/// <param name=\wParam\>

/// [in] Specifies whether the message was sent by the current thread

/// If the message was sent by the current thread it is nonzero; otherwise it is zero

/// </param>

/// <param name=\lParam\>

/// [in] Pointer to a CWPSTRUCT structure that contains details about the message

/// </param>

/// <returns>

/// If nCode is less than zero the hook procedure must return the value returned by CallNextHookEx

/// If nCode is greater than or equal to zero it is highly recommended that you call CallNextHookEx

/// and return the value it returns; otherwise other applications that have installed WH_CALLWNDPROC

/// hooks will not receive hook notifications and may behave incorrectly as a result If the hook

/// procedure does not call CallNextHookEx the return value should be zero

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/callwndprocasp

/// </remarks>

private delegate int HookProc(int nCode int wParam IntPtr lParam);[Page]

/// <summary>

/// The ToAscii function translates the specified virtualkey code and keyboard

/// state to the corresponding character or characters The function translates the code

/// using the input language and physical keyboard layout identified by the keyboard layout handle

/// </summary>

/// <param name=\uVirtKey\>

/// [in] Specifies the virtualkey code to be translated

/// </param>

/// <param name=\uScanCode\>

/// [in] Specifies the hardware scan code of the key to be translated

/// The highorder bit of this value is set if the key is up (not pressed)

/// </param>

/// <param name=\lpbKeyState\>

/// [in] Pointer to a byte array that contains the current keyboard state

/// Each element (byte) in the array contains the state of one key

/// If the highorder bit of a byte is set the key is down (pressed)

/// The low bit if set indicates that the key is toggled on In this function

/// only the toggle bit of the CAPS LOCK key is relevant The toggle state

/// of the NUM LOCK and SCROLL LOCK keys is ignored

/// </param>

/// <param name=\lpwTransKey\>

/// [out] Pointer to the buffer that receives the translated character or characters

/// </param>

/// <param name=\fuState\>

/// [in] Specifies whether a menu is active This parameter must be if a menu is active or otherwise

/// </param>

/// <returns>

/// If the specified key is a dead key the return value is negative Otherwise it is one of the following values

/// Value Meaning

/// The specified virtual key has no translation for the current state of the keyboard

/// One character was copied to the buffer

/// Two characters were copied to the buffer This usually happens when a deadkey character

/// (accent or diacritic) stored in the keyboard layout cannot be composed with the specified

/// virtual key to form a single character

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/toasciiasp[Page]

/// </remarks>

[DllImport(\user\)]

private static extern int ToAscii(

int uVirtKey

int uScanCode

byte[] lpbKeyState

byte[] lpwTransKey

int fuState);

/// <summary>

/// The GetKeyboardState function copies the status of the virtual keys to the

/// specified buffer

/// </summary>

/// <param name=\pbKeyState\>

/// [in] Pointer to a byte array that contains keyboard key states

/// </param>

/// <returns>

/// If the function succeeds the return value is nonzero

/// If the function fails the return value is zero To get extended error information call GetLastError

/// </returns>

/// <remarks>

/// ?url=/library/enus/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/toasciiasp

/// </remarks>

[DllImport(\user\)]

private static extern int GetKeyboardState(byte[] pbKeyState);

[DllImport(\userdll\ CharSet = CharSetAuto CallingConvention = CallingConventionStdCall)]

private static extern short GetKeyState(int vKey);

#endregion

#region Windows constants

//values from Winuserh in Microsoft SDK

/// <summary>

/// Windows NT//XP: Installs a hook procedure that monitors lowlevel mouse input events

/// </summary>

private const int WH_MOUSE_LL = ;

/// <summary>

/// Windows NT//XP: Installs a hook procedure that monitors lowlevel keyboard input events

/// </summary>

private const int WH_KEYBOARD_LL = ;

/// <summary>

/// Installs a hook procedure that monitors mouse messages For more information see the MouseProc hook procedure

/// </summary>

private const int WH_MOUSE = ;

/// <summary>

/// Installs a hook procedure that monitors keystroke messages For more information see the KeyboardProc hook procedure

/// </summary>

private const int WH_KEYBOARD = ;

/// <summary>

/// The WM_MOUSEMOVE message is posted to a window when the cursor moves [Page]

/// </summary>

private const int WM_MOUSEMOVE = x;

/// <summary>

/// The WM_LBUTTONDOWN message is posted when the user presses the left mouse button

/// </summary>

private const int WM_LBUTTONDOWN = x;

/// <summary>

/// The WM_RBUTTONDOWN message is posted when the user presses the right mouse button

/// </summary>

private const int WM_RBUTTONDOWN = x;

/// <summary>

/// The WM_MBUTTONDOWN message is posted when the user presses the middle mouse button

/// </summary>

private const int WM_MBUTTONDOWN = x;

/// <summary>

/// The WM_LBUTTONUP message is posted when the user releases the left mouse button

/// </summary>

private const int WM_LBUTTONUP = x;

/// <summary>

/// The WM_RBUTTONUP message is posted when the user releases the right mouse button

/// </summary>

private const int WM_RBUTTONUP = x;

/// <summary>

/// The WM_MBUTTONUP message is posted when the user releases the middle mouse button

/// </summary>

private const int WM_MBUTTONUP = x;

/// <summary>

/// The WM_LBUTTONDBLCLK message is posted when the user doubleclicks the left mouse button

/// </summary>

private const int WM_LBUTTONDBLCLK = x;

/// <summary>

/// The WM_RBUTTONDBLCLK message is posted when the user doubleclicks the right mouse button

/// </summary>

private const int WM_RBUTTONDBLCLK = x;

/// <summary>

/// The WM_RBUTTONDOWN message is posted when the user presses the right mouse button

/// </summary>

private const int WM_MBUTTONDBLCLK = x;

/// <summary>

/// The WM_MOUSEWHEEL message is posted when the user presses the mouse wheel

/// </summary>

private const int WM_MOUSEWHEEL = xA;

/// <summary>

/// The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem

/// key is pressed A nonsystem key is a key that is pressed when the ALT key is not pressed

/// </summary>[Page]

private const int WM_KEYDOWN = x;

/// <summary>

/// The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem

/// key is released A nonsystem key is a key that is pressed when the ALT key is not pressed

/// or a keyboard key that is pressed when a window has the keyboard focus

/// </summary>

private const int WM_KEYUP = x;

/// <summary>

/// The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when the user

/// presses the F key (which activates the menu bar) or holds down the ALT key and then

/// presses another key It also occurs when no window currently has the keyboard focus;

/// in this case the WM_SYSKEYDOWN message is sent to the active window The window that

/// receives the message can distinguish between these two contexts by checking the context

/// code in the lParam parameter

/// </summary>

private const int WM_SYSKEYDOWN = x;

/// <summary>

/// The WM_SYSKEYUP message is posted to the window with the keyboard focus when the user

/// releases a key that was pressed while the ALT key was held down It also occurs when no

/// window currently has the keyboard focus; in this case the WM_SYSKEYUP message is sent

/// to the active window The window that receives the message can distinguish between

/// these two contexts by checking the context code in the lParam parameter

/// </summary>

private const int WM_SYSKEYUP = x;

private const byte VK_SHIFT = x;

private const byte VK_CAPITAL = x;

private const byte VK_NUMLOCK = x;

#endregion

/// <summary>

/// Creates an instance of UserActivityHook object and sets mouse and keyboard hooks

/// </summary>

/// <exception cref=\WinException\>Any windows problem</exception>

public UserActivityHook()

{

Start();

}

/// <summary>

/// Creates an instance of UserActivityHook object and installs both or one of mouse and/or keyboard hooks and starts rasing events

/// </summary>

/// <param name=\InstallMouseHook\><b>true</b> if mouse events must be monitored</param>[Page]

/// <param name=\InstallKeyboardHook\><b>true</b> if keyboard events must be monitored</param>

/// <exception cref=\WinException\>Any windows problem</exception>

/// <remarks>

/// To create an instance without installing hooks call new UserActivityHook(false false)

/// </remarks>

public UserActivityHook(bool InstallMouseHook bool InstallKeyboardHook)

{

Start(InstallMouseHook InstallKeyboardHook);

}

/// <summary>

/// Destruction

/// </summary>

~UserActivityHook()

{

//uninstall hooks and do not throw exceptions

Stop(true true false);

}

/// <summary>

/// Occurs when the user moves the mouse presses any mouse button or scrolls the wheel

/// </summary>

public event MouseEventHandler OnMouseActivity;

/// <summary>

/// Occurs when the user presses a key

/// </summary>

public event KeyEventHandler KeyDown;

/// <summary>

/// Occurs when the user presses and releases

/// </summary>

public event KeyPressEventHandler KeyPress;

/// <summary>

/// Occurs when the user releases a key

/// </summary>

public event KeyEventHandler KeyUp;

/// <summary>

/// Stores the handle to the mouse hook procedure

/// </summary>

private int hMouseHook = ;

/// <summary>

/// Stores the handle to the keyboard hook procedure

/// </summary>

private int hKeyboardHook = ;

/// <summary>

/// Declare MouseHookProcedure as HookProc type

/// </summary>

private static HookProc MouseHookProcedure;

/// <summary>

/// Declare KeyboardHookProcedure as HookProc type

/// </summary>

private static HookProc KeyboardHookProcedure;

/// <summary>

/// Installs both mouse and keyboard hooks and starts raising events

/// </summary>

/// <exception cref=\WinException\>Any windows problem</exception>

public void Start()[Page]

{

thisStart(true true);

}

/// <summary>

/// Installs both or one of mouse and/or keyboard hooks and starts raising events

/// </summary>

/// <param name=\InstallMouseHook\><b>true</b> if mouse events must be monitored</param>

/// <param name=\InstallKeyboardHook\><b>true</b> if keyboard events must be monitored</param>

/// <exception cref=\WinException\>Any windows problem</exception>

public void Start(bool InstallMouseHook bool InstallKeyboardHook)

{

// install Mouse hook only if it is not installed and must be installed

if (hMouseHook == && InstallMouseHook)

{

// Create an instance of HookProc

MouseHookProcedure = new HookProc(MouseHookProc);

//install hook

hMouseHook = SetWindowsHookEx(

WH_MOUSE_LL

MouseHookProcedure

MarshalGetHINSTANCE(

AssemblyGetExecutingAssembly()GetModules()[])

);

//If SetWindowsHookEx fails

if (hMouseHook == )

{

//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttributeSetLastError flag set

int errorCode = MarshalGetLastWinError();

//do cleanup

Stop(true false false);

//Initializes and throws a new instance of the WinException class with the specified error

throw new WinException(errorCode);

}

}

// install Keyboard hook only if it is not installed and must be installed

if (hKeyboardHook == && InstallKeyboardHook)

{

// Create an instance of HookProc

KeyboardHookProcedure = new HookProc(KeyboardHookProc);

//install hook

hKeyboardHook = SetWindowsHookEx(

WH_KEYBOARD_LL

KeyboardHookProcedure[Page]

MarshalGetHINSTANCE(

AssemblyGetExecutingAssembly()GetModules()[])

);

//If SetWindowsHookEx fails

if (hKeyboardHook == )

{

//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttributeSetLastError flag set

int errorCode = MarshalGetLastWinError();

//do cleanup

Stop(false true false);

//Initializes and throws a new instance of the WinException class with the specified error

throw new WinException(errorCode);

}

}

}

/// <summary>

/// Stops monitoring both mouse and keyboard events and rasing events

/// </summary>

/// <exception cref=\WinException\>Any windows problem</exception>

public void Stop()

{

thisStop(true true true);

}

/// <summary>

/// Stops monitoring both or one of mouse and/or keyboard events and rasing events

/// </summary>

/// <param name=\UninstallMouseHook\><b>true</b> if mouse hook must be uninstalled</param>

/// <param name=\UninstallKeyboardHook\><b>true</b> if keyboard hook must be uninstalled</param>

/// <param name=\ThrowExceptions\><b>true</b> if exceptions which occured during uninstalling must be thrown</param>

/// <exception cref=\WinException\>Any windows problem</exception>

public void Stop(bool UninstallMouseHook bool UninstallKeyboardHook bool ThrowExceptions)

{

//if mouse hook set and must be uninstalled

if (hMouseHook != && UninstallMouseHook)

{

//uninstall hook

int retMouse = UnhookWindowsHookEx(hMouseHook);

//reset invalid handle

hMouseHook = ;

//if failed and exception must be thrown

if (retMouse == && ThrowExceptions)

{[Page]

//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttributeSetLastError flag set

int errorCode = MarshalGetLastWinError();

//Initializes and throws a new instance of the WinException class with the specified error

throw new WinException(errorCode);

}

}

//if keyboard hook set and must be uninstalled

if (hKeyboardHook != && UninstallKeyboardHook)

{

//uninstall hook

int retKeyboard = UnhookWindowsHookEx(hKeyboardHook);

//reset invalid handle

hKeyboardHook = ;

//if failed and exception must be thrown

if (retKeyboard == && ThrowExceptions)

{

//Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttributeSetLastError flag set

int errorCode = MarshalGetLastWinError();

//Initializes and throws a new instance of the WinException class with the specified error

throw new WinException(errorCode);

}

}

}

/// <summary>

/// A callback function which will be called every time a mouse activity detected

/// </summary>

/// <param name=\nCode\>

/// [in] Specifies whether the hook procedure must process the message

/// If nCode is HC_ACTION the hook procedure must process the message

/// If nCode is less than zero the hook procedure must pass the message to the

/// CallNextHookEx function without further processing and must return the

/// value returned by CallNextHookEx

/// </param>

/// <param name=\wParam\>

/// [in] Specifies whether the message was sent by the current thread

/// If the message was sent by the current thread it is nonzero; otherwise it is zero

/// </param>

/// <param name=\lParam\>

/// [in] Pointer to a CWPSTRUCT structure that contains details about the message [Page]

/// </param>

/// <returns>

/// If nCode is less than zero the hook procedure must return the value returned by CallNextHookEx

/// If nCode is greater than or equal to zero it is highly recommended that you call CallNextHookEx

/// and return the value it returns; otherwise other applications that have installed WH_CALLWNDPROC

/// hooks will not receive hook notifications and may behave incorrectly as a result If the hook

/// procedure does not call CallNextHookEx the return value should be zero

/// </returns>

private int MouseHookProc(int nCode int wParam IntPtr lParam)

{

// if ok and someone listens to our events

if ((nCode >= ) && (OnMouseActivity != null))

{

//Marshall the data from callback

MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)MarshalPtrToStructure(lParam typeof(MouseLLHookStruct));

//detect button clicked

MouseButtons button = MouseButtonsNone;

short mouseDelta = ;

switch (wParam)

{

case WM_LBUTTONDOWN:

//case WM_LBUTTONUP:

//case WM_LBUTTONDBLCLK:

button = MouseButtonsLeft;

break;

case WM_RBUTTONDOWN:

//case WM_RBUTTONUP:

//case WM_RBUTTONDBLCLK:

button = MouseButtonsRight;

break;

case WM_MOUSEWHEEL:

//If the message is WM_MOUSEWHEEL the highorder word of mouseData member is the wheel delta

//One wheel click is defined as WHEEL_DELTA which is

//(value >> ) & xffff; retrieves the highorder word from the given bit value

mouseDelta = (short)((mouseHookStructmouseData >> ) & xffff);

//TODO: X BUTTONS (I havent them so was unable to test)

//If the message is WM_XBUTTONDOWN WM_XBUTTONUP WM_XBUTTONDBLCLK WM_NCXBUTTONDOWN WM_NCXBUTTONUP

//or WM_NCXBUTTONDBLCLK the highorder word specifies which X button was pressed or released

//and the loworder word is reserved This value can be one or more of the following values

//Otherwise mouseData is not used

break;

}

//double clicks

int clickCount = ;

if (button != MouseButtonsNone)

if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = ;

else clickCount = ;

//generate event

MouseEventArgs e = new MouseEventArgs(

button

clickCount

mouseHookStructptx

mouseHookStructpty

mouseDelta);

//raise it

OnMouseActivity(this e);

}

//call next hook

return CallNextHookEx(hMouseHook nCode wParam lParam);

}

/// <summary>

/// A callback function which will be called every time a keyboard activity detected

/// </summary>

/// <param name=\nCode\>

/// [in] Specifies whether the hook procedure must process the message

/// If nCode is HC_ACTION the hook procedure must process the message

/// If nCode is less than zero the hook procedure must pass the message to the

/// CallNextHookEx function without further processing and must return the

/// value returned by CallNextHookEx

/// </param>

/// <param name=\wParam\>

/// [in] Specifies whether the message was sent by the current thread

/// If the message was sent by the current thread it is nonzero; otherwise it is zero

/// </param>

/// <param name=\lParam\>

/// [in] Pointer to a CWPSTRUCT structure that contains details about the message

/// </param>

/// <returns>

/// If nCode is less than zero the hook procedure must return the value returned by CallNextHookEx

/// If nCode is greater than or equal to zero it is highly recommended that you call CallNextHookEx [Page]

/// and return the value it returns; otherwise other applications that have installed WH_CALLWNDPROC

/// hooks will not receive hook notifications and may behave incorrectly as a result If the hook

/// procedure does not call CallNextHookEx the return value should be zero

/// </returns>

private int KeyboardHookProc(int nCode Int wParam IntPtr lParam)

{

//indicates if any of underlaing events set eHandled flag

bool handled = false;

//it was ok and someone listens to events

if ((nCode >= ) && (KeyDown != null || KeyUp != null || KeyPress != null))

{

//read structure KeyboardHookStruct at lParam

KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)MarshalPtrToStructure(lParam typeof(KeyboardHookStruct));

//raise KeyDown

if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

{

Keys keyData = (Keys)MyKeyboardHookStructvkCode;

KeyEventArgs e = new KeyEventArgs(keyData);

KeyDown(this e);

handled = handled || eHandled;

}

// raise KeyPress

if (KeyPress != null && wParam == WM_KEYDOWN)

{

bool isDownShift = ((GetKeyState(VK_SHIFT) & x) == x ? true : false);

bool isDownCapslock = (GetKeyState(VK_CAPITAL) != ? true : false);

byte[] keyState = new byte[];

GetKeyboardState(keyState);

byte[] inBuffer = new byte[];

if (ToAscii(MyKeyboardHookStructvkCode

MyKeyboardHookStructscanCode

keyState

inBuffer

MyKeyboardHookStructflags) == )

{

char key = (char)inBuffer[];

if ((isDownCapslock ^ isDownShift) && CharIsLetter(key)) key = CharToUpper(key);

KeyPressEventArgs e = new KeyPressEventArgs(key);[Page]

KeyPress(this e);

handled = handled || eHandled;

}

}

// raise KeyUp

if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

{

Keys keyData = (Keys)MyKeyboardHookStructvkCode;

KeyEventArgs e = new KeyEventArgs(keyData);

KeyUp(this e);

handled = handled || eHandled;

}

}

//if event handled in application do not handoff to other listeners

if (handled)

return ;

else

return CallNextHookEx(hKeyboardHook nCode wParam lParam);

}

}

}

Formcs

using System;

using SystemDrawing;

using SystemCollections;

using SystemComponentModel;

using SystemWindowsForms;

using SystemData;

namespace WindowsApplication

{

/// <summary>

/// Form 的摘要说明清清月儿主页;

/// </summary>

public class Form : SystemWindowsFormsForm

{

private SystemWindowsFormsTextBox textBox;

private SystemWindowsFormsTextBox textBox;

private SystemWindowsFormsPanel panel;

/// <summary>

/// 必需的设计器变量

/// </summary>

private SystemComponentModelContainer components = null;

public Form()

{

//

// Windows 窗体设计器支持所必需的

//

InitializeComponent();

//

// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

//

}

/// <summary>

/// 清理所有正在使用的资源

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

componentsDispose();

}

}

baseDispose( disposing );

}

#region Windows 窗体设计器生成的代码

/// <summary>

/// 设计器支持所需的方法 不要使用代码编辑器修改[Page]

/// 此方法的内容

/// </summary>

private void InitializeComponent()

{

thistextBox = new SystemWindowsFormsTextBox();

thistextBox = new SystemWindowsFormsTextBox();

thispanel = new SystemWindowsFormsPanel();

thispanelSuspendLayout();

thisSuspendLayout();

//

// textBox

//

thistextBoxLocation = new SystemDrawingPoint( );

thistextBoxName = \textBox\;

thistextBoxSize = new SystemDrawingSize( );

thistextBoxTabIndex = ;

thistextBoxText = \\;

//

// textBox

//

thistextBoxLocation = new SystemDrawingPoint( );

thistextBoxMultiline = true;

thistextBoxName = \textBox\;

thistextBoxSize = new SystemDrawingSize( );

thistextBoxTabIndex = ;

thistextBoxText = \textBox\;

//

// panel

//

thispanelControlsAdd(thistextBox);

thispanelLocation = new SystemDrawingPoint( );

thispanelName = \panel\;

thispanelSize = new SystemDrawingSize( );

thispanelTabIndex = ;

//

// Form

//

thisAutoScaleBaseSize = new SystemDrawingSize( );

thisClientSize = new SystemDrawingSize( );

thisControlsAdd(thispanel);

thisControlsAdd(thistextBox);

thisName = \Form\;

thisText = \Form\;

thisLoad += new SystemEventHandler(thisForm_Load);

thispanelResumeLayout(false);

thisResumeLayout(false);

}

#endregion

/// <summary>

/// 应用程序的主入口点

/// </summary>

[STAThread]

static void Main()

{

ApplicationRun(new Form());

}

public void MyKeyDown(object sender KeyEventArgs e)

{

}

public void MyKeyPress(object sender KeyPressEventArgs e)[Page]

{

}

public void MyKeyUp(object sender KeyEventArgs e)

{

}

void choose_OnMouseActivity(object sender MouseEventArgs e)

{

//自定义右键

//if (ActiveControlParent == panel) 备用

//if (ActiveControlParent is SystemWindowsFormsPanel) 备用

if (ActiveControl == textBox)

{

MenuItem copy = new MenuItem(\copy\);

copyClick += new EventHandler(copy_Click);

MenuItem[] menuItems = new MenuItem[] { copy };

ContextMenu buttonMenu = new ContextMenu(menuItems);

textBoxContextMenu = buttonMenu;

//thisActiveControlContextMenu = buttonMenu; 备用

}

}

private void copy_Click(object sender EventArgs e)

{

ClipboardSetDataObject(textBoxSelectedText) ; //复制到剪切板

}

private void Form_Load(object sender SystemEventArgs e)

{

//初始化

gmaSystemWindowsUserActivityHook choosesc=new gmaSystemWindowsUserActivityHook();

choosescOnMouseActivity += new MouseEventHandler(choose_OnMouseActivity);

//choosescKeyDown += new KeyEventHandler(MyKeyDown);

//choosescKeyPress += new KeyPressEventHandler(MyKeyPress);

//choosescKeyUp += new KeyEventHandler(MyKeyUp);

}

}

}

说明这个钩子有点问题就是一次只能打开一个窗口(如果该窗口使用钩子)打开后一定要关闭否则出问题后果很严重!!!

               

上一篇:ADO.NET 2.0 Dataset和Datatable 新功能新

下一篇:调用.NET XML Web Services返回数据集合二