Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Эмулирование мыши


Автор: grust 27.12.2006, 23:46
Нужно написать прогу которая, будет нажимать сама в разных местах экрана, как это сделать?

Автор: codelord 28.12.2006, 02:05
тебе помогут 
Цитата

 Функция SetCursorPos

     Описание:
 function SetCursorPos(X, Y: Integer);

     Пеpемещает куpсоp в указанные кооpдинаты экpана. Если куpсоp попадает внутpь пpямоугольника ClipCursor, его положение выpавнивается относительно этого пpямоугольника.

     Паpаметpы:
     X, Y: Новое положение куpсоpа (в кооpдинатах экpана).

 функция находится в файле user32.dll

И
mouse_event

Автор: witex 28.12.2006, 02:12
Разделом ошибся! Это в winapi. ваабще всё в мсдн есть!
Код

BOOL SetCursorPos(          int X,
    int Y
);

установка координат.
установку дал.. остальное ищи=)

З.Ы. Codelord, чё то ты мня опередил=))

Автор: grust 28.12.2006, 20:30
А как сэмулировать нажатие на левую кнопку мыши?

Автор: WERITAS 28.12.2006, 23:20
Цитата
А как сэмулировать нажатие на левую кнопку мыши? 

В оконной процедуре обработать case WM_LBUTTONDOWN:, если ты конечно на API делаешь.

Автор: zkv 28.12.2006, 23:37
Цитата(WERITAS @  28.12.2006,  23:20 Найти цитируемый пост)
В оконной процедуре обработать case WM_LBUTTONDOWN:, если ты конечно на API делаешь.


WERITAS, таким образом ты обработаешь реакцию программы на нажатие левой клавиши мыши.


grust,  не ленимся пользоваться поиском, ради интереса скопировал в гугл http://www.google.com/search?hl=ru&newwindow=1&sa=X&oi=spell&resnum=0&ct=result&cd=1&q=%D0%BA%D0%B0%D0%BA+%D1%8D%D0%BC%D1%83%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C+%D0%BD%D0%B0%D0%B6%D0%B0%D1%82%D0%B8%D0%B5+%D0%BD%D0%B0+%D0%BB%D0%B5%D0%B2%D1%83%D1%8E+%D0%BA%D0%BD%D0%BE%D0%BF%D0%BA%D1%83+%D0%BC%D1%8B%D1%88%D0%B8&spell=1

Автор: grust 29.12.2006, 00:28
Мне нужно что он нажимал на кнопки в чужой программе

Автор: zkv 29.12.2006, 01:01
Цитата(grust @  29.12.2006,  00:28 Найти цитируемый пост)
Мне нужно что он нажимал на кнопки в чужой программе 

догадался, повторяю:
Цитата(zkv @  28.12.2006,  23:37 Найти цитируемый пост)
grust,  не ленимся пользоваться поиском, ради интереса скопировал в гугл "как сэмулировать нажатие на левую кнопку мыши"  



Автор: grust 29.12.2006, 02:14
Я просмотрел 10 страниц в  поисковике, но так и не нашёл ни чего интересного, кроме SendMessage(Хэндл окна,WM_LBUTTONDOWN, MK_LBUTTON,MAKELONG(15,10)) но я не знаю какой хэндл у приложения на котрое мне нужно нажимать, как отловить этот хэдл?

Автор: zkv 29.12.2006, 03:52
в первой ссылке пример для Дельфи, в третьей для Buildera...
вот в MFC:
Код

void CTestDlg::OnBnClickedOk()
{
    CPaintDC dc(this);
    int iWidth = dc.GetDeviceCaps( HORZRES );
    int iHeight = dc.GetDeviceCaps( VERTRES );

    POINT cur_pos;
    GetCursorPos(&cur_pos);
    cur_pos.x *= (65535 / iWidth );
    cur_pos.y *= (65535 / iHeight );
    mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); // нажали левую кнопку мыши
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0); // отпустили левую кнопку мыши ( НЕ ЗАБЫВАТЬ )
}

Автор: W4FhLF 29.12.2006, 08:45
Между нажатием и отпусканием сделай паузу Sleep(50);
Часто сталкивался с ситациями, когда без этой задержки нажатие не осуществлялось, точнее оно может и было, но на него не успела отреагировать программа(вытесняющая многопоточность, не забываем).

Автор: grust 29.12.2006, 12:11
mouse_event работает только на том окне, которое его запустило, а мне нужно, что бы он нажимал на чужое окно...

Автор: HellanD 29.12.2006, 12:50

Цитата

но я не знаю какой хэндл у приложения на котрое мне нужно нажимать, как отловить этот хэдл? 



Дак ведь это делает функа FindWindow или FindWindowEx

Вот читай

Цитата

FindWindow Function

The FindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. This function does not perform a case-sensitive search.

To search child windows, beginning with a specified child window, use the FindWindowEx function.

Syntax


HWND FindWindow(          LPCTSTR lpClassName,
    LPCTSTR lpWindowName
);
Parameters

lpClassName
[in] Pointer to a null-terminated string that specifies the class name or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. 
If lpClassName points to a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. 

If lpClassName is NULL, it finds any window whose title matches the lpWindowName parameter. 

lpWindowName
[in] Pointer to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match. 
Return Value

If the function succeeds, the return value is a handle to the window that has the specified class name and window name.

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



Автор: zkv 29.12.2006, 13:39
Цитата(grust @  29.12.2006,  12:11 Найти цитируемый пост)
mouse_event работает только на том окне

неправда, следующий код кликнет куда угодно на экране:
Код

    CPaintDC dc(this);
    int iWidth = dc.GetDeviceCaps( HORZRES );
    int iHeight = dc.GetDeviceCaps( VERTRES );
    
    CString str;
    int iX = 0, iY = 0;
    m_EdX.GetWindowText( str ); //m_EdX и m_EdY - Edit'ы в которые вводятся координаты 
    sscanf( str, "%d", &iX);
    m_EdY.GetWindowText( str );
    sscanf( str, "%d", &iY);
    
    POINT cur_pos;
    GetCursorPos(&cur_pos);
    cur_pos.x *= (65535 / iWidth );
    cur_pos.y *= (65535 / iHeight );
    
    iX *= (65535 / iWidth );
    iY *= (65535 / iHeight );
    mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,iX,iY,0,0);
    Sleep( 50 );
    mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE,0,0,0,0); // нажали левую кнопку мыши
    Sleep( 50 );
    mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE,0,0,0,0); // отпустили левую кнопку мыши ( НЕ ЗАБЫВАТЬ )
    Sleep( 50 );
    mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,cur_pos.x,cur_pos.y,0,0);
 

Автор: grust 29.12.2006, 15:52
Да, код работает, на других приложениях, кроме того кторое мне надо..( Приложение на которое мне нужно нажимать - игрушка, со всеми вытекающими последствиями, постоянный рэндеринг и т.д. так вот на него он не кликает(

Автор: W4FhLF 29.12.2006, 18:50
grust, писал такое для игры(CS) и как раз с помощью mouse_event, правда флаги были другими, попробуй вот  так:

Код

mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, cbuttons, dwExtraInfo);
Sleep(50);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, cbuttons, dwExtraInfo);


Всё чётко работало и работает.

Автор: grust 29.12.2006, 19:38
не компилируеться
.\hook.cpp(41) : error C2065: 'cbuttons' : undeclared identifier
.\hook.cpp(41) : error C2065: 'dwExtraInfo' : undeclared identifier

Автор: W4FhLF 29.12.2006, 20:57
Цитата

не компилируеться
.\hook.cpp(41) : error C2065: 'cbuttons' : undeclared identifier
.\hook.cpp(41) : error C2065: 'dwExtraInfo' : undeclared identifier



Даже не знаю почему, наверное так сложились звёзды...

Автор: codelord 29.12.2006, 21:28
если  windows 2000/xp то dwData параметр  там где cbutton вообще не нужен:
Цитата

Windows 2000/XP: 
Если dwFlags - не MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, или MOUSEEVENTF_XUP, то dwData должен быть нулевым


а второй пармерт dwExtraInfo можно найти:
Код

 LPARAM  dwExtraInfo;
 dwExtraInfo = GetMessageExtraInfo();


Добавлено @ 21:34 
Цитата(W4FhLF @  29.12.2006,  14:50 Найти цитируемый пост)
Всё чётко работало и работает.

а что делает если не секрет smile

Автор: Rockie 29.12.2006, 22:00
Цитата(W4FhLF @  29.12.2006,  20:57 Найти цитируемый пост)
Даже не знаю почему, наверное так сложились звёзды...

smile

Цитата(W4FhLF @  29.12.2006,  18:50 Найти цитируемый пост)
 писал такое для игры(CS)


W4FhLF, хы, а что скрипт делал? smile средствами самого cstrike не получалось обойтись?


Автор: zkv 29.12.2006, 23:22
Цитата(grust @  29.12.2006,  19:38 Найти цитируемый пост)
не компилируеться
.\hook.cpp(41) : error C2065: 'cbuttons' : undeclared identifier
.\hook.cpp(41) : error C2065: 'dwExtraInfo' : undeclared identifier 

можно посоветовать только книжку почитать какую-нибудь по С/С++
Цитата(W4FhLF @  29.12.2006,  20:57 Найти цитируемый пост)
Даже не знаю почему, наверное так сложились звёзды... 

smilesmilesmile

Автор: W4FhLF 30.12.2006, 09:43
Цитата

а что делает если не секрет


Цитата

W4FhLF, хы, а что скрипт делал?  средствами самого cstrike не получалось обойтись?


А может кстати и не для CS, я точно не знаю, мне просто заказали. Делала она следующее:
Если держать 1.5 секунды левую кнопку мыши, то после этого периода  кнопка начинает программно нажиматься каждый 100 миллисекунд. Ну насколько я понял, человеку это нужно было для того, чтобы из пистолета стрелять как из автоматаsmile

Автор: Rockie 30.12.2006, 14:15
W4FhLF, понятно. Это просто делается и средствами CS, можно к примеру повесить выстрел и на нажатие кнопки мыши и на отжатие. А задержки кстати зависят напрямую от качества линии, то есть нужно их подстраивать. Наверное все-таки не для CS..



Автор: Alx 18.8.2010, 12:20
Столкнулся с похожей задачей:
сразу несколько вопросов:

1) а игры могут распознать, что клик такими средствами был сэмулирован? что, если они как-то работают напрямую? (с DirectX?)

2) возможно, тогда встает необходимость написать драйвер, эмулирующий мышь? наверное, это должно быть на основе DDK/WDK?

3) может лежит уже что-то в форме API у кого нибудь? ищу 2 дня, пока не нашел..  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)