Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Программно нажать на кнопку закрытия формы(крестик) [D7, Win2k, WinXP]


Dimich1978 ©   (2006-04-20 10:57:00) 

Пишу следующее
procedure TForm1.Button1Click(Sender: TObject);
var
 hwndHandle: THANDLE;
 hMenuHandle: HMENU;
begin
 hwndHandle := FindWindow(nil, 'Калькулятор');
 if (hwndHandle <> 0) then
 begin
   hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
   if (hMenuHandle <> 0) then
   SendMessage(hMenuHandle, BM_CLICK, 0, 0);
 end;
end;
Но нажатия не просиходит, т.е. калькулятор не закрываеться.
Помогите плиз..почему ? и как можно сделать закрытие?


Dimich1978   (2006-04-27 13:55:00) [1]

По вышеописанному коду все работает ОК. Но есть одна штука. Т.е когда я пытаюсь закрыть приложение, то могут выскакивать  в1С (с одинаковым заголовком и отличающееся) диалоговые окна, которые надо закрыть все подряд надимая Да. Немного дописал. Прога окна стала закрывать. Но необходимо постоянно посылать команды для закрытия, т.е.е выпало 3 окна три раза надо на кнопку нажать. Хотелось бы автоматизировать.
т.е. закрывать окна пока не закроеться приложение.
К примеру я нажимаю Закрыть программу, в ответ появляетьяс окно, Сохраните изменения, я отвечаю ДА, в ответ выскакивает окно, Время проведения документа...нужно ответить ОК. Т.е. у меян выскочило 3 диалоговых окна, необходимо процедуру    EnumWindows(@ParentWnd,0) вызвать 3 раза, а если вылетить 4 окна. Т.е. хотелось бы закрыть их , точнее закрывать пока не закроеться приложение. Если мой бред хоть чуть чуть понятен, скажите как енто можно сделть.
Заранее спасибо.
function ChildWnd(h:THandle; Info: Pointer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
Form1.Memo1.Lines.Add(Text);
if (StrPas(Text) = '&Да')or (StrPas(Text) = 'OK')then begin
postMessage(h,BM_CLICK,0,0);
result:=false;
end else result:=true;
end;

function ParentWnd(h:THandle; Info: Pointer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 256);
if (StrPas(Text) = '1С:Предприятие) or (strpas(text)='Ввод времени') then begin
 EnumChildWindows(h,@ChildWnd,0);
Form1.Memo2.Lines.Add(Text);
 result:=false;
end else result:=true;
end;

procedure TForm1.close1c_ON;
begin
  EnumWindows(@ParentWnd,0);
end;

procedure TForm1.close1c_start(Sender: TObject);
var
   h: THANDLE;
begin
h := FindWindow(nil, '1С:Предприятие - Комплексная конфа 4.5');
 PostMessage(h, WM_CLOSE, 0 ,0);
end;


Eraser   (2006-04-24 18:24:00) [2]


> Dimich1978   (24.04.06 18:04) [18]


> Окно закрываеться , но со второго раза, т.к. по первому
> разу происходит активация окна (диалогового) и кнопки, потом
> происходит собственно нажатие....

"Эт врядли" (с)
хотя сам не проверял.


Dimich1978   (2006-04-24 18:04:00) [3]

Окно закрываеться , но со второго раза, т.к. по первому разу происходит активация окна (диалогового) и кнопки, потом происходит собственно нажатие....данный путь возможно сократить или посылать сразу просто два sendmessage подряд?


Eraser   (2006-04-24 16:39:00) [4]


> Dimich1978   (21.04.06 12:47) [15]


> А про манипуляции PostMessage(h, WM_CLOSE, 0 ,0) т.е. почему
> не через sendmessage?

1. PostMessage работает асинхронно, т.е. осослал и забыл, а SendMessage - синхронно, т.е. отсылает и ждёт ответа, которые не всегда и нужен.
2. SendMessage(h, WM_CLOSE, 0 ,0) не работает в win98, почему - не вкурсе, наверное, потому что обрабатывается не в оконной процедуре окна.


AbrosimovA   (2006-04-24 16:31:00) [5]

function ChildWnd(h:THandle; Info: Pointer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
Form1.Memo1.Lines.Add(Text,nil); // Все чилды окна
if Text = 'Да' then begin // Здесь возможны варианты: &Даили Д&а, это будет видно из Memo1
 SendMessage(h,BM_CLICK,0,0);
 result:=false;
end else result:=true;
end;

function ParentWnd(h:THandle; Info: Pointer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 256);
if StrPas(Text) = '1 С:Предприятие' then begin // Английская С или русская?
  EnumChildWindows(h,@ChildWnd,0);
 Form1.Memo1.Lines.Add(Text,nil); // для контроля, что окно найдено
  result:=false;
end else result:=true;
end;


Dimich1978   (2006-04-21 12:47:00) [6]

Т.е. я закрываю окно 1С главное. Вываливаеться диалогове окно.. www.ochakovo2.ru/screen.jpg
вот его и надо закрыть, точнее нажать Да и закрыть.
А про манипуляции PostMessage(h, WM_CLOSE, 0 ,0) т.е. почему не через sendmessage?


Dimich1978   (2006-04-21 12:46:00) [7]

Т.е. я закрываю окно 1С главное. Вываливаеться диалогове окно.. www.ochakovo2.ru/screen.jpg
вот его и надо закрыть, точнее нажать Да и закрыть.
А про манипуляции PostMessage(h, WM_CLOSE, 0 ,0) т.е. почему не через sendmessage?


AbrosimovA   (2006-04-21 08:12:00) [8]

Я не совсем понял, какое окно у тебя является диалоговым, и что это за манипуляции с WM_CLOSE.
А здесь
> form1.memo1.lines.add( text);

заменить на StrPas(text)


Dimich1978   (2006-04-20 16:55:00) [9]

по данному коду происходит следующее.
Выскакивает диалоговое окно и ничего не происходит. Проходит некоторое время...я перехожу на форму 1С и нажимаю кнопку НЕТ(не заканчиватьь работу с программой), чтобы не закрывалось. Но 1С закрываеться.  
добавил memo1.lines.add(text);
в данном списке не видно 1С:Предприятие...хотя определяю его windows text выдает что 1С:Предприятие, да и в заголовке диалогового окна тоже написано 1С:Предприятие. Блин осталось чуточку чтобы дописать...видна победа....
помогите еще чуть чуть.
Заранее благодарен
function ChildWnd(h:THandle; wparam:integer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
if Text = '&Да' then begin
SendMessage(h,BM_CLICK,0,0);
result:=false;
end else result:=true;
end;

function ParentWnd(h:THandle; wparam:integer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
form1.memo1.lines.add(text);
if StrPas(Text) = '1С:Предприятие' then begin
 EnumChildWindows(h,@ChildWnd,0);
 result:=false;
end else result:=true;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
hwndHandle: THANDLE;
   h2,h1,h: THANDLE;
 hMenuHandle: HMENU;
begin
h := FindWindow(nil, '1С:Предприятие - Конфа.1.0.030');
 if (h 0) then
 begin
   hMenuHandle := GetSystemMenu(h, FALSE);
   if (hMenuHandle 0) then
 PostMessage(h, WM_CLOSE, 0 ,0);
 end;
EnumWindows(@ParentWnd,0);
end;


AbrosimovA   (2006-04-20 15:23:00) [10]

function ChildWnd(h:THandle; wparam:integer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
if Text = '&Да' then begin
 SendMessage(h,BM_CLICK,0,0);
 result:=false;
end else result:=true;
end;

function ParentWnd(h:THandle; wparam:integer): Bool;stdcall;
var
Text: array [0..256] of Char;
begin
GetWindowText(h, text, 200);
if StrPas(Text) = '1С:Предприятие' then begin
  EnumChildWindows(h,@ChildWnd,0);
  result:=false;
end else result:=true;
end;

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


AbrosimovA   (2006-04-20 15:16:00) [11]

А какой текст в заголовке диалогового окна?


Dimich1978   (2006-04-20 14:27:00) [12]

Висла прога на sendmessage переделал на postmessage все ок.

procedure TForm1.Button1Click(Sender: TObject);
var
 hwndHandle: THANDLE;
   h2,h1,h: THANDLE;
 hMenuHandle: HMENU;
begin
 hwndHandle := FindWindow(nil, '1С:Предприятие - Общепит ред.1.0.030');
 if (hwndHandle 0) then
 begin
   hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
   if (hMenuHandle 0) then
//    SendMessage(hwndHandle, WM_CLOSE, 0, 0);
 PostMessage(hwndHandle, WM_CLOSE, 0 ,0);
 h:=FindWindow(nil, '1С:Предприятие');

//  EnumChildWindows(h,@ef,0);

 if (hwndHandle 0) then
   begin
h2 := FindWindowEx(h, 0, 'TButton', '&Да');
 SendMessage(h2, BM_CLICK, 0, 0);
   end;
end;
end;
вторая часть , а именно закрытие диалогового окна через FindWindowEx не получаеться значит надо делать через EnumChildWindows.
Можно пример как с ней работать и вычислить мое диалоговое окно и нажать на кнопку.
Спасибо. Помогите плиз.


Dimich1978   (2006-04-20 13:47:00) [13]

Виснет прога на этом месте
SendMessage(hwndHandle, WM_CLOSE, 0, 0);
т.е. посылаю форме сообщение на закрытие , закрытия не происходит появляетьяс диалоговое окно и все прога останавливаеться на этом месте..т.е.е выполнение EnumChildWindows не происходит (смотрел пошагово)
вот отрывок
function ef(h:THandle;wparam:integer):boolean;stdcall;
var
 h1:THandle;
 s:string;
begin
{  s:='Òèïà ñåðèéíûé íîìåð';
 if wparam5 then begin}
   SendMessage(h,WM_COMMAND,wparam,0);//Òèïà ñîîáùàåì äèàëîãó, ÷òî ìû íàæàëè
{  end else begin
   h1:=FindWindowEx(h,0,'Edit',nil);  //Èùåì òðåòèé ïî ñ÷åòó Edit è ââîäèì â íåãî òåêñò
   h1:=FindWindowEx(h,h1,'Edit',nil);
   h1:=FindWindowEx(h,h1,'Edit',nil);
   SendMessage(h1,WM_SETTEXT,0,cardinal(s));
 end;}
 result:=false;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 hwndHandle: THANDLE;
   h2,h1,h: THANDLE;
 hMenuHandle: HMENU;
begin
 hwndHandle := FindWindow(nil, '1С:Предприятие - Конфа.1.0.030');
 if (hwndHandle 0) then
 begin
   hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
   if (hMenuHandle 0) then
   SendMessage(hwndHandle, WM_CLOSE, 0, 0);
     Sleep(1000);
 h:=FindWindow(nil, '1С:Предприятие);
 EnumChildWindows(h,@ef,0);
 end;

end;
Почему происходит завис....не догоняю..


AbrosimovA   (2006-04-20 13:03:00) [14]

function EnumChildWindows(hWndParent: HWND; lpEnumFunc: TFNWndEnumProc;
 lParam: LPARAM): BOOL; stdcall;


Dimich1978   (2006-04-20 12:21:00) [15]

Перенправил..виснет
var
 hwndHandle: THANDLE;
   h2,h1: THANDLE;
 hMenuHandle: HMENU;
begin
 hwndHandle := FindWindow(nil, '1Ñ:Ïðåäïðèÿòèå - Îáùåïèò ðåä.1.0.030');
 h1:= FindWindow(nil, '1Ñ:Ïðåäïðèÿòèå');
 if (hwndHandle 0) then
 begin
   hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
   if (hMenuHandle 0) then
   SendMessage(hwndHandle, WM_CLOSE, 0, 0);
 end;
   if (hwndHandle 0) then
   begin
h2 := FindWindowEx(h1, 0, 'TBitBtn', '&Yes');
 SendMessage(h2, BM_CLICK, 0, 0);
   end;


Dimich1978   (2006-04-20 12:17:00) [16]

Имееться 1С, нажимаю программно закрыть её(крестик). Все нормально, но если есть MDI форма то вываливаеться диалог типа "Закончить рабоу программы", мне вот необходимо нажать в этом диалоге, Да.
Пишу:
var
 hwndHandle: THANDLE;
   h2: THANDLE;
 hMenuHandle: HMENU;
begin
 hwndHandle := FindWindow(nil, '1Ñ:Ïðåäïðèÿòèå - Îáùåïèò ðåä.1.0.030');
 if (hwndHandle 0) then
 begin
   hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
   if (hMenuHandle 0) then
   SendMessage(hwndHandle, WM_CLOSE, 0, 0);
 end;
 if (hwndHandle 0) then //Если окно не закрыто значит появился диалог
begin
h2 := FindWindowEx(hwndHandle, 0, 'TBitBtn', '&Yes'); - думаю что тут вот проблема, т.к. хендл окна диалоговского другой нежели у главной формы
 SendMessage(h2, BM_CLICK, 0, 0); А тут пытаюсь нажать Да.
end;
end;
Прокомментируйте плиз... и что можно придумать?


AbrosimovA   (2006-04-20 11:24:00) [17]

Известен способ имитации нажатия клавиш в чужом приложении. Ищи в FAQ.


Dimich1978   (2006-04-20 11:21:00) [18]

ок дошло..спасибо..не увидел с первого раза.


Dimich1978   (2006-04-20 11:08:00) [19]

Хорошо, а как нажать кнопку находящуюся на меню?


MBo   (2006-04-20 11:06:00) [20]

А почему ты считаещь, что меню должно отвечать на сообщение, предназначенное кнопкам?

hwndHandle := FindWindow(nil, 'Калькулятор');
if (hwndHandle <> 0) then
  SendMessage(hwndHandle, WM_CLOSE, 0, 0);


Наверх

Титульная страница Поиск, карта сайта Написать письмо