Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];

Вниз

Как нажать кнопку в другой программе (ЧУЖОЙ ПРОЦЕСС не мой)?   Найти похожие ветки 

 
comwad ©   (2004-01-14 10:00) [0]

Как нажать кнопку в другой программе (ЧУЖОЙ ПРОЦЕСС не мой)?

Этот код не работает.
Где ошибка?

procedure TForm1.Button1Click(Sender: TObject);
var
wnd:HWND;
caption:string;
TheChildHandle:HWND;
const
NameApp="Form1";
begin
wnd:=FindWindow(nil, NameApp);
if wnd<> 0 then
Begin
TheChildHandle:=FindWindowEx(wnd,0,nil,PChar("Button3"));
SendMessage(TheChildHandle,WM_LButtonDown,1,1);
SendMessage(TheChildHandle,WM_LButtonUP,1,1);
End;
end;



Пожалуйста подскажите почему  этот код
при поиске TheChildHandle:HWND кнопки "Button3" своем же приложении находит, а в другом нет, хотя wnd находит правильно и там и там?

Работаю под XP , в HELP написано , что в NT FindWindowEx не работает,
может это с этим связано, тогда чем можно заменить?


 
[lamer]Barmaglot ©   (2004-01-14 10:25) [1]

DuplicateHandle?


 
YuRock ©   (2004-01-14 10:42) [2]

Надо делать примерно так:


procedure TForm1.Button1Click(Sender: TObject);
const
 NameApp = "Form1";
 NameLength = 10;
var
 wnd: HWND;
 caption: string;
 TheChildHandle: HWND;
 ButtonCaption: Array[0..NameLength] of Char;
begin
 wnd := FindWindow(nil, NameApp);
 if wnd <> 0 then begin
   TheChildHandle := GetWindow(wnd, GW_CHILD);
   while TheChildHandle <> 0 do begin
     GetWindowText(TheChildHandle, ButtonCaption, NameLength);
     if String(ButtonCaption) = "Button3" then begin
       SendMessage(TheChildHandle, BM_CLICK, 0, 0);
       Break;
     end;
   
     TheChildHandle := GetNextWindow(TheChildHandle, GW_HWNDNEXT);
   end;
   TheChildHandle:=FindWindowEx(wnd,0,nil,PChar("Button3"));
   SendMessage(TheChildHandle,WM_LButtonDown,1,1);
   SendMessage(TheChildHandle,WM_LButtonUP,1,1);
 end;
end;


 
YuRock ©   (2004-01-14 10:43) [3]

...

Переменная "caption: string;" в приведенном коде не нужна.


 
YuRock ©   (2004-01-14 10:44) [4]

:)))

Извините, блок кода

 TheChildHandle:=FindWindowEx(wnd,0,nil,PChar("Button3"));
 SendMessage(TheChildHandle,WM_LButtonDown,1,1);
 SendMessage(TheChildHandle,WM_LButtonUP,1,1);

тоже не нужен.


 
comwad ©   (2004-01-14 11:16) [5]

В этом месте
TheChildHandle := GetWindow(wnd, GW_CHILD);
уже возвращается 0.

Все тоже что и в моем коде.


 
YuRock ©   (2004-01-14 11:20) [6]

Быть не может (только когда на окне wnd нет ни одного дочернего окна).


 
comwad ©   (2004-01-14 11:47) [7]

Код из которого я запускаю предложенный Вами код
- не работает с другой программой. (код см.ниже)

procedure TForm__1.Button4Click(Sender: TObject);
const
NameApp = "Project1";
NameLength = 10;
var
wnd: HWND;
// caption: string;
TheChildHandle: HWND;
ButtonCaption: Array[0..NameLength] of Char;
begin
  wnd := FindWindow(nil, Pchar(NameApp));
  if wnd <> 0 then begin
  TheChildHandle := GetWindow(wnd, GW_CHILD);

// ЗДЕСЬ    TheChildHandle=0 !!!!!!!!!!!!!!!!!!!!!!!!!!!

  while TheChildHandle <> 0 do
  begin
  GetWindowText(TheChildHandle, ButtonCaption, NameLength);
  if String(ButtonCaption) = "Button1" then
      begin
      SendMessage(TheChildHandle, BM_CLICK, 0, 0);
      Break;
      end;

    TheChildHandle := GetNextWindow(TheChildHandle, GW_HWNDNEXT);
  end;
end;

end;


Код окна на котором нужно нажать кнопку Button1

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Edit1: TEdit;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage("Button1");
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage("Button2");
end;

end.


 
comwad ©   (2004-01-14 11:48) [8]

Может из-за Windows XP не работает?

Код из которого я запускаю предложенный Вами код
- не работает с другой программой. (код см.ниже)

procedure TForm__1.Button4Click(Sender: TObject);
const
NameApp = "Project1";
NameLength = 10;
var
wnd: HWND;
// caption: string;
TheChildHandle: HWND;
ButtonCaption: Array[0..NameLength] of Char;
begin
  wnd := FindWindow(nil, Pchar(NameApp));
  if wnd <> 0 then begin
  TheChildHandle := GetWindow(wnd, GW_CHILD);

// ЗДЕСЬ    TheChildHandle=0 !!!!!!!!!!!!!!!!!!!!!!!!!!!

  while TheChildHandle <> 0 do
  begin
  GetWindowText(TheChildHandle, ButtonCaption, NameLength);
  if String(ButtonCaption) = "Button1" then
      begin
      SendMessage(TheChildHandle, BM_CLICK, 0, 0);
      Break;
      end;

    TheChildHandle := GetNextWindow(TheChildHandle, GW_HWNDNEXT);
  end;
end;

end;


Код окна на котором нужно нажать кнопку Button1

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Edit1: TEdit;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage("Button1");
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage("Button2");
end;

end.


 
comwad ©   (2004-01-14 12:22) [9]

В своем процессе (в вызываемой программе) все работает нормально в ЧУЖОМ ПРОЦЕССЕ не работает (если нажимать на кнопку в чужой программе )!!!


 
YuRock ©   (2004-01-14 12:46) [10]

Единственное, что может быть - прога находит не то, что нужно окно с заголовком "Form1" - на котором и нет ничего. Кстати, надо писать не

GetWindowText(TheChildHandle, ButtonCaption, NameLength);

а

GetWindowText(TheChildHandle, @ButtonCaption, NameLength);


 
comwad ©   (2004-01-14 15:49) [11]

До GetWindowText(TheChildHandle, @ButtonCaption, NameLength);

дело к сожалению не доходит.
Что за хрень.
wnd - находит (= например 2033033), а по нему TheChildHandle не находит.

 wnd := FindWindow(nil, Pchar(NameApp));
 if wnd <> 0 then begin
 TheChildHandle := GetWindow(wnd, GW_CHILD);

 Может я исходники вам кину , если позволите конечно.
 Любопытно как на вашей машине они будут себя вести?
  Кстати на 98 проверял - тоже самое.


 
Digitman ©   (2004-01-15 08:22) [12]

NameApp - это что ? Caption главной формы "чужого" приложения ?


 
YuRock ©   (2004-01-15 10:09) [13]

> Digitman ©   (15.01.04 08:22) [12]

Да. Это из примера [2].


 
Digitman ©   (2004-01-15 10:30) [14]


> YuRock ©   (15.01.04 10:09) [13]


а вот это весьма сомнительно
в твоем примере идет действительно поиск окна формы с подписью Form1

автора же скорей всего ищет находит не окно гл.формы, а гл.окно приложения, у которого нет доч.окон, поэтому и GetWindow(GW_CHILD) дает отказ


 
YuRock ©   (2004-01-15 10:42) [15]

> Digitman ©   (15.01.04 10:30) [14]

Возможно. Но вряд ли. Обычно в программах, в которых заголовок главной формы "Form1" - заголовок главного окна "Project1" :)).

А т.к. в вопросе, в приведенном примере, ищется окно с заголовком "Form1", то я и думаю, что вряд ли.


 
Digitman ©   (2004-01-15 10:58) [16]


> в вопросе, в приведенном примере


там - да ...
но я - о переработанном автором с учетом твоего кода примере в [8]

ивот там как раз непонятно, с какого перепугу Form1 вдруг превратился в Project1

если св-во Application.Title в настройках проекта явно не указано и проект имеет имя исп.файла Project1.exe, то имя гл.окна приложения как раз и будет иметь подпись "Project1" (при имени класса этого окна "TApplication")

вот и сдается мне, что в [8] он ищет не форму, а как раз гл.окно приложения. которое, разумеется, никаких доч.окон по умолчанию не имеет


 
Digitman ©   (2004-01-15 11:03) [17]


> YuRock ©   (14.01.04 10:42) [2]
> Надо делать примерно так:


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

imho,  если в [8] строчку
wnd := FindWindow(nil, Pchar(NameApp));

изменить  на

wnd := FindWindow("TForm", Pchar(NameApp));

то wnd будет равным 0, что докажет оправданность моего предположения о том, что автором в [8] ищется совсем не то что нужно


 
YuRock ©   (2004-01-15 11:10) [18]

> Digitman ©   (15.01.04 10:58) [16]

Да, я и не заметил, что "Form1" превратилось в "Project1"...

> Digitman ©   (15.01.04 11:03) [17]

Небольшое уточнение:

wnd := FindWindow(nil, Pchar(NameApp));

изменить не на

wnd := FindWindow("TForm", Pchar(NameApp));

а на

wnd := FindWindow("TForm1", Pchar(NameApp));


 
Digitman ©   (2004-01-15 11:14) [19]


> YuRock ©   (15.01.04 11:10) [18]



> Небольшое уточнение


да, разумеется


 
Игорь Шевченко ©   (2004-01-15 15:36) [20]

А еще можно дать совет воспользоваться Spy++ :)
А еще можно дать совет - не нажимать кнопки в чужом окне...Ни к чему это...


 
Digitman ©   (2004-01-15 15:52) [21]


> Игорь Шевченко ©   (15.01.04 15:36) [20]


> не нажимать кнопки в чужом окне...Ни к чему это...


эт точно) ... ну разве что это стоит хороших денег от явно не скупого заказчика)


 
Игорь Шевченко ©   (2004-01-15 16:45) [22]

Digitman ©   (15.01.04 15:52)

Тогда вполне очевидно, что толикой денег автору надо делиться с тобой и с YuRock ? ;)


 
Digitman ©   (2004-01-15 18:11) [23]


> Игорь Шевченко


это очевидно нам) отвечающим) ... но явно не автору))


 
GrayFace ©   (2004-01-16 09:02) [24]

Лучше всего использовать первый код, но форму назвать "Моя супер-пупер форма" тогда точно найдется то, что надо. Или создать атом у той формы. Или создать там компонент "MySuperPuperComponent". А потом так:

var FormName, ComponentName, TheChildHandle:string//Или const

function AddWinInfo(WinHandle: HWnd; List: TListView): Boolean; stdcall;
var WinCaption,WinClass: array[0..255] of Char; a:Hwnd;
 n,j:integer;
begin
 Result:=True;
 GetWindowText(WinHandle,WinCaption,SizeOf(WinCaption));
 if ""+WinCaption<>FormName then exit;
 TheChildHandle:=FindWindowEx(wnd,0,nil,PChar("Button3"));
 if TheChildHandle<>0 then result:=false;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 EnumWindows(@GetButton,0);  
end;


 
GrayFace ©   (2004-01-16 09:03) [25]

Вместо AddWinInfo(WinHandle: HWnd; List: TListView) надо GetButton(WinHandle: HWnd)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.035 c
14-1077737081
тихий вовочка
2004-02-25 22:24
2004.03.28
Транспортная задача


1-1078829595
Rauf
2004-03-09 13:53
2004.03.28
Wide аналог StrPos???


4-1073984926
Андрю-ХА
2004-01-13 12:08
2004.03.28
Контекстное меню


14-1077899292
Adil Aliyev
2004-02-27 19:28
2004.03.28
Простой вопрос по сетю


4-1074451535
DillerXX
2004-01-18 21:45
2004.03.28
Как вставить текст из буфера обмена?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский