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


Автор: Гость_Aaz 30.12.2005, 12:42
Мне нужно эмуляция нажатия кнопки мышы в определенном окне.
Мой код:
HWND wnd1 = FindWindow(NULL,"XXX");

//PostMessage(wnd1, WM_KEYDOWN, VK_F1, 0);
//Проверял правильно ли найдено окно. Все ок Кнопка Ф1 срабатывала

// Пробовал так ничего возвращает true- в очередь ставит
// PostMessage(wnd1, WM_LBUTTONDOWN, 0, MAKELPARAM(300,300));
// PostMessage(wnd1, WM_LBUTTONUP, 0, MAKELPARAM(300,300));

// Так Ничего тоже самое
// PostMessage(wnd1, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(300,300));
// PostMessage(wnd1, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(300,300));

//Попробовал напрямую без очереди Выдает false
bool y = SendMessage(wnd1, WM_LBUTTONDOWN, 0, 300*65536+300);
bool yy = SendMessage(wnd1, WM_LBUTTONUP, 0, MAKELPARAM(300,300));

Помогите плиззз..я уже незнаю что придумать или что я упустил.
Может кто подскажет др реализацию эмуляции мыши не через PostMessage
заранее спасибо

Автор: _hunter 30.12.2005, 12:58
а ты уверен что мышой нажать нужно в окне а не на какой-нить кнопке?

Автор: Гость_Aaz 30.12.2005, 13:17
В часности мне надо нажимать кнопки в флешь обекте, на веб странице.
Вполне возможно что придеться не только кнопки но и просто нажатие в отдельную точку.
Поэтому и пытаюсь сразу с мышкой разобраться...А не конкретизироваться на отдельных кнопках.
Но если нечего не получиться то придеться и кнопкоми заняться...Тока как определить индификатор Флешь кнопки в Флешь обекте???

Автор: Romikgy 30.12.2005, 13:36
Цитата
300,300

Мож не попадаешь по кнопке???

Автор: Гость_Aaz 30.12.2005, 13:49
Вставлял строчку

SetCursorPos(300,300);

И разворачивал окно на весь экран что бы небыло делем с относительными координатами экрана и окна.

Так же на простом приложении AkelPad пробовал эмуляции нажатия правой кнопки. Должно было вылезни меню, по всей поверхности приложения. Ничего те же результаты. при SendMessage выдает false

Автор: _hunter 30.12.2005, 13:50
нарисуй тестовое приложение ( с одной кнопкой и попробуй ему таким образом послать сообщения )
+ координаты тым не абсолютные а оконные

Автор: _hunter 30.12.2005, 14:02
тут дело, скорее всего, в адресате
потому как в тестовом приложении такой:
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    PostMessage(Button2->Handle, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(10,10));
    PostMessage(Button2->Handle, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(10,10));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    MessageBox(Handle, "test", "test", MB_OK);
}
//---------------------------------------------------------------------------

код работает, а такой
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    PostMessage(Handle, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(Button2->Top + 5, Button2->Left + 5));
    PostMessage(Handle, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(Button2->Top + 5, Button2->Left + 5));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    MessageBox(Handle, "test", "test", MB_OK);
}
//---------------------------------------------------------------------------

уже нет...
Добавлено @ 14:08
+ вот что spy++
показывает:
Код

<00302> 002B0362 R WM_SETCURSOR fHaltProcessing:False
<00303> 002B0362 S WM_PARENTNOTIFY fwEvent:WM_LBUTTONDOWN xPos:64 yPos:23
<00304> 002B0362 R WM_PARENTNOTIFY
<00305> 002B0362 S WM_MOUSEACTIVATE hwndTopLevel:002B0362 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
<00306> 002B0362 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<00307> 002B0362 S WM_SETCURSOR hwnd:003B0374 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN
<00308> 002B0362 R WM_SETCURSOR fHaltProcessing:False
<00309> 002B0362 S WM_CTLCOLORBTN hdcButton:2A01136A hwndButton:003B0374
<00310> 002B0362 R WM_CTLCOLORBTN hBrush:3010153C
<00311> 002B0362 S WM_CTLCOLORBTN hdcButton:2A01136A hwndButton:003B0374
<00312> 002B0362 R WM_CTLCOLORBTN hBrush:3010153C
<00313> 002B0362 S WM_COMMAND wNotifyCode:0000 wID:884 hwndCtl:003B0374
<00314> 002B0362 R WM_COMMAND
<00315> 002B0362 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:44 yPos:13
<00316> 002B0362 P WM_LBUTTONUP fwKeys:MK_LBUTTON xPos:44 yPos:13

последние два -- уже реакция кнопки.
попробуй такой же набор послать

Автор: Гость_Aaz 30.12.2005, 14:15
Создал форму. С одной большой кнопкой и текст полем для отоброжения результата.

Координаты относительно окна.
Навсякий случай подвинул форму в левый верзний угол.

код
Код

HWND wnd1 = FindWindow(NULL,"Form1");
               
PostMessage(wnd1, WM_LBUTTONDOWN, 0,MAKELPARAM(100,100)); 
PostMessage(wnd1, WM_LBUTTONUP, 0,MAKELPARAM(100,100));
PostMessage(wnd1, WM_LBUTTONDOWN, 0, MAKELPARAM(100,100)); 
PostMessage(wnd1, WM_LBUTTONUP, 0, MAKELPARAM(100,100));


непомогает...ничего.... Уже Пробовал перестовлять PostMessage(wnd1, WM_LBUTTONDOWN, MAKELPARAM(100,100),0); параметры....Уже крыша едет smile.
Может ещо у кого есть соображения.

Автор: Aleksandor 30.12.2005, 14:21
А пробовал SetFocus(wnd1) перед тем как слать ему сообщения? Попробуй вставить Beep(3000,200); чтобы узнать получает ли окно твои сообщения.

Автор: _hunter 30.12.2005, 14:49
я ж говорю. сообщения идут адресату, а он ( адресат ) не пытается определить есть ли у него дети по заданным координатам.

Автор: Гость_Aaz 30.12.2005, 15:17
to hunter :
Я ещо только учусь поправь где я непонял пожалуйста.
--Spy++ Перехватывает сообщения окну.
R ответ окна
S SendMessage
P PostMessage

И поручаеться нужно послать окну (по твоему коду):

Код

SendMessage(wnd1, WM_LBUTTONDOWN, 0, MAKELPARAM(64,23));
SendMessage(wnd1, WM_MOUSEACTIVATE, 0, MAKELPARAM(HTCLIENT,WM_LBUTTONDOWN));
SendMessage(wnd1, WM_SETCURSOR, 0, MAKELPARAM(HTCLIENT,WM_LBUTTONDOWN));
SendMessage(wnd1, WM_COMMAND, 884, 0x003B0374);
PostMessage(wnd1, WM_LBUTTONDOWN, MK_LBUTTON,MAKELPARAM(44,13));
PostMessage(wnd1, WM_LBUTTONUP, MK_LBUTTON,MAKELPARAM(44,13));



Или я тебя неправильно понял????
Потому что при этом коде тоже ничего непроисходит.

Автор: Aleksandor 30.12.2005, 15:18
А если так
Код

POINT pt;
pt.x=5; pt.y=5; 

hwnd = ChildWindowFromPoint(hwndParent, &pt);
SendMessage (hwnd, WM_LBUTTONDOWN, 0, (LPARAM)0xF000F); 
SendMessage (hwnd, WM_LBUTTONUP, 0, (LPARAM)0xF000F);  


Автор: _hunter 30.12.2005, 15:40
Гость_Aaz, по-идее -- так. ( хотя с флешем может и не сработать -- лучше spy' ем посмотри такие же ему сообщения идут или нет )

Aleksandor, посылать нужно не нормальному окну, а во флеш

Автор: Гость_Aaz 30.12.2005, 15:43
to Alexsandor:
О гуру smile
РАБОТАЕТ smile))))))))
Оканчательный вариант
Код

HWND wnd1 = FindWindow(NULL,"Form1");
    POINT pt;
    pt.x=50; 
    pt.y=50; 

HWND    hwnd2 = ChildWindowFromPoint(wnd1, pt);

SendMessage (hwnd2, WM_LBUTTONDOWN, 0, MAKELPARAM(50,50)); 
SendMessage (hwnd2, WM_LBUTTONUP, 0, MAKELPARAM(50,50));  

Мдя......Я бы долго соображал....

Автор: Гость_Aaz 30.12.2005, 15:44
огромное спасибо всем кто неполенился подумать над моей проблемой.

Автор: Earnest 30.12.2005, 17:02
Для эмуляции мыши лучше использовать функции mouse_event или SendInput.
Цитата

The mouse_event function synthesizes mouse motion and button clicks.
The SendInput function synthesizes keystrokes, mouse motions, and button clicks.

Преимущества: нет привязки к окну. Событие обрабатывается системой абсолютно так же, как если бы пользователь действительно ткнул мышем. И попадает в очередь ввода правильного окна автоматически.

Автор: GremlinProg 5.1.2006, 21:51
Почти не читал комментарии, но сразу вижу правильное решение Earnest

Автор: KQT 3.2.2010, 14:02
Earnest, благодярю за наводку: mouse_event и SendInput, но всё же...


Гость_Aaz, действительно ли окончательный вариант "такой"? SendMessage отправляет сообщение обработчику окна и ждёт(!) обработки. Тот видимо не завершает работы пока клавиша мыши не будет отжата, то есть второй Send уже не играет ни какой роли: программа повисает на первом в ожидании WM_LBUTTUNUP. Все получается если например использовать SendMessageCallback...

Автор: Earnest 3.2.2010, 14:51
Не поняла твое замечание, да и тема древняя...
Цитата(KQT @  3.2.2010,  15:02 Найти цитируемый пост)
SendMessage отправляет сообщение обработчику окна и ждёт(!) обработки. Тот видимо не завершает работы пока клавиша мыши не будет отжата,

SendMessage не помещает событие в очередь, а напрямую (синхронно) вызывает оконную функцию, отсюда и блокировка. 

Автор: KQT 3.2.2010, 16:45
... Не помещает - хотим напрямую обратиться к обработчику окна. Но
Цитата

The SendMessage function calls the window procedure for the specified window and does not return UNTIL the window procedure has processed the message

В переписав код приведенный выше моя программа стоорилась на первом sendmessage в ожидании отжатия клавиши мыши, иначе говоря управление было передано процедуре окна первым sendmessage, а она по какой то причине не желает завершатсья пока кнопка не будет отжата... В итоге второй sendmessage выполняется "впустую", когда в этом необходимости уже нет. Решается это PostMessage или SendMessageCallback .

Тема то старая, но мне нынче актуальна) и оказалась чем-то полезна.

Автор: walkmn 30.10.2010, 16:18
Код

HWND wnd1 = FindWindow(NULL,"Form1");
    POINT pt;
    pt.x=50; 
    pt.y=50; 

HWND    hwnd2 = ChildWindowFromPoint(wnd1, pt);

SendMessage (hwnd2, WM_LBUTTONDOWN, 0, MAKELPARAM(50,50)); 
SendMessage (hwnd2, WM_LBUTTONUP, 0, MAKELPARAM(50,50));  


У меня работает только если в данных координатах кнопка, а мне нужно чтобы нажималась в определенных координатах компонента СppWebBrowser.

Ну например есть форма с компонентов СppWebBrowser в котором загружен гугл, и мне нужно клацнуть по определенной ссылке, но сетмоусепоз не предлагать, кликать по ссылке программа должна в свернутом режиме!!!

Автор: Romikgy 31.10.2010, 23:26
Цитата(walkmn @  30.10.2010,  15:18 Найти цитируемый пост)
кликать по ссылке программа должна в свернутом режиме!!! 

это не проканает ... имхо нужно парсить страницу на наличие ссылок и переходить на урл....

Автор: walkmn 31.10.2010, 23:46
Romikgy, да нет, просто я это как в пример привел, на самом деле нужно нажать на кнопку, которая написана на Flash.
Тоесть это флеш игрушка, нужно написать для нее чтото типа автобота.

Автор: Romikgy 11.11.2010, 22:17
walkmn, тогда попутно разобратся с флешем ... видать там есть типа мессаг при нажатии на кнопки ... вот их можно слать (я так думаю) иначе только активировать окно и по координатам кнопать ...

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