![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Программно нажать на кнопку закрытия формы(крестик) [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);