mouse_event是一個(gè)計(jì)算機(jī)函數(shù),功能是綜合鼠標(biāo)移動(dòng)和按鈕點(diǎn)擊。如果鼠標(biāo)被移動(dòng),用設(shè)置MOUSEEVENTF_MOVE來(lái)表明,dX和dy保留移動(dòng)的信息。給出的信息是絕對(duì)或相對(duì)整數(shù)值。
在自動(dòng)化測(cè)試的開(kāi)發(fā)中,有一些控件的ID是很難找到的,所以有些時(shí)候,我們直接設(shè)置鼠標(biāo)的位置,然后是用click事件,會(huì)收到很好的效果。在Windows API中有個(gè)mouse_event函數(shù)為我們準(zhǔn)備好了這一切。
這個(gè)函數(shù)在user32.dll這個(gè)庫(kù)文件里面。我們可以在C:/WINDOWS/system32(XP系統(tǒng))這個(gè)目錄下找到這個(gè)文件,他是系統(tǒng)自帶的。 我們以C#直接調(diào)用這個(gè)文件中的API為例子來(lái)說(shuō)下怎么進(jìn)行鼠標(biāo)操作,首先在我們C#中聲明引用,如果是一個(gè)基于From的程序,這個(gè)聲明的位置寫(xiě)在你的From class就可以了
[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
參數(shù) 意義
dwFlags Long,下表中標(biāo)志之一或它們的組合
dx,dy Long,根據(jù)MOUSEEVENTF_ABSOLUTE標(biāo)志,指定x,y方向的絕對(duì)位置或相對(duì)位置
cButtons Long,沒(méi)有使用
dwExtraInfo Long,沒(méi)有使用
dwFlags常數(shù) 意義
const int MOUSEEVENTF_MOVE = 0x0001; 移動(dòng)鼠標(biāo)
const int MOUSEEVENTF_LEFTDOWN = 0x0002; 模擬鼠標(biāo)左鍵按下
const int MOUSEEVENTF_LEFTUP = 0x0004; 模擬鼠標(biāo)左鍵抬起
const int MOUSEEVENTF_RIGHTDOWN = 0x0008; 模擬鼠標(biāo)右鍵按下
const int MOUSEEVENTF_RIGHTUP = 0x0010; 模擬鼠標(biāo)右鍵抬起
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; 模擬鼠標(biāo)中鍵按下
const int MOUSEEVENTF_MIDDLEUP = 0x0040; 模擬鼠標(biāo)中鍵抬起
const int MOUSEEVENTF_ABSOLUTE = 0x8000; 標(biāo)示是否采用絕對(duì)坐標(biāo)
程序中我們直接調(diào)用mouse_event函數(shù)就可以了
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 500, 500, 0, 0);
1、這里是鼠標(biāo)左鍵按下和松開(kāi)兩個(gè)事件的組合即一次單擊:
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
2、模擬鼠標(biāo)右鍵單擊事件:
mouse_event (MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 )
3、兩次連續(xù)的鼠標(biāo)左鍵單擊事件 構(gòu)成一次鼠標(biāo)雙擊事件:
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 )
4、使用絕對(duì)坐標(biāo)
MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 500, 500, 0, 0
需要說(shuō)明的是,如果沒(méi)有使用MOUSEEVENTF_ABSOLUTE,函數(shù)默認(rèn)的是相對(duì)于鼠標(biāo)當(dāng)前位置的點(diǎn),如果dx,和dy,用0,0表示,這函數(shù)認(rèn)為是當(dāng)前鼠標(biāo)所在的點(diǎn)。5、直接設(shè)定絕對(duì)坐標(biāo)并單擊
mouse_event(MOUSEEVENTF_LEFTDOWN, X * 65536 / 1024, Y * 65536 / 768, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, X * 65536 / 1024, Y * 65536 / 768, 0, 0);
其中X,Y分別是你要點(diǎn)擊的點(diǎn)的橫坐標(biāo)和縱坐標(biāo)
使用mouse_event時(shí)屏幕絕對(duì)坐標(biāo)如何計(jì)算
[DllImport("user32", EntryPoint="mouse_event")]
public static extern void mouse_event (
int dwFlags,
int dx,
int dy,
int cButtons,
int dwExtraInfo
);
MOOSE_EVENTF_ABSOLOTE:表明參數(shù)dX,dy含有規(guī)范化的絕對(duì)坐標(biāo)。如果不設(shè)置此位,參數(shù)含有相對(duì)數(shù)據(jù):相對(duì)于上次位置的改動(dòng)位置。此標(biāo)志可被設(shè)置,也可不設(shè)置,不管鼠標(biāo)的類型或與系統(tǒng)相連的類似于鼠標(biāo)的設(shè)備的類型如何。要得到關(guān)于相對(duì)鼠標(biāo)動(dòng)作的信息,參見(jiàn)下面?zhèn)渥⒉糠帧?
MOOSEEVENTFMOVE:表明發(fā)生移動(dòng)。
M00SEEVENTF_LEFTDOWN:表明接按下鼠標(biāo)左鍵。
M00SEEVENTF_LEFTUP:表明松開(kāi)鼠標(biāo)左鍵。
MOOSEEVENTF_RIGHTDOWN:表明按下鼠標(biāo)右鍵。
MOOSEEVENTF_RIGHTUP:表明松開(kāi)鼠標(biāo)右鍵。
MOOSEEVENTF_MIDDLEDOWN:表明按下鼠標(biāo)中鍵。
MOOSEEVENTF_MIDDLEUP:表明松開(kāi)鼠標(biāo)中鍵。
MOOSEEVENTF_WHEEL:在Windows NT中如果鼠標(biāo)有一個(gè)輪,表明鼠標(biāo)輪被移動(dòng)。移動(dòng)的數(shù)量由dwData給出。
dx:指定鼠標(biāo)沿x軸的絕對(duì)位置或者從上次鼠標(biāo)事件產(chǎn)生以來(lái)移動(dòng)的數(shù)量,依賴于MOOSEEVENTF_ABSOLOTE的設(shè)置。給出的絕對(duì)數(shù)據(jù)作為鼠標(biāo)的實(shí)際X坐標(biāo);給出的相對(duì)數(shù)據(jù)作為移動(dòng)的mickeys數(shù)。一個(gè)mickey表示鼠標(biāo)移動(dòng)的數(shù)量,表明鼠標(biāo)已經(jīng)移動(dòng)。
dy:指定鼠標(biāo)沿y軸的絕對(duì)位置或者從上次鼠標(biāo)事件產(chǎn)生以來(lái)移動(dòng)的數(shù)量,依賴于MOOSEEVENTF_ABSOLVTE的設(shè)置。給出的絕對(duì)數(shù)據(jù)作為鼠標(biāo)的實(shí)際y坐標(biāo),給出的相對(duì)數(shù)據(jù)作為移動(dòng)的mickeys數(shù)。
dwData:如果dwFlags為MOOSEEVENTF_WHEEL,則dwData指定鼠標(biāo)輪移動(dòng)的數(shù)量。正值表明鼠標(biāo)輪向前轉(zhuǎn)動(dòng),即遠(yuǎn)離用戶的方向;負(fù)值表明鼠標(biāo)輪向后轉(zhuǎn)動(dòng),即朝向用戶。一個(gè)輪擊定義為WHEEL_DELTA,即120。
如果dwFlagsS不是MOOSEEVENTF_WHEEL,則dWData應(yīng)為零。
dwExtralnfo:指定與鼠標(biāo)事件相關(guān)的附加32位值。應(yīng)用程序調(diào)用函數(shù)GetMessgeExtrajnfo來(lái)獲得此附加信息。
看完幫助還是不知道怎么計(jì)算dx和dy,下面給出C++的代碼以供參考:
cursor.X = static_cast<unsigned short>( position.point.x * 65535 / pimpl->desktopSize.width );
cursor.Y = static_cast<unsigned short>( position.point.y * 65535 / pimpl->desktopSize.height );
c# mouse_event 模擬鼠標(biāo)點(diǎn)擊事件 絕對(duì)位置
首先添加
using System.Runtime.InteropServices; //鼠標(biāo)事件 因?yàn)槲矣玫牟欢?,所以其他參?shù)沒(méi)有寫(xiě) private readonly int MOUSEEVENTF_LEFTDOWN = 0x0002;//模擬鼠標(biāo)移動(dòng) private readonly int MOUSEEVENTF_MOVE = 0x0001;//模擬鼠標(biāo)左鍵按下 private readonly int MOUSEEVENTF_LEFTUP = 0x0004;//模擬鼠標(biāo)左鍵抬起 private readonly int MOUSEEVENTF_ABSOLUTE = 0x8000;//鼠標(biāo)絕對(duì)位置 private readonlyint MOUSEEVENTF_RIGHTDOWN = 0x0008; //模擬鼠標(biāo)右鍵按下 private readonlyint MOUSEEVENTF_RIGHTUP = 0x0010; //模擬鼠標(biāo)右鍵抬起 private readonlyint MOUSEEVENTF_MIDDLEDOWN = 0x0020; //模擬鼠標(biāo)中鍵按下 private readonlyint MOUSEEVENTF_MIDDLEUP = 0x0040;// 模擬鼠標(biāo)中鍵抬起 [DllImport("user32")] public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo); private void button2_Click(object sender, EventArgs e) { int x = int.Parse(textBox1.Text); int y = int.Parse(textBox2.Text); //絕對(duì)位置 mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, x * 65535 / 1600, y * 65535 / 900, 0, 0);//移動(dòng)到需要點(diǎn)擊的位置 mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE, x * 65535 / 1600, y * 65535 / 900, 0, 0);//點(diǎn)擊 mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE, x * 65535 / 1600, y * 65535 / 900, 0, 0);//抬起 //相對(duì)位置 指的是相對(duì)于當(dāng)前鼠標(biāo)的相對(duì)位置 mouse_event(MOUSEEVENTF_MOVE , x , y, 0, 0);//移動(dòng) mouse_event(MOUSEEVENTF_LEFTDOWN , x , y, 0, 0);//點(diǎn)擊 mouse_event(MOUSEEVENTF_LEFTUP , x , y , 0, 0);//抬起 }
在textBox1,textBox2中輸入要點(diǎn)擊的位置,即可點(diǎn)擊。 點(diǎn)擊的范圍是當(dāng)前的整個(gè)屏幕
VC模擬鼠標(biāo)的兩種方式(SendMessage、mouse_event)
鼠標(biāo)模擬的常用方案,包括發(fā)送鼠標(biāo)事件消息和使用mouse_event系統(tǒng)函數(shù),發(fā)送鼠標(biāo)消息的例子如下:
pWnd->SendMessage(WM_RBUTTONDOWN,0,(y<<16)|x);
這種方法不需要窗體在前端,甚至最小化也可以使用,但是此方法并不是在所有場(chǎng)合有效,特別是對(duì)于不響應(yīng)鼠標(biāo)消息的程序更是如此。在這種情況下,可以嘗試使用mouse_event函數(shù)。
首先給出mouse_event函數(shù)的原型:
VOID mouse_event( DWORD <em>dwFlags</em>, DWORD <em>dx</em>, DWORD <em>dy</em>, DWORD <em>dwData</em>, ULONG_PTR <em>dwExtraInfo</em> );
mouse_event有五個(gè)參數(shù),第 一個(gè)為選項(xiàng)標(biāo)志,為MOUSEEVENTF_LEFTDOWN時(shí)表示左鍵按下為MOUSEEVENTF_LEFTUP表示左鍵松開(kāi),向系統(tǒng)發(fā)送相應(yīng)消息;第二、三個(gè)參數(shù)分別表示模擬鼠標(biāo)對(duì)應(yīng)x,y的位置,需要注意測(cè)是該參數(shù)對(duì)應(yīng)的是屏幕坐標(biāo);第四、五個(gè)參數(shù)并不重要,一般也可設(shè)為0,0。若要得到Keybd_event和mouse_event函數(shù)的更詳細(xì)的用法,可以查閱msdn。
mouse_even只能夠發(fā)送前臺(tái)消息,即僅對(duì)當(dāng)前激活的窗體有效。t最好配合SetCursorPos(x,y)函數(shù)一起使用,首先調(diào)用SetCursorPos函數(shù)設(shè)置鼠標(biāo)位置到需要模擬鼠標(biāo)操作的位置,然后調(diào)用mouse_event模擬鼠標(biāo)操作,下面是關(guān)于mouse_event的示例代碼:
POINT lpPoint; GetCursorPos(&lpPoint); SetCursorPos(lpPoint.x, lpPoint.y); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
示例代碼表示鼠標(biāo)的雙擊,若要表示單擊,用兩個(gè)mouse_event即可(一次放下,一次松開(kāi))。
上面說(shuō)明了模擬鼠標(biāo)操作的兩種常用方法,下面再給出一個(gè)綜合實(shí)例進(jìn)行闡述說(shuō)明:
//在發(fā)送按鍵消息前需要設(shè)置下鼠標(biāo)位置,掃雷程序似乎是根據(jù)鼠標(biāo)位置 //確定點(diǎn)擊的方塊的,而不是鼠標(biāo)消息的參數(shù) //所以PostMessage在這里也不可以使用 ::SetCursorPos(x,y); //判斷是否是雷,不是雷才執(zhí)行鼠標(biāo)點(diǎn)擊動(dòng)作 if(MineInf[acol*row+arow]==1){ /*::mouse_event(MOUSEEVENTF_RIGHTDOWN,x,y,0,0); ::mouse_event(MOUSEEVENTF_RIGHTUP,x,y,0,0); */ pWnd->SendMessage(WM_RBUTTONDOWN,0,(y<<16)|x); pWnd->SendMessage(WM_RBUTTONUP,0,(y<<16)|x); }else{ /*::mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0); ::mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);*/ pWnd->SendMessage(WM_LBUTTONDOWN,0,(y<<16)|x); pWnd->SendMessage(WM_LBUTTONUP,0,(y<<16)|x); }
好了,這就是目前使用最多的VC程序進(jìn)行鼠標(biāo)事件模擬的兩種方案,讀者可以根據(jù)實(shí)際情況選擇使用。
使用mouse_event模擬鼠標(biāo)事件時(shí),程序窗口失去焦點(diǎn)就失效
最近在使用mouse_event模擬鼠標(biāo)事件時(shí),頭疼的是,運(yùn)行程序測(cè)試時(shí),鼠標(biāo)單擊、雙擊、移動(dòng)都OK,一旦執(zhí)行可執(zhí)行文件,窗口失去焦點(diǎn)時(shí)候,就失效。
剛根據(jù)網(wǎng)上所說(shuō)的方法,把360關(guān)掉就好了,試了下,確實(shí)有這現(xiàn)象。解決了好幾天的困擾,原來(lái)是這個(gè)原因。
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇