|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Как реализовать запуск разных версий Автокада из Delphi ?
Всем привет!
Задачка такая... На форме имеется ComboBox с списком версий автокада AutoCAD 2012 AutoCAD 2015 И кнопка <Запустить Автокад> Как реализовать запуск нужной версии ? Как я понимаю основная проблема в подключении нужной библиотеки в реал тайм... Пробовал в uses прописать все подключенные библиотеки Код:
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ComObj, Vcl.StdCtrls, Vcl.OleServer, AutoCAD_2012_TLB, AutoCAD_2015_TLB, Vcl.Menus; Библиотеки AutoCAD_2012_TLB, AutoCAD_2015_TLB естественно были предварительно подключены На машине на которой установлен только автокад 2015 всё заработало на ура. Но стоит запустить на машине на которой установлен только 2012 автокад тут же появится сообщение о том что "ни чего дружочек у тебя не выйдет" т.е. Interface not supported ... хотя обе библиотеки прописаны в юзесах и AutoCAD_2012_TLB точно подключена, её компоненты присутствуют на инструментально палитре ... Как решить эту задачку ? Последний раз редактировалось Homo-Fantasmus, 15.12.2014 в 22:40. |
#2
|
||||
|
||||
Цитата:
Вангую, что если программа запускается на машине с 2012-м AutoCAD-ом, а падает только на попытке его запуска, в программе нужно через точку писать: Код:
begin if ComboBox1.ItemIndex = 0 then AutoCAD_2012_TLB.Запустись else AutoCAD_2015_TLB.Запустись; end; Не стоит путать форумы с богадельнями. © Bargest |
#3
|
||||
|
||||
Цитата:
Гениально )) AutoCAD_2015_TLB.Запустись; НАСМЕШИЛ МАХАЛАЙ-БАХАЛАЙ АВТОКАДА ЗАПУСТИСЬ TLB (англ. Type Library — библиотека типов) — иерархическое хранилище информации о возможностях ActiveX-сервера в OLE Automation. |
#4
|
||||
|
||||
Забыл ; поставить
МАХАЛАЙ-БАХАЛАЙ АВТОКАДА ЗАПУСТИСЬ; До конструкции IF - ELSE я бы как ни будь сам додумался )) видишь ли тут всё немного сложнее ... |
#5
|
||||
|
||||
Не смеяться нужно, а на вопросы отвечать. Я не телепат и в отпуске не был. В прошлом сообщении подразумевались вопросы:
Не стоит путать форумы с богадельнями. © Bargest |
#6
|
||||
|
||||
Смотри второй скриншот, там справа в менеджере проекта подключены 2 библиотеки AutoCAD_2012_TLB и AutoCAD_2015_TLB
в uses они прописаны Цитата:
вот в таком виде запускается только на машине где установлен Acad2015, на машине где установлен Acad2012 не запускается. теперь если из uses убрать AutoCAD_2015_TLB, то будет запускаться на машине где установлен Acad2012. Редактируя uses я пока и запускаю нужную версию, т.е. я пока не знаю как это реализовать нормально т.е. программно... В этом и проблема я не пойму как это сделать ... Запускается автокад по нажатию кнопки <Запустить Автокад> но запускается только та версия библиотека которой прописана в uses Теперь код запуска Код:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ComObj, Vcl.StdCtrls, Vcl.OleServer, AutoCAD_2012_TLB, Vcl.Menus; type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; ComboBox1: TComboBox; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } mess: TModalResult; AcadApp: IAcadApplication; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} Function GetAcadApplication(Visible: Boolean): IAcadApplication; var v : OleVariant; begin Try // пытаемся присоединиться к уже запущенной копии AutoCad v := GetActiveOleObject('AutoCAD.Application'); Except // если не получилось присоединиться, то запускаем новую копию AutoCad v:= CreateOleObject('AutoCAD.Application'); end; // приводим переменную типа OleVariant к типу IAcadApplication Result := IDispatch(v) as IAcadApplication; // далее проверяем, надо ли делать приложение AutoCad видимым if Visible then Result.Visible := True; end; .... //ЗАПУСК АВТОКАДА procedure TForm1.Button1Click(Sender: TObject); begin // делаем так, что бы наша форма отображалась всегда поверх окна AutoCad FormStyle:= fsStayOnTop; AcadApp:= GetAcadApplication(true); end; Как реализовать управление версиями ? |
#7
|
||||
|
||||
Для VB есть решение:
GetObject("AutoCAD.Application.18") для запуска 2012 версии GetObject("AutoCAD.Application.20") должен по логике запускать 2015 Кто ни будь знает для Delphi есть какой ни будь подобный инструмент ? |
#8
|
||||
|
||||
Пробовал подобным образом запустить Acad 2012
Код:
Function GetAcadApplication(Visible: Boolean): IAcadApplication; var v1 : OleVariant; begin Try // пытаемся присоединиться к уже запущенной копии AutoCad v1 := GetActiveOleObject('AutoCAD.Application.18'); Except // если не получилось присоединиться, то запускаем новую копию AutoCad v1:= CreateOleObject('AutoCAD.Application.18'); end; // приводим переменную типа OleVariant к типу IAcadApplication Result := IDispatch(v1) as IAcadApplication; // далее проверяем, надо ли делать приложение AutoCad видимым if Visible then Result.Visible := True; end; procedure TForm1.Button2Click(Sender: TObject); begin FormStyle:= fsStayOnTop; AcadApp:= GetAcadApplication(true); end; но в ответ Interface NOT Supported! или "Недопустимая строка с указанием класса" |
#9
|
||||
|
||||
Цитата:
Код:
begin CreateOleObject'Excel.Application.10'); // работает CreateOleObject'Excel.Application.11'); // ошибка end; Код:
Result := v1 as AutoCAD_2012_TLB.IAcadApplication; Не стоит путать форумы с богадельнями. © Bargest |
#10
|
|||
|
|||
Например, считать в реестре
HKEY_CLASSES_ROOT\AutoCAD.Application\CurVer там будет что-то вроде AutoCAD.Application.18 Затем последовательно искать в реестре наличие версий HKEY_CLASSES_ROOT\AutoCAD.Application.18 HKEY_CLASSES_ROOT\AutoCAD.Application.17 HKEY_CLASSES_ROOT\AutoCAD.Application.16 и.т.д HKEY_CLASSES_ROOT\AutoCAD.Application.1 |
#11
|
||||
|
||||
Цитата:
Не стоит путать форумы с богадельнями. © Bargest |
#12
|
||||
|
||||
А вот таким способом пробовали?
Код:
uses ComObj, ActiveX; resourcestring rsAcadNotFound = 'AutoCAD не найден!'; var Acad: OleVariant; procedure AcConnect(const acClassName: String; const acNewInstance: Boolean; const acVisible: Boolean); var IU: IUnknown; ClassID: TCLSID; IsCreate: Boolean; ErrorCode: HResult; begin if VarIsClear(Acad) then // если еще не присоединились… begin // если AutoCAD не установлен — произойдет ошибка ErrorCode:= CLSIDFromProgID(PWideChar(WideString(acClassName)), ClassID); if not Succeeded(ErrorCode) then raise EOleSysError.Create(rsAcadNotFound, ErrorCode, 0); // пытаемся присоединиться к уже запущенному экземпляру AutoCAD IsCreate:= acNewInstance or (not Succeeded(GetActiveObject(ClassID, nil, IU))); if IsCreate then try // запускаем новый экземпляр AutoCAD Acad:= CreateComObject(ClassID) as IDispatch; except raise EOleSysError.Create(rsAcadNotFound, ErrorCode, 0); end else Acad:= IU as IDispatch; // управляем видимостью AutoCAD if not VarIsClear(Acad) then Acad.Visible:= acVisible; end; end; Где-то в программе: AcConnect('AutoCAD.Application', True, False); Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#13
|
||||
|
||||
Спасибо, буду пробовать, разбираться.
|
#14
|
||||
|
||||
Решение найдено
Кажется я всё слишком усложнил ...
Прописывать в коде - AutoCAD.Application.18 *.19 *.20 - это всё не нужно ... Нужно только подцепить библиотеку для последней версии ACada например для 2015 И можно будет работать с Автокадами версий 2014, 2013, 2012; будут ли работать версии ниже 2012 не знаю, но мне это и не нужно... Код:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ComObj, Vcl.StdCtrls,Vcl.OleServer, AutoCAD_TLB, Vcl.Menus; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Button2: TButton; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } AcadApp: IAcadApplication; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} Function GetAcadApplication(Visible: Boolean): IAcadApplication; var v : OleVariant; begin Try v := GetActiveOleObject('AutoCAD.Application'); Except AutoCad v:= CreateOleObject('AutoCAD.Application'); end; Result := IDispatch(v) as IAcadApplication; if Visible then Result.Visible := True; end; procedure TForm1.Button2Click(Sender: TObject); begin AutoCad FormStyle:= fsStayOnTop; AcadApp:= GetAcadApplication(true); end; end. Как завещал товарищ Ленин: УЧИТЬСЯ! УЧИТСЯ! И ЕЩЁ РАЗ УЧИЦЦА! |