注册 登录
编程论坛 VFP论坛

在Win7中模拟鼠标左键单击给定位置的代码在Win10和Win11中不好使了,谁知道怎么解决?

jlliushi 发布于 2022-01-01 17:30, 2262 次点击
以下是在Win7中模拟鼠标左键单击给定位置的代码,在Win10和Win11中能移到指定位置,却不能实现单击了。谁知道怎么解决?
*--模拟鼠标动作,如 单击左键
MOUSEEVENTF_LEFTDOWN=0x2
MOUSEEVENTF_LEFTUP=0x4
MOUSEEVENTF_MIDDLEDOWN=0x20
MOUSEEVENTF_MIDDLEUP=0x40
MOUSEEVENTF_MOVE=0x1
MOUSEEVENTF_ABSOLUTE=0x8000
MOUSEEVENTF_RIGHTDOWN=0x8
MOUSEEVENTF_RIGHTUP=0x10
Declare mouse_event In Win32API Integer dwFlags,Integer dx,Integer dy,Integer cButtons,Integer dwExtraInfo
*在鼠标坐标系统中,不管什么分辨率屏幕在水平和垂直方向上均匀分割成65535×65535个单元
=mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE,10000,10000,0,0) &&移动鼠标到绝对位置10000,10000
=mouse_event(MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,0,0,0,0)       &&单击左键(按下再松开的组合)
*=mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0)
*=mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0)
9 回复
#2
吹水佬2022-01-01 18:26
如果能点击,只是点击的位置不准,可能是 dx、dy 的问题,这个与屏幕的宽度和高度有关。
dx、dy 不是以象素为单位的,而是以鼠标设备移动量为单位的。
当 dwFlags 设置了MOUSEEVENTF_ABSOLUTE标志,表示将鼠标移动到 dx,dy 的位置。
但是这个坐标值也不是以象素为单位的,这个值的范围是0到65535(0xFFFF)。
当dx等于0、dy等于0时表示屏幕的最左上角,当dx等于65535、dy等于65535时表示屏幕的最右下角,相当于将屏幕的宽和高分别65536等分。
API函数 GetSystemMetrics(SM_CXSCREEN) 可以返回屏幕的宽度,函数GetSystemMetrics(SM_CYSCREEN)可以返回屏幕的高度。
利用屏幕的宽度和高度就可以将象素坐标换算成相应的 dx、dy。
注意:这种换算最多会出现1象素的误差。
VFP也有个类似 GetSystemMetrics() 的函数 SYSMETRIC(),有可能也是调用 GetSystemMetrics()的。


#3
jlliushi2022-01-02 10:14
回复 2楼 吹水佬
现在的问题是能够移动到指定位置,而点击不起作用了!
#4
吹水佬2022-01-02 10:30
以下是引用jlliushi在2022-1-2 10:14:08的发言:

现在的问题是能够移动到指定位置,而点击不起作用了!

点击起不起作用要看具体点击的是什么,所谓的起作用应该是指触发了点击对象的点击事件,这个问题要具体分析,不是能模拟点击动作就一定有效。
#5
吹水佬2022-01-03 11:52
win10专业版21H2测试未见异常
只有本站会员才能查看附件,请 登录

程序代码:
#define MOUSEEVENTF_ABSOLUTE  0x8000
#define MOUSEEVENTF_MOVE      0x1
#define MOUSEEVENTF_LEFTDOWN  0x2
#define MOUSEEVENTF_LEFTUP    0x4
DECLARE long mouse_event IN user32 long,long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
READ EVENTS

DEFINE CLASS form1 as Form
    ShowWindow = 2
    AutoCenter = .T.
    ADD OBJECT command1 as commandbutton WITH top=10,left=10,height=22,caption="test"
    ADD OBJECT command2 as commandbutton WITH top=10,left=120,height=22
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC
    PROCEDURE command1.click
        dx = (0xFFFF/SYSMETRIC(1)) * (SYSMETRIC(3)+thisform.Left+Left+10)
        dy = (0xFFFF/SYSMETRIC(2)) * (SYSMETRIC(4)+SYSMETRIC(9)+thisform.Top+Top+10)
        mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE,dx,dy,0,0)
        mouse_event(MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,0,0,0,0)
    ENDPROC
    PROCEDURE command2.click
        MESSAGEBOX("点击了command2")
    ENDPROC
ENDDEFINE
#6
nbwww2022-01-03 19:18
借贴请教一下版主,鼠标中间的滚轮上下可以模拟吗?

以下是引用吹水佬在2022-1-3 11:52:56的发言:

win10专业版21H2测试未见异常

#define MOUSEEVENTF_ABSOLUTE  0x8000
#define MOUSEEVENTF_MOVE      0x1
#define MOUSEEVENTF_LEFTDOWN  0x2
#define MOUSEEVENTF_LEFTUP    0x4
DECLARE long mouse_event IN user32 long,long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
READ EVENTS

DEFINE CLASS form1 as Form
    ShowWindow = 2
    AutoCenter = .T.
    ADD OBJECT command1 as commandbutton WITH top=10,left=10,height=22,caption="test"
    ADD OBJECT command2 as commandbutton WITH top=10,left=120,height=22
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC
    PROCEDURE command1.click
        dx = (0xFFFF/SYSMETRIC(1)) * (SYSMETRIC(3)+thisform.Left+)
        dy = (0xFFFF/SYSMETRIC(2)) * (SYSMETRIC(4)+SYSMETRIC(9)+thisform.Top+)
        mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE,dx,dy,0,0)
        mouse_event(MOUSEEVENTF_LEFTDOWN+MOUSEEVENTF_LEFTUP,0,0,0,0)
    ENDPROC
    PROCEDURE command2.click
        MESSAGEBOX("点击了command2")
    ENDPROC
ENDDEFINE

#7
吹水佬2022-01-03 20:52
回复 6楼 nbwww
用 MOUSEEVENTF_WHEEL  0x0800
程序代码:
#define MOUSEEVENTF_ABSOLUTE  0x8000
#define MOUSEEVENTF_MOVE      0x1
#define MOUSEEVENTF_WHEEL     0x0800
DECLARE long mouse_event IN user32 long,long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
READ EVENTS

DEFINE CLASS form1 as Form
    ShowWindow = 2
    AutoCenter = .T.
    ADD OBJECT command1 as commandbutton WITH top=10,left=10,height=22,caption="向前滚动"
    ADD OBJECT command2 as commandbutton WITH top=10,left=120,height=22,caption="向后滚动"
    ADD OBJECT list1 as listbox WITH top=40,left=10
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC
    PROCEDURE list1.init
        FOR i=1 TO 100
            this.AddItem(TRANSFORM(i))
        ENDFOR
    ENDPROC   
    PROCEDURE myMouseWheel(oThis, nData)
        dx = (0xFFFF/SYSMETRIC(1)) * (SYSMETRIC(3)+thisform.Left+oThis.Left+10)
        dy = (0xFFFF/SYSMETRIC(2)) * (SYSMETRIC(4)+SYSMETRIC(9)+thisform.Top+oThis.Top+10)
        mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE,dx,dy,0,0)
        oThis.setfocus
        FOR i=1 TO 10
            mouse_event(MOUSEEVENTF_WHEEL,0,0,nData,0)
            INKEY(0.1)
        ENDFOR
    ENDPROC
    PROCEDURE command1.click
        thisform.myMouseWheel(thisform.list1, 120)
    ENDPROC
    PROCEDURE command2.click
        thisform.myMouseWheel(thisform.list1, -120)
    ENDPROC
ENDDEFINE

#8
schtg2022-01-04 05:47
回复 7楼 吹水佬
太好啦,谢谢!
#9
nbwww2022-01-04 18:08

万分感谢  收藏!!

以下是引用吹水佬在2022-1-3 20:52:21的发言:

用 MOUSEEVENTF_WHEEL  0x0800
#define MOUSEEVENTF_ABSOLUTE  0x8000
#define MOUSEEVENTF_MOVE      0x1
#define MOUSEEVENTF_WHEEL     0x0800
DECLARE long mouse_event IN user32 long,long,long,long,long
of = CREATEOBJECT("form1")
of.show(1)
READ EVENTS

DEFINE CLASS form1 as Form
    ShowWindow = 2
    AutoCenter = .T.
    ADD OBJECT command1 as commandbutton WITH top=10,left=10,height=22,caption="向前滚动"
    ADD OBJECT command2 as commandbutton WITH top=10,left=120,height=22,caption="向后滚动"
    ADD OBJECT list1 as listbox WITH top=40,left=10
    PROCEDURE Destroy
        CLEAR EVENTS
    ENDPROC
    PROCEDURE list1.init
        FOR i=1 TO 100
            this.AddItem(TRANSFORM(i))
        ENDFOR
    ENDPROC   
    PROCEDURE myMouseWheel(oThis, nData)
        dx = (0xFFFF/SYSMETRIC(1)) * (SYSMETRIC(3)+thisform.Left+oThis.Left+10)
        dy = (0xFFFF/SYSMETRIC(2)) * (SYSMETRIC(4)+SYSMETRIC(9)+thisform.Top+oThis.Top+10)
        mouse_event(MOUSEEVENTF_ABSOLUTE+MOUSEEVENTF_MOVE,dx,dy,0,0)
        oThis.setfocus
        FOR i=1 TO 10
            mouse_event(MOUSEEVENTF_WHEEL,0,0,nData,0)
            INKEY(0.1)
        ENDFOR
    ENDPROC
    PROCEDURE command1.click
        thisform.myMouseWheel(thisform.list1, 120)
    ENDPROC
    PROCEDURE command2.click
        thisform.myMouseWheel(thisform.list1, -120)
    ENDPROC
ENDDEFINE

#10
zhaihs772022-01-19 19:39
标记一下备查
1