Форум программистов
 
О проблемах, например, с регистрацией пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль.

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы
Старый 04.07.2007, 13:42   #1
SeRыЙ
 
Аватар для SeRыЙ
 
Регистрация: 01.07.2007
Сообщений: 4
По умолчанию Нужно программно найти окно программы и нажать на нем кнопку

Ну как найти окно я знаю. А как кнопку на нем найти и нажать? Не подскажете?
http://i-info.iplot.ru/
icq: 434327678
SeRыЙ вне форума
Старый 04.07.2007, 14:20   #2
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Код:
// Для приложений написанных на Delphi - TCheckBox, TButton, TBitBtn,
// для других языков - CheckBox, Button, BitBtn.

// Нажатие на кнопку:

procedure TForm1.Button1Click(Sender: TObject);
var
  h1, h2: hwnd;
begin
  h1 := FindWindow('tform2', nil);
  h2 := FindWindowEx(h1, 0, 'TBitBtn', '&No');
  SendMessage(h2, BM_CLICK, 0, 0);
end;

// Установка или снятие флажка:

procedure TForm1.Button2Click(Sender: TObject);
var
  h1, h2: hwnd;
begin
  h1 := FindWindow('tform2', nil);
  h2 := FindWindowEx(h1, 0, 'TCheckBox', 'Флажок');
  SendMessage(h2, BM_SetCheck, 1, 0);
end;
(c)3,14жжено с DelphiWorld
Сматры не пэрэпутай, Кутузов
пыщь
JTG вне форума
Старый 04.07.2007, 15:07   #3
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 15
По умолчанию

Насчёт предыдущего примера - он не универсален, т.к. будет работать, только если кнопка находитяся непосредственно на форме.

Кратко о навигации по окнам:
У каждого окна (формы) как правило есть дочерние окна, т.е. объекты, находящиеся на этой форме. Каждого из этих объектов могут быть свои дочерние объекты, а у тех свои и т.д. Вот пример иерархии вложенности:

...................Главная______фор ма..........................
.................../........................... \........................
............Панель N1 ................. Панель N2...............
.........../........... \.................. /.............\..............
....нопка N1 .... Кнопка N2 ... Панель N3 ... Кнопка N3
................................... ......./................................
................................... Кнопка N4..........................

Таким образом навигацию по окнам можно сравнить с навигацией по файловой системе.
Раз у вас уже есть хэндл (назовём его hMain) "Главной формы", то остаётся "добраться" до нужной кнопки. Сделать это можно так:

Напишем рекурсивную функцию, которая будет обходить наше "оконное дерево", ища кнопку с именем "Кнопка N3". Вид функции:
HWND Walk(HWND Current,char * Name);

Где-нибудь в программе делаем вызов target=Walk(hMain,"Кнопка N3").
Код:

HWND Walk(HWND Current,char * name)
{
  HWND temp;
  temp=GetWindow(Current,GW_CHILD); // находим первое дочернее окно
  while (temp!=NULL) // проверяем, а есть ли оно вообще
  {
     char WindowText[1024];
     GetWindowText(temp,WindowText,1023); // получаем его название
     if (!strcmp(name,WindowText)) return temp; // проверяем, искомая ли это кнопка, если да, то возвращаем её хэндл

     HWND result=Walk(temp,name); // если это была не она, то обходим её дочерние объекты

     if (result!=NULL) return result; // если при этом искомый объект был найден, возвращаем хэндл на него

     temp=GetWindow(temp,GW_HWNDNEXT) // иначе - проверяем следующий объект, дочерний для Current
  }
  return NULL; // объект не найден
}
Если в окне на который указывет хэндл hMain есть объект с именем "Кнопка N3", эта функция вернёт его хэндл, иначе - NULL.

Если обект найден, то на него осталось только нажать:
SendMessage(target,WM_LBUUTONDOWN,0 ,0);
И "отжать" его:
SendMessage(target,WM_LBUUTONUP,0,0 );

Простите, что имею нагласть вопреки названию форума писать примеры на Си - я давно не писал на паскале и, решись я на это, я обрёк бы свой код быть одной большой ошибкой. Если кто-то считает это недопуститым - пишите, я перепишу этот пример на паскале и впредь буду использовать только его.

Кстати. Если интересно, то вот программа (всесте с исходниками разумеется), которую я написал (как ни странно на дельфи), когда учился работать с чужими окнами. Она позволяет управлять любыми запущенными окнами и их дочерними объектами, как то скрывать и показывать их, переименовывать, рисовать на них, перемещать, унечтожать, ставить и снимать блокировку (послееднее особенно полезно, когда очень хочется нажать на кнопочку, а она по каким-то причинам недоступна).
Вложения
Тип файла: zip WndOwner.zip (282.9 Кб, 481 просмотров)
Практика - лучший критерий истины. К.Маркс.

Последний раз редактировалось unnamed; 04.07.2007 в 15:24.
unnamed вне форума
Старый 04.07.2007, 17:03   #4
SeRыЙ
 
Аватар для SeRыЙ
 
Регистрация: 01.07.2007
Сообщений: 4
По умолчанию

Что-то у меня ни один вариант не пашет(( Не знаю почему.
Вот есть запущенное окно подключения к интернету моего провайдера wanPPPoe с заголовком Connect altair и кнопкой Connect
Вот код:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  h1, h2: hwnd;
begin
  h1 := FindWindow(nil, 'Connect altair');
  h2 := FindWindowEx(h1, 0, 'TButton', 'Connect');
 // SendMessage(h2, BM_CLICK, 0, 0);
 showmessage(inttostr(h2));
 end;
ничего не работает вобще. showmessage возвращает ноль. Пробовал Tbutton и TBitBtn. Я вот думаю, может это защита микрософтская, типа чтобы трояны не могли интернет сами подлкючать? Или почему?

И если это защита, то можт там класс у кнопок какой стремный? Не знаете, как я могу узнать класс кнопки?

Даа точно, со своей программкой все работает. Значит что-то там не то. Наверно классы.
http://i-info.iplot.ru/
icq: 434327678

Последний раз редактировалось Stilet; 09.03.2010 в 07:58.
SeRыЙ вне форума
Старый 04.07.2007, 17:20   #5
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Пардон, не буду больше бред писать =) там в FindWindow парамерты местами поменять надо, да и bm_click не будет работать

Вот пришлось фасм быстренько скачать, рабочий код, жмет ОК в диалоге выполнить, ну в дельфе думаю ясно как

Код:
include 'D:\JTG\FASM167\include\win32ax.inc'

.data
  a dd 0
.code

  start:
        invoke  FindWindow,0,'Запуск программы'
        cmp eax,0
        jz error1

        invoke  FindWindowEx, eax,0,'Button','ОК' ;РУССКОЕ!
        cmp eax,0
        jz error2

        mov [a],eax
        invoke  SendMessage, [a],WM_LBUTTONDOWN,1,1
        invoke  SendMessage, [a],WM_LBUTTONUP,1,1
       ; invoke  SendMessage, [a],WM_LBUTTONDOWN,1,1 ;иногда дважды надо жать, хз
       ; invoke  SendMessage, [a],WM_LBUTTONUP,1,1
        invoke  ExitProcess,0
error1:
        invoke  MessageBoxA,0,'Не нашел окно','',0
        invoke  ExitProcess,0
error2:
       invoke  MessageBoxA,0,'Не нашел кнопку','',0
       invoke  ExitProcess,0

.end start
--

Вот короче. ДОЛЖНО уже работать, надеюсь. дельфы рядом нет, проверить не могу, звыняйте
Код:
procedure TForm1.Button1Click(Sender: TObject);
var h1,h2:HWND;
begin
  h1:=FindWindow(nil,'Connect altair');
  h2:=FindWindowEx(h1,0,'Button','Connect');
  SendMessage(h2,WM_LBUTTONDOWN,1,1);
  SendMessage(h2,WM_LBUTTONUP,1,1);
  //SendMessage(h2,WM_LBUTTONDOWN,1,1);
  //SendMessage(h2,WM_LBUTTONUP,1,1);
end;
Тока Connect м.б. &Connect и Сo&nnect, где там горячая клавиша

--
А, ну да, unnamed прав, может эта твоя проглятая кнопка не просто на форме лежит. Шли скриншот
Вложения
Тип файла: zip HELLO.zip (566 байт, 120 просмотров)
пыщь

Последний раз редактировалось JTG; 04.07.2007 в 17:40.
JTG вне форума
Старый 04.07.2007, 17:56   #6
SeRыЙ
 
Аватар для SeRыЙ
 
Регистрация: 01.07.2007
Сообщений: 4
По умолчанию

Млиин чуваак!! Я то думал что ты просто опечатался когда написал "&Connect" )) Я уже хотел забить на это дело но случайно прочитал последнюю строчку Действительно с классом "Button" и текстом "&Connect" все работает. Ну про текст понятно,но почему класс кнопки не TButton, а просто Button?
http://i-info.iplot.ru/
icq: 434327678
SeRыЙ вне форума
Старый 04.07.2007, 18:00   #7
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

TButton TCheckBox etc. это всё от дяди Борманда. В WinAPI таких классов нет. Там просто Button

DelphiWorld какашка!!! За такие примеры руки в обратную сторону выгибать надо
пыщь
JTG вне форума
Старый 04.07.2007, 18:03   #8
SeRыЙ
 
Аватар для SeRыЙ
 
Регистрация: 01.07.2007
Сообщений: 4
По умолчанию

Ну ясно. Вобщем спасибо что помогли!
http://i-info.iplot.ru/
icq: 434327678
SeRыЙ вне форума
Старый 13.07.2007, 17:13   #9
MaGiCaN
 
Регистрация: 13.07.2007
Сообщений: 6
По умолчанию

Если нужно работать с приложением писанным на дельфи то вот так:

Код:
procedure TForm1.Button1Click(Sender: TObject);
    var h1,h2:HWND;
begin
     h1:=FindWindow(nil,'Form1');
     h2:=FindWindowEx(h1,0,'TButton','Button2');
     SendMessage(h2,WM_LBUTTONDOWN,1,1);
     SendMessage(h2,WM_LBUTTONUP,1,1);
end;
А мне нужно чтобы прога получала окно и тыкала на кнопку по координатам например кнопка находится в левом верхнем углу и координаты у нее 1,1. Мне нужно чтобы прога автоматом на нее тыкнула.
MaGiCaN вне форума
Старый 13.07.2007, 22:12   #10
unnamed
Пользователь
 
Регистрация: 08.04.2007
Сообщений: 15
По умолчанию

Если известны только относительные координаты (x0,y0) кнопки, то можно нажать на неё мышкой

Код:
HWND wnd;
wnd=FindWindowEx(0,0,"Имя окна",0); // получаем хэндл окна с кнопкой
if (!wnd) 
{
  MessageBox(0,"окно не найдено",0,MB_OK);
  exit(1); 
} 
RECT r; 
GetWindowRect(wnd,&r);   // получаем координаты окна.
POINT prev_pos;
GetCursorPos(&prev_pos);           // запоминаем положение курсора 
SetCursorPos(x0+r.left,y0+r.top); // устанавливаем курсор над кнопкой
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); // надавливаем 
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);      // отпускаем
SetCursorPos(prev_pos.x,prev_pos.y); // возвращаем курсор на прежнее место
Практика - лучший критерий истины. К.Маркс.

Последний раз редактировалось unnamed; 13.07.2007 в 22:15.
unnamed вне форума
Закрытая тема

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
не могу нажать на кнопку 'Отправить' с помощью IdHTTP Dron_kss Работа с сетью в Delphi 3 17.04.2009 12:34
Нажать кнопку Dron_kss Работа с сетью в Delphi 1 28.03.2009 17:33
Программно нажать кнопку DeDoK Общие вопросы Delphi 2 04.05.2008 20:46
Нажать кнопку Teen4jump Работа с сетью в Delphi 11 29.02.2008 08:33
Как программно нажать Ctrl + V ffo Win Api 11 29.07.2007 16:58


Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru
Пеллетный котёл Emtas
котлы EMTAS
Здесь нужно купить рекламу за 7 тыс руб в месяц! )
пишите сюда - alarforum@yandex.ru
ИКС 840