![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как узнать что пользователь только-что закрыл AutoCAD [D7, WinXP]
Calibr2 © (2006-07-11 06:37:00)У меня проблема в том, что нужно отловить момент, когда пользователь закроет приложение AutoCAD. Приложение AutoCAD у меня хранится в переменной типа IAcadApplication из модуля AutoCAD_TLB. Как это возможно сделать подскажите, буду очень признателен!!!
Calibr2 (2006-07-11 13:14:00) [21]Спасибо тебе Elen за твое терпение, но все таки иногда одно сообщение не отображается!!! Но все равно спасибо всем за советы!!!
Elen (2006-07-11 12:49:00) [22]
> Calibr2
У меня твой пример работает на ура. Но окно сообщения появляется только если ты перейдеш на свою форму после клика по закрыть. Ты наверное пропустил одно сообщение (Не заметил). Вместо этого ставь свою форму на перед типа SetForegroundWindow
umbra (2006-07-11 12:32:00) [23]http://www.autocad.ru/cgi-bin/f1/board.cgi?t=6915Ah
Calibr2 (2006-07-11 12:32:00) [24]Ладно ответте мне пожалуйста на такой вопрос. Если в AutoCADе запущено несколько документов и они абсолютно все хранятся у меня в массиве и для них всех назначен метод OnClose, почему он срабатывает не для всех документов. При тестировании я запустил 3 документа, затем закрыл AutoCAD и MessageBox вышел только 2 раза, а 3-ий документ проигнорировал, помогите исправить проблему, подскажите, что у меня не так:
var
Acad: OleVariant;
AcadApp: IAcadApplication;
AcadDocs: array[0..50] of TAcadDocument;
procedureTForm1.Timer1Timer(Sender: TObject);
var
i: Integer;//Счетчик, вспомогат. переменная
iCol: Integer;//Количество документов в AutoCADе
begin
try
{пытаемся подключиться к уже запущенному AutoCADу}
Acad := GetActiveOleObject('AutoCAD.Application');
AcadApp := IDispatch(Acad) as IAcadApplication;
Caption := 'AutoCAD запущен';// пишем, что AutoCAD запущен
except
{если не получилось, то пишем, что AutoCAD закрыт}
Caption := 'AutoCAD сейчас закрыт...';
ListBox1.Clear;// очищаем список
iCol := 0;
exit;// выходим
end;
try
{пытаемся подключиться к активному документу}
iCol := AcadApp.Documents.Count;//Определяем кол-во документов
{Цикл перебора всех запущенных документов}
fori := 0 toiCol - 1 do
begin
AcadDocs[i].Free;
AcadDocs[i] := nil;
AcadDocs[i] := TAcadDocument.Create(Self);//Создаем документ
AcadDocs[i].ConnectTo(AcadApp.Documents.Item(i));//Соединяем его с
//i-тым в AutoCadе
AcadDocs[i].OnBeginClose := BeginClose;//Закрытие
end;
except
{если не получилось, то пишем Чертёж не запущен}
Caption := 'Чертеж не запущен...';
exit;// выходим
end;
end;
(******* ПРОЦЕДУРА ЗАКРЫТИЯ ДОКУМЕНТОВ *******)
procedureTForm1.BeginClose(Sender: TObject);
var
i : Integer;//Счётчик
Name: String; //Имя закрывающегося файла
begin
Timer1.Enabled := false;
Name := (Sender as TAcadDocument).Name;//Определяем имя закрывающегося файла
{Выводим диалог сохранения}
ifApplication.MessageBox(pChar('Сохранить изменения в документе ' + Name + '?'), 'AutoCAD', mb_YESNO + MB_ICONWARNING) = idYES then
{Если отвечают "ДА"}
Caption := 'Yes';
else
Caption := 'No';
Timer1.Enabled := true;
end;
Calibr2 (2006-07-11 11:55:00) [25]AbrosimovA
а где можно скачать компонент TAcadApplicationEvents?
Elen (2006-07-11 11:42:00) [26]
> AbrosimovA ©
ИМХО Автор имеет в виду не СОМ объект а стороннее приложение где это не пройдет Пусть лучше изучит VBA, хоть это и гадость но это лучше
Elen (2006-07-11 11:30:00) [27]И что мешает попробовать прямо сейчас?
AbrosimovA (2006-07-11 11:30:00) [28]Смотри здесь:
http://66.249.93.104/search?q=cache:4LIqHO1_xaIJ:www.autocad.ru/cgi-bin/f1/board.cgi%3Ft%3D6915Ah+TAcadApplicationEvents&hl=ru&gl=ru&ct=clnk&cd=1
Calibr2 (2006-07-11 11:21:00) [29]В моем понимании это так:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
OldWinProc, NewWinProc: Pointer;
procedure NewWinProcedure(var Msg: TMessage);
public
{ Public declarations }
end;
var
Form1: TForm1;
h: hWnd;
implementation
{$R *.dfm}
procedure TForm1.NewWinProcedure(var Msg: TMessage);
begin
if Msg.Msg = WM_DESTROY then
Application.MessageBox('Сохранит изменения в документе?',
'AutoCAD', MB_YESNO + MB_ICONWARNING);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//Ну Handle я найду конечно иным способом чем этот
//просто допустим Handle уже у меня есть
h := FindWindow(nil, 'AutoCAD 2004');
NewWinProc := MakeObjectInstance(NewWinProcedure);
OldWinProc := Pointer(SetWindowLong(h, GWL_WNDPROC, Cardinal
(NewWinProc)));
end;
end.
Elen (2006-07-11 11:07:00) [30]
> задать для него новую оконну процедуру
А это как в твоем понимании?
Calibr2 (2006-07-11 11:02:00) [31]Да хук на данный момент не надежный помощник. Ну неужели никак нельзя отловить закрытие AutoCADa. А если узнать его Handle, потом задать для него новую оконну процедуру и отлавливать сообщение WM_DESTROY или WM_QUIT, как вы думаете выйдет так или нет
Elen (2006-07-11 10:31:00) [32]P.S.
//Это DLL
uses
SysUtils,
windows,
Dialogs,
Classes;
var hook:HHOOK;
{$R *.res}
function _(code:Integer;w:WPARAM;l:LPARAM):word;stdcall;
var
begin
beep(100,100);
//Будет пикать при закрытии и открытии приложения и в других случаях
result:=CallNextHookEx(hook,code,w,l) ;
end;
//********** FUNCTION **********
function hh:hhook ;
begin
result:=SetWindowsHookEx( WH_CBT,@_,HInstance,0);
end;
//********** END FUNCTION ******
//********** FUNCTION **********
function uh(hhh:hhook):LongBool;
begin
result:=UnhookWindowsHookEx(hhh);
end;
//********** END FUNCTION ******
exports hh, uh;
begin
end.
Создай проект и загружай в нем эту ДЛЛ и пусть висит
Вызовеш hh в проекте и она вернет тебе хендл на хук, который потом нужно закрывать в uh
Почитай еще про WH_CBT и иже с ними в SDK
Elen (2006-07-11 10:22:00) [33]
> Calibr2
Попробуй на VBA написать скрипт который будет выполнятся с Акадом и помести его как стандартный шаблон и там ты сможеш проконтролировать все. Это будет гораздо эффективнее и безопаснее чем ставить Хуки.
Если все же хочеш хук то рой в сторону SetWindowhookEx в SDK хелпе. И на этом форуме много про это веток в WinAPI и основной
Calibr2 (2006-07-11 09:57:00) [34]Я уточняю! Мне нужно перехватить закрытие AutoCADа, чтобы перед закрытием вывести сообщение типа MessageBox, а если AutoCAD уже закроется уже будет поздно. Мне нужно именно перехватить закрытие, а когда ответят на MessageBox, то пожалуйста пусть дальше закрывается. Говорите написать Хук, а какие комбинации клавиш мне в нем отлавливать? Приведите пример кода please...
Elen (2006-07-11 08:57:00) [35]
> AbrosimovA ©
У автора речь идет не о документе а о приложении. Акад не факт что закроют а на документе это сработает но при закрытии дока Акад не сам закрывается если конечно автор это не пропишет
AbrosimovA (2006-07-11 08:39:00) [36]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleServer, AutoCAD_TLB;
type
TForm1 = class(TForm)
AcadDocument1: TAcadDocument;
procedure AcadDocument1BeginClose(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AcadDocument1BeginClose(Sender: TObject);
begin
ShowMessage('AutoCAD закрывается')
end;
end.
Elen (2006-07-11 08:00:00) [37]
> Calibr2
Уточни свой вопрос - для чего?
ИМХО попробуй в таймере что нибудь типа
try
caption:=AcadApplication1.caption;
except
Messagebox('','Все закрыто')
end;
Это не самый лучший вариант но работает.
Или ставь хук на закрытие приложения