IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Правильный WM_LButtonClick
Unconnected
сообщение 19.06.2011 15:13
Сообщение #1


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Как правильно отправить кнопке клик мыши? Делал традиционно так:
Procedure clickng(w:THandle);
begin
SendMessage(w, WM_LButtonDown, 1, 1);
SendMessage(w, WM_LButtonUP, 1, 1);
end;


за 1-3 параметры уверен, а вот 4й - в msdn написано, что там должна быть структура с координатами курсора, а везде в сети там тупо 0 или 1, но я подозреваю, что это очередной ГК.. хотя раньше всегда так же делал, ну вот сейчас опять работает как-то непонятно и через раз.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 19.06.2011 15:22
Сообщение #2


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Опять "магические числа"?

SendMessage(w, WM_LBUTTONDOWN, MK_LBUTTON, MakeLong(xPos, yPos));
не проще читается?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 19.06.2011 15:25
Сообщение #3


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Проще, ну это для краткости) А xPos-yPos это искать координаты кнопки ведь?


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 19.06.2011 15:31
Сообщение #4


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


xPos и yPos - это координаты мыши (относительно клиентской части окна W), которые будут переданы в обработчик WM_LBUTTONDOWN.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 19.06.2011 15:32
Сообщение #5


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Проще, ну это для краткости) А xPos-yPos это искать координаты кнопки ведь?

added: и ещё.. в msdn про последний параметр что-то было про "выше-левее угла клиентской области", что ли, не совсем понял. Это, случаем, значило не то, что клик не будет работать, если кнопка вне экрана (окно так расположено, например) ?


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 19.06.2011 15:34
Сообщение #6


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
в msdn про последний параметр что-то было про "выше-левее угла клиентской области", что ли, не совсем понял.
Это?
Цитата(MSDN)
The coordinate is relative to the upper-left corner of the client area.
"Координата относительно верхнего левого угла клиентской области".
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 19.06.2011 16:00
Сообщение #7


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Procedure clickng(w:THandle);
var r,r2:TRect;
p:TPoint;
begin
getwindowrect(w,r);
p:=r.TopLeft;
SendMessage(w, WM_LBUTTONDOWN, MK_LBUTTON, MakeLong(p.x, p.y));
SendMessage(w, WM_LBUTTONUP, MK_LBUTTON, MakeLong(p.x,p.y));
end;


Сделал так.. что-то он вообще кликать перестал, только тень на кнопке появляется.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 19.06.2011 16:17
Сообщение #8


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Следи за руками:

  p:=r.TopLeft;
ScreenToClient(w, p); // Я ж 2 раза написал - что относительно клиентской области КНОПКИ
SendMessage(w, WM_LBUTTONDOWN, MK_LBUTTON, MakeLong(p.x, p.y));
Теперь нажимается? smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 19.06.2011 16:33
Сообщение #9


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


O_o нажалось... я сначала примерно так же пробовал, только ScreenToClient-ом возвращал значение в другую переменную, а там видать входной параметр сам и изменяется.. спасибо)


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 0:10
Сообщение #10


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


deleted

Сообщение отредактировано: Unconnected - 20.06.2011 1:50


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 20.06.2011 9:31
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


А тебе для чего посылать щелчок?
Я когда таким образон радиогруппу переключал (потому что это наименее накладный способ, не запоминать ИД первого и последнего элементов), Вольво меня разругал.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 11:53
Сообщение #12


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Ну, надо кнопку нажать.. или ещё как-то можно её нажать, не щелчком? Он как-то нестабильно работает. У меня на машине всегда, а на других иногда вообще не кликает, хотя тоже XP.. посмотрите, может не так делаю чего..


const kname='PrivatCom';
var kh,but1h:THandle;
Procedure clickng(w:THandle);
var r:TRect;
p:TPoint;
begin
getwindowrect(w,r);
p:=r.TopLeft;
ScreenToClient(w, p);
sendMessage(w, WM_LBUTTONDOWN, MK_LBUTTON, MakeLong(p.x, p.y));
sendMessage(w, WM_LBUTTONUP, MK_LBUTTON, MakeLong(p.x, p.y));
end;

function GetText(wnd:THandle):string;stdcall;
var p:array [0..pred(MAX_PATH)] of char;
begin
GetWindowText(wnd,p,max_path);
result:=strpas(p);
end;

var res:THandle;
fn:string;

function ChildTree(Han:THandle; Info: lparam):BOOL;stdcall;
var sp:string;
begin
sp:=ansiuppercase(gettext(han));
if pos(fn,sp)>0 then begin
res:=han;
result:=false;
end else result:=true;
end;

function findbut(h:THandle;fnk:string):THandle; //ищет дочерние окна h, в именах которых есть fnk
begin
res:=0;fn:=fnk;
enumChildWindows(h,@ChildTree, 0);
result:=res;
end;

function findnewk(k:THandle):THandle; //может быть несколько окон с одним caption-ом, ищет новое,
var d:integer; //если его нет, ждет пока оно появится 50 с.
begin
d:=0;result:=0;
repeat
result:=findbut(0,kname);
sleep(1);inc(d);
until ((result<>k) and (result<>0)) or (d=50000);
end;

Procedure kdown;
var k:THandle;
begin
kh:=findnewk(0);
sleep(3000); //надо ли?
if kh<>0 then but1h:=findbut(kh,'ПОДКЛЮЧЕНИЕ') else exit;
clickng(but1h);
end;


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 20.06.2011 12:07
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Чтобы нажать кнопку, надо просто вызвать ту же процедуру, которая сидит в ветке WM_COMMAND->ID_BTN_1 в оконной процедуре.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 12:15
Сообщение #14


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Что-то новое.. и как её вызвать, тоже sendmessage какой-то?


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 20.06.2011 12:29
Сообщение #15


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
посмотрите, может не так делаю чего..
Угу... Все не так... Не надо делать этот ужасный цикл длительностью до 50 секунд. Проверил один раз - нет на экране подходящего окна - все, устанавливай хук. Глобальный. На HCBT_CREATEWND. Там проверяй заголовок создаваемого окна, и если он - тот, что нужен, то работай дальше (дождись появления окна на экране и пошли ему Enter, если кнопка, которую ты пытаешься нажать - дефолтная, а в большинстве случаев это так - то она и нажмется. Если не дефолтная - то надо будет искать).

На данный момент у меня твой код не работает. По одной простой причине:
  if pos(fn,sp)>0 then begin // Ищем заголовок
, если учесть, что в fn находится заголовок, НЕ приведенный к верхнему регистру, то программа даже теоретически не может отработать. Никогда (поскольку 'PrivatCom' и 'PRIVATCOM' - это очень уж разные вещи для компьютера). Либо ты показываешь не тот код, который работает, либо выдаешь желаемое за действительное...


Сообщение отредактировано: IUnknown - 20.06.2011 12:35
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 12:36
Сообщение #16


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Ооо нет, опять эти dll, мэппинг, затыки на пустом месте.. а почему бы не проверять хотя бы в таймере наличие нужного окна? Кнопки все дефолтные (TButton и TBitButton).

added:
Цитата
Либо ты показываешь не тот код

Да да, в оригинале большими буквами, эту константу уже тут допечатывал.. так то хэндлы всегда находятся, но нажимается далеко не всегда.

Сообщение отредактировано: Unconnected - 20.06.2011 12:38


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 20.06.2011 12:43
Сообщение #17


a.k.a. volvo877
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской

Репутация: -  627  +


Цитата
а почему бы не проверять хотя бы в таймере наличие нужного окна?
Да мне-то все равно, хоть вручную проверяй (показывай каждую секунду сообщение пользователю, "если на экране появилось окошко с заголовком bla_bla_bla, то подведите мышу к кнопке ПОДКЛЮЧЕНИЕ и нажмите левую кнопку мыши. Если нет - нажмите Cancel"). Только вот пользоваться такой программой никому на фиг не надо. Равно как и той, что работает по таймеру.

Выбирай, присоединяться к 90% "писателей кода", либо учиться, наконец, делать нормально... Как выберешь - скажешь...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 12:58
Сообщение #18


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Хочу нормально, а с дллками связываться не хочу... Ладно, допустим есть у меня хэндл кнопки\окна, чтобы отправить ей WM_COMMAND, надо ID кнопки где-то взять же?


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
TarasBer
сообщение 20.06.2011 13:22
Сообщение #19


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Что-то новое.. и как её вызвать, тоже sendmessage какой-то?

Нет, тупо берёшь и вызываешь.

Ты ведь нажимаешь кнопку своего приложения, так? У тебя на эту кнопку уже повешена какая-то процедура, так? Ну вот её тупо и вызывай.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 20.06.2011 13:27
Сообщение #20


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Если бы своего, то понятное дело не кликал бы так) В общем, посмотрел, что окну при нажатии шлётся: извещение BN_CLICKED, в wParam лежит ID кнопки, а в lParam - её хэндл, или окна.. вот как бы ID получить.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 28.03.2024 14:20
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"