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

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

Как узнать что пользователь только-что закрыл AutoCAD [D7, WinXP]


Страницы:   1 2

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;

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


Страницы:   1 2

Наверх

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