mouse_event只能向当前鼠标所在的地方发送事件,可不可以向一个指定的座标发送而又不影响当前鼠标的运行呢?就像向一个句柄发送消息一样

解决方案 »

  1.   

    模拟一次鼠标事件
    Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
    dwFlags:标志位集,指定点击按钮和鼠标动作的多种情况。此参数里的各位可以是下列值的任何合理组合:
    MOOSE_EVENTF_ABSOLOTE:表明参数dX,dy含有规范化的绝对坐标。如果不设置此位,参数含有相对数据:相对于上次位置的改动位置。此标志可被设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分。
    MOOSEEVENTFMOVE:表明发生移动。
    M00SEEVENTF_LEFTDOWN:表明接按下鼠标左键。
    M00SEEVENTF_LEFTUP:表明松开鼠标左键。
    MOOSEEVENTF_RIGHTDOWN:表明按下鼠标右键。
    MOOSEEVENTF_RIGHTUP:表明松开鼠标右键。
    MOOSEEVENTF_MIDDLEDOWN:表明按下鼠标中键。
    MOOSEEVENTF_MIDDLEUP:表明松开鼠标中键。
    MOOSEEVENTF_WHEEL:在Windows NT中如果鼠标有一个轮,表明鼠标轮被移动。移动的数量由dwData给出。
    dx:指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLOTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
    dy:指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLVTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
    dwData:如果dwFlags为MOOSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。
        如果dwFlagsS不是MOOSEEVENTF_WHEEL,则dWData应为零。
    dwExtralnfo:指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessgeExtrajnfo来获得此附加信息。如果鼠标被移动,用设置MOUSEEVENTF_MOVE来表明,dX和dy保留移动的信息。给出的信息是绝对或相对整数值。
        如果指定了MOWSEEVENTF_ABSOLOTE值,则dX和dy含有标准化的绝对坐标,其值在0到65535之间。事件程序将此坐标映射到显示表面。坐标(0,0)映射到显示表面的左上角,(6553,65535)映射到右下角。
        如果没指定MOWSEEVENTF_ABSOLOTE,dX和dy表示相对于上次鼠标事件产生的位置(即上次报告的位置)的移动。正值表示鼠标向右(或下)移动;负值表示鼠标向左(或上)移动。
        鼠标的相对移动服从鼠标速度和加速度等级的设置,一个最终用户用鼠标控制面板应用程序来设置这些值,应用程序用函数SystemParameterslnfo来取得和设置这些值。
        在应用加速时系统对指定相对鼠标移动提供了两个测试。如果指定的沿X轴y轴的距离比第一个鼠标阈值大,并且鼠标的加速等级非零,则操作系统将距离加倍。如果指定的沿X轴或y轴的距离比第二个鼠标阈值大,并且鼠标的加速等级为2,则操作系统将从第一个阈测试得来的距离加倍。这样就允许操作系统将指定鼠标沿X轴或y轴的相对位移加到4倍。
        一旦应用了加速,系统用期望的鼠标速度换算合成的值。鼠标速度的范围是从1(最慢)到20(最快),并代表基于鼠标移动的距离指示符移动的数量。缺省值是10,表示对鼠标的移动设有附加的修改。
        函数mouse_event需要用的应用程序用来合成鼠标事件。也被应用程序用来取得鼠标位置和鼠标按键状态之外的鼠标信息。例如,如果输入板制造商想将基于画笔的信息传给自己的应用程序,可以写一个直接与输入板硬件通信的动态键接库(DLL),获得附加的信息,并保存到一个队列中。DLL然后调用mouse_event,用标准按键和x/y位置数据,并在参数dwExtralnfo设置排列的附加信息的指针或索引。当应用程序需要附加信息时,调用DLL(连同存贮在dwEXtralnfo中的指针或索引),则DLL返回附加信息。
        Windows CE:Windows CE不支持参数 dwFlags取MOOSE EVENTF WHEEL常数。'模拟鼠标单击
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTUP, 0,0, 0, 0
      进行相对运动的时候,由SystemParametersInfo函数规定的系统鼠标轨迹速度会应用于鼠标运行的速度
      

  2.   

    我现在需要在绝对位置上模拟,
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTDOWN, 193, 145, 0, 0
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTUP, 193,145, 0, 0
    其中193、145是我用getcursorpos得到的座标,是不是要转换一下这个数?
      

  3.   

    你参考一下这个例子:'【VB声明】
    '  Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)'【说明】
    '  模拟一次鼠标事件'【备注】
    '  进行相对运动的时候,由SystemParametersInfo函数规定的系统鼠标轨迹速度会应用于鼠标运行的速度'【参数表】
    '  dwFlags --------  Long,下述标志的一个组合
    '  MOUSEEVENTF_ABSOLUTE
    '  dx和dy指定鼠标坐标系统中的一个绝对位置。在鼠标坐标系统中,屏幕在水平和垂直方向上均匀分割成65535×65535个单元 -
    '  MOUSEEVENTF_MOVE         移动鼠标
    '  MOUSEEVENTF_LEFTDOWN     模拟鼠标左键按下
    '  MOUSEEVENTF_LEFTUP       模拟鼠标左键抬起
    '  MOUSEEVENTF_RIGHTDOWN    模拟鼠标右键按下
    '  MOUSEEVENTF_RIGHTUP      模拟鼠标右键抬起
    '  MOUSEEVENTF_MIDDLEDOWN   模拟鼠标中键按下
    '  MOUSEEVENTF_MIDDLEUP     模拟鼠标中键抬起
    '  dx -------------  Long,根据是否指定了MOUSEEVENTF_ABSOLUTE标志,指定水平方向的绝对位置或相对运动''  dy -------------  Long,根据是否指定了MOUSEEVENTF_ABSOLUTE标志,指定垂直方向的绝对位置或相对运动'  cButtons -------  Long,未使用'  dwExtraInfo ----  Long,通常未用的一个值。用GetMessageExtraInfo函数可取得这个值。可用的值取决于特定的驱动程序
    Option Explicit
        Private Declare Sub mouse_event Lib "user32" _
        ( _
        ByVal dwFlags As Long, _
        ByVal dx As Long, _
        ByVal dy As Long, _
        ByVal cButtons As Long, _
        ByVal dwExtraInfo As Long _
        )'Option_Tag标示选择了哪一种模拟事件
    Dim Option_Tag As Integer
    'OnTest标示是否处于模拟状态,以便我们停止模拟
    Dim OnTest As Boolean
    '对API变量的定义
    Const MOUSEEVENTF_LEFTDOWN = &H2
    Const MOUSEEVENTF_LEFTUP = &H4
    Const MOUSEEVENTF_MIDDLEDOWN = &H20
    Const MOUSEEVENTF_MIDDLEUP = &H40
    Const MOUSEEVENTF_MOVE = &H1
    Const MOUSEEVENTF_ABSOLUTE = &H8000
    Const MOUSEEVENTF_RIGHTDOWN = &H8
    Const MOUSEEVENTF_RIGHTUP = &H10'控制 模拟的开始与结束
    Private Sub Command1_Click()'如果不处于模拟状态
    If OnTest = False Then
    Command1.Caption = "快停下来吧"
    Timer1.Enabled = True
    OnTest = True
    '如果处于模拟状态
    Else
    Command1.Caption = "试一试"
    Timer1.Enabled = False
    OnTest = False
    End If
    End Sub'窗体加载时一些变量需要设置
    Private Sub Form_Load()
    Option_Tag = 1
    Timer1.Enabled = False
    OnTest = False
    End Sub'选择了模拟“鼠标左键单击事件”
    Private Sub Option1_Click()
    Option_Tag = 1      '左键单击事件
    Option2.Value = False
    Option3.Value = False
    End Sub'选择了模拟“鼠标右键单击事件”
    Private Sub Option2_Click()
    Option_Tag = 2      '右键单击事件
    Option1.Value = False
    Option3.Value = False
    End Sub'选择了模拟“鼠标双击事件”
    Private Sub Option3_Click()
    Option_Tag = 3      '双击事件
    Option1.Value = False
    Option2.Value = False
    End Sub'每隔一秒中模拟一次鼠标事件
    Private Sub Timer1_Timer()
    If Option_Tag = 1 Then
        '调用了mouse_event函数,其参数的设置见前面说明
        '如果同时要模拟两个鼠标事件,可以用 Or 将两个参数连接
        '这里是 鼠标左键按下 和松开两个事件的组合即一次单击
        mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
    ElseIf Option_Tag = 2 Then
        '模拟鼠标右键单击事件
        mouse_event MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
    Else
        '两次连续的鼠标左键单击事件 构成一次鼠标双击事件
        mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
        mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
    End If
    End Sub
      

  4.   

    FORM1上添加三个OPTION BUTTON,一个TIMER,和一个COMMANDBUTTON
      

  5.   

    Option Explicit' 注意最后一个参数改了,原型是 byval lParam as long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
        ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, _
         ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As LongPrivate Const GWL_WNDPROC = (-4)Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
        ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Const WM_LBUTTONDBLCLK = &H203
    Private Type POINTAPI
        x As Long
        y As Long
    End TypePrivate Sub Command1_Click()
        Dim lpPoint As POINTAPI
        lpPoint.x = 1     ' 向 picture1 的(1,1)处发送鼠标双击消息
        lpPoint.y = 1
        CallWindowProc GetWindowLong(Me.hwnd, GWL_WNDPROC), Picture1.hwnd, WM_LBUTTONDBLCLK, 0, lpPoint
    End SubPrivate Sub Picture1_DblClick()
        MsgBox "又失恋了。"
    End Sub
      

  6.   

    to:铁拳,如果他想向一个FORM中指定的一个没有控件的地方发一个这样的事件,如何?
      

  7.   

    上述函数中的dx和dy就是绝对位置:
    dx:指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLOTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
    dy:指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOOSEEVENTF_ABSOLVTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
      

  8.   

    我将代码回在按纽上
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTDOWN, 193, 145, 0, 0
    mouse_event MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTUP, 193,145, 0, 0
    其中193、145是我用getcursorpos得到的座标然后我一按按纽,发现该事件发送到按纽上而不是我指定的座标上了(现在才终于入正题让大家知道我所遇到的问题了)
      

  9.   

    现在问题更清楚了
    我将参数改为MOUSEEVENTF_MOVE
    能顺利移到指定座标但一改为MOUSEEVENTF_LEFTDOWN就不能在指定座标发送按下消息为何?
      

  10.   

    你应该用SetCursorPos 函数啊,把鼠标坐标设置到既定位置,再调用MOUSE_EVENT
      

  11.   

    mouse_event MOUSEEVENTF_MOVE Or MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 193, 145, 0, 0
    mouse_event MOUSEEVENTF_MOVE Or MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 193, 145, 0, 0
    可以实现
      

  12.   

    老狼怎么都喜欢用那么古怪的方法呀。刚才想回贴,结果掉线了,等了好久才连上,可连上后又回贴,结果又掉线了,郁闷
    to 老狼: to:铁拳,如果他想向一个FORM中指定的一个没有控件的地方发一个这样的事件,如何?
    用 WindowFromPoint 获取指定位置的句柄。
      

  13.   

    先用 WindowFromPoint 获取指定位置所持句柄,
    lpPoint.x=1 'x 座标
    lpPoint.y=1 'y 座标
    hWnd=WindowFromPoint(lpPoint.x,lpPoint.y)
    然后再调用
    callwindowproc getwindowlong(hwnd,gwl_wndproc),hwnd,WM_LBUTTONDBLCLK,0,lpPoint
      

  14.   

    '我把完整的代码贴出来吧。
    Option ExplicitPrivate Const WM_LBUTTONDBLCLK = &H203
    Private Const WM_LBUTTONDOWN = &H201
    Private Const WM_LBUTTONUP = &H202
    Private Const WM_MBUTTONDBLCLK = &H209
    Private Const WM_MBUTTONDOWN = &H207
    Private Const WM_MBUTTONUP = &H208
    Private Const WM_RBUTTONDBLCLK = &H206
    Private Const WM_RBUTTONDOWN = &H204
    Private Const WM_RBUTTONUP = &H205
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As LongPrivate Const GWL_WNDPROC = (-4)
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Private Type POINTAPI
        x As Long
        y As Long
    End Type
    Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPrivate Sub cmdSend_Click()
        Dim lpPoint As POINTAPI
        Dim hMyWnd As Long
        lpPoint.x = 100     ' X 座标
        lpPoint.y = 100     ' Y 座标
        hMyWnd = WindowFromPoint(lpPoint.x, lpPoint.y)
        
        ' 这里是一串组合消息
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_LBUTTONDOWN, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_LBUTTONUP, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_LBUTTONDBLCLK, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_MBUTTONDOWN, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_MBUTTONUP, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_MBUTTONDBLCLK, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_RBUTTONDOWN, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_RBUTTONUP, 0, lpPoint
        CallWindowProc GetWindowLong(hMyWnd, GWL_WNDPROC), hMyWnd, WM_RBUTTONUP, 0, lpPoint
    End Sub
      

  15.   

    我看了半天,觉得铁拳的命好苦,不过谁是老狼啊我现在用的是迈克尔乔丹的方法,虽然有点笨(看隐约看到鼠标自己移动的痕迹,像幽灵一样)铁拳的方法我不能用,因为WindowFromPoint不是万能的,它最多只能获取子控件的句柄,如果像LABEL这样的就没办法了,所以只能通过座标不过,铁拳的代码值得收藏,1人100分请铁拳到http://expert.csdn.net/Expert/topic/2980/2980014.xml?temp=.5600092拿分
      

  16.   

    真正的label 应属于 static类,而vb里面很多控件都是假的,比如SysListView32类,SysTreeView32类等等,在VB里都拿 ListViewWndClass,TreeViewWndClass 或 ListView20WndClass, TreeView20WndClass 等换掉了,连 ReBarWindow32 类也是拿一个容器装着的,还有 ToolbarWindow32 也是拿一个容器装着的,对于真正爱好 Windows 编程的人来说损失还真不少,这些问题都是在新的操作系统(xp)出来以后才表现出来的。