![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нажатие кнопки в другой программе [D7, Win2k, WinXP]
pavel_guzhanov © (2004-06-29 11:44:00)Имеется запущенная программа (не моя). Мне известен заголовок формы, и имя кнопки на этой форме. Мне надо из моей программы нажать эту кнопку. Кнопка на тулбаре, известен ее хинт.
Можно ли это сделать, и как?
pavel_guzhanov (2004-07-07 11:23:00) [1]да, именно так. Но, что еще прикольнее, теперь этот глюк пропал, и все заработало так, как надо. Спасибо за помощь всем, кто пытался помочь!
jack128 (2004-07-07 10:42:00) [2]координаты задаются относительно левого верхнего угла окна(в данном случае тулбара). ты так делаешь?
pavel_guzhanov (2004-07-07 10:12:00) [3]получилось прикольно. Прикол в том, ято координаты нужной мне кнопки - 88, 11. Когда подставляю их - ничего не работает. Подставляю исходные координаты (15, 15) - срабатывает именно нужная мне кнопка. Прикольно, но может ли кто-нибудь объяснить, почему это происходит?
pavel_guzhanov (2004-07-06 17:42:00) [4]спасибо, попробую завтра, а то рабочий день кончается
jack128 (2004-07-06 17:18:00) [5]вот тебе пример. Это код нажимает первую кнопку на тулбаре в DMClient'e
function EnumWindowCallback(hWnd: THandle; Param: Integer): BOOL; stdcall;
const
_Caption = 'Форум "Мастера Дельфи"';
var
Buffer: string;
hToolBar: THandle;
Pos: TSmallPoint;
begin
Result := True;
SetLength(Buffer, 256);
SetLength(Buffer, GetClassName(hWnd, PChar(Buffer), Length(Buffer)));
// Смотрим - тот ли класс окна
if Buffer <> 'TMainForm' then
Exit;
SetLength(Buffer, GetWindowTextLength(hWnd));
GetWindowText(hWnd, PChar(Buffer), Length(Buffer));
// Смотрим тот ли заголовок окна (в программе заголовок меняется, но начало заголовка неизменно)
if copy(Buffer, 1, Length(_Caption)) <> _Caption then
Exit;
// Нужное окно нашли - прекращаем цикл по окнам
Result := False;
// Ищем ToolBar
hToolBar := FindWindowEx(hWnd, 0, 'TToolBar', nil);
if hToolBar = 0 then
Exit;
// Примерные координаты центра перевой кнопки на тулбаре
Pos := SmallPoint(15, 15);
// Нажали кнопку мыши
SendMessage(hToolBar, WM_LBUTTONDOWN, 0, Integer(Pos));
// Отпустили кнопку мыши
SendMessage(hToolBar, WM_LBUTTONUP, 0, Integer(Pos));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Запускаем цикл по всем окнам верхнего уровня
EnumWindows(@EnumWindowCallback, 0);
end;
GrayFace (2004-07-06 15:50:00) [6]>я бы послал сообщение WM_LBUTTONxxx, только это сообщение требует координат курсора мыши. А окно не моей программы может быть в любом месте, так что координата кнопки - это неизвестная величина
По-моему, в нем координаты ставятся относительно клиентской части. Координаты кнопки на тулбаре могут меняться только от версии к версии. Чтобы вычислить их, наведи мышь на кнопку иScreenToClient(h,mouse.CursorPos)будет тем, что нужно. (h - handle Toolbar'а)
GuAV (2004-07-06 11:38:00) [7]не через WM_LBUTTONxxx - не вижу способа. Потому что так работает VCL. TToolButton.Click - реализовано тем же макаром, что и TSpeedButton.Click.
Координаты можно получить TB_GETITEMRECT. В этой мессаге результат передается через указатель на структуру, что вызовет дополнительные трудности.
> А окно не моей программы может быть в любом месте
Существуют функции преобразования координат. ClientToScreen.
pavel_guzhanov (2004-07-06 09:05:00) [8]я бы послал сообщение WM_LBUTTONxxx, только это сообщение требует координат курсора мыши. А окно не моей программы может быть в любом месте, так что координата кнопки - это неизвестная величина
GuAV (2004-07-05 23:17:00) [9]
> THintWindow
Блин, я посмотрел нет ли буквы T и увидел что нет. меня глючит.
2pavel_guzhanov ©
Раз таки на Дельфи, забудь что я написал, шли WM_LBUTTONxxx, cм.
GrayFace © (03.07.04 08:04) [11]
jack128 (2004-07-05 22:08:00) [10]
> Это возможно пойдет, т.к. похоже, что прога не на Дельфи.
как раз НА дельфи
> ClassName THintWindow хотя я слабо понимаю зачем человек hint ловил ;-)
GuAV (2004-07-05 19:55:00) [11]
> Получил такую информацию:
Не ту инфу получил.
Выбери Messages->Options, оставь только WM_COMMAND и отметь HexValues.
нажать Start.
Мессага будет внизу.
Это возможно пойдет, т.к. похоже, что прога не на Дельфи.
В VCL же как только что выяснил подобные мессаги игнорируются, VCL мышу ловит, так что только GrayFace © (03.07.04 08:04) [11]
pavel_guzhanov (2004-07-05 17:57:00) [12]Получил такую информацию:
Window text Поиск сотрудника по карте…
Process ID 00000A44 Client.exe
Application instance 00010000
Window Handle 000B012C
Parent Window 00010014
Window Function 00048BA8
Menu Handle 00000000
Window Rect in screen (417,172)-(587,231)
Window rect in parent (417,172)-(587,231)
Client rectangle (0,0)-(157,17)
#Msg processrd 87
Wndow Style 84800000
Popup, ClipSiblings, BorderTopmost, ToolWindow, Left,
LTRReading, RightScrollBar
ClassName THintWindow
Excutable module 00010000 Client.exe
Class window function 00048BA8
Icon 00000000
Cursor 00010011
Bakground brush 00000000
Window extra byts 00000000
Class extra Bytes 00000000
Class Style 0000080B
VRedraw, HRedraw, DblClks, SaveBits
Какую из этих данных посылать, и кому, окну или ToolBar??
GuAV (2004-07-05 16:50:00) [13]
> А что такое WinSight?
Програма, которая отображает сообщения передаваемые окнам других программ.
ws32.exe
AFAIK, не в любом Делфи есть
при установке как по умолчанию ставится.
pavel_guzhanov (2004-07-05 16:44:00) [14]А что такое WinSight? И как им пользоваться?
GuAV (2004-07-05 16:39:00) [15]А если не winsightом, то имхо через TB_GETBUTTON определить WM_COMMAND но это гемморой со сруктурой передаваемой через указатель.
или уже WM_LBUTTONDOWN, etc.
TB_PRESSBUTTON - только нажимает, упомяутого выше дейтсвия не происходит.
GuAV (2004-07-05 16:29:00) [16]
> Да, надо выполнить действие. Но исходников той программы
> у меня нет
а и не нужно WinSightом можно словить WM_COMMAND при нажатии кнопки, его затем и слать.
pavel_guzhanov (2004-07-05 16:10:00) [17]Да, надо выполнить действие. Но исходников той программы у меня нет, поэтому я и пытаюсь ее нажать. А нумерация кнопок как идет? Ну типа слева направо, или как то еще?
GuAV (2004-07-05 16:02:00) [18]
> А вот что такое ID кнопки?
Это ID. Кнопки нумеруются 0, 1, 2...
Я вот еще что подумал, может тебе эту кнопку нажимать не нужно, а нужно выполнить действие, которое выполняется, когда пользователь нажимает кнопку?
pavel_guzhanov (2004-07-05 15:28:00) [19]Спасибо! Извини, осерчал я очень, уже неделю бьюсь! А вот что такое ID кнопки? Если ее имя, т.е 'ToolButton1', то ничего не получается, т.к этот патаметр должен быть Integer, а если хендл, то ты сам говорил, что у этих кнопок хендла нет. Так что же туда подставлять?
GuAV (2004-07-05 15:09:00) [20]Ладно уговорил, давай я почитаю.
SendMessage(TBHnd, TB_PRESSBUTTON, <сюда ID кнопки>, <cюда 1 - зажать, 0 - отпустить>);
т. е. если "нажать" понимать как зажать, а потом отпустить, то сначала
SendMessage(TBHnd, TB_PRESSBUTTON, <сюда ID кнопки>, 1);
, а потом (можно через время, чтобы увидеть, что она таки нажалась)
SendMessage(TBHnd, TB_PRESSBUTTON, <сюда ID кнопки>, 0);