Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Дипломная работа.docx
Скачиваний:
12
Добавлен:
23.03.2022
Размер:
353.66 Кб
Скачать

2.2 Разработка плагина

Проектировать плагин будем в Microsoft Visual Studio 2017. За отладку и тестирование работоспособности плагина будет отвечать AutoCAD 2018.

В процессе создание плагина нам понадобятся следующие dll-файлы. Добавляем их в наш проект:

  • accoremgd.dll;

  • AcCui.dll;

  • acdbmgd.dll;

  • acmgd.dll;

  • AdWindows.dll.

Плагин будет связующим элементом между базой данных и AutoCAD. Он должен уметь просматривать файлы чертежей в БД, скачивать их и сохранять в виде новых записей. Так же он должен уметь выполнять деталировку чертежа (полный листинг плагина смотрите в приложении 1).

Для начала создадим внешний вид вкладки плагина. Пример кода создания первой кнопки представлен ниже:

// создание первой кнопки

RibbonButton rb1 = new RibbonButton();

// задаем ее ориентацию

rb1.Orientation = System.Windows.Controls.Orientation.Vertical;

// указываем размер картинки

rb1.Size = RibbonItemSize.Large;

// задаем айди кнопки

rb1.Id = "btn1";

// задаем название кнопки

rb1.Text = "Войти в КБ";

// включаем отображение текста

rb1.ShowText = true;

// присваиваем кнопке картинку

rb1.LargeImage = LoadImage("icon_1");

// включаем отображение картинки

rb1.ShowImage = true;

// всплывающая подсказка

rb1.ToolTip = "Авторизация в системе СУБД для конструкторского бюро";

// включаем отображение подсказки

rb1.IsToolTipEnabled = true;

// обработчик кнопки

rb1.CommandHandler = new CH_rb1();

После, нужно поместить все кнопки в контейнеры. Фрагмент кода представлен ниже:

// создаем контейнер

RibbonPanelSource rbs1 = new RibbonPanelSource();

rbs1.Title = "Авторизация";

// добавляем в контейнер кнопку

rbs1.Items.Add(rb1);

Дальше нужно поместить контейнеры в панели. Фрагмент кода представлен ниже:

// создание панели

RibbonPanel rp1 = new RibbonPanel();

// помещаем контейнер в панель

rp1.Source = rbs1;

Последнее, нужно создать вкладку, поместить в нее панель. А вкладку поместить в ленту. Пример кода представлен ниже:

// создаем вкладку

RibbonTab rt = new RibbonTab();

// присваиваем айди

rt.Id = "rtable";

// задаем заголовок

rt.Title = "Плагин";

// добавляем на вкладку панель

rt.Panels.Add(rp1);

// переменная обеспечивающая связь с лентой

RibbonControl rc = ComponentManager.Ribbon;

// добавляем на ленту вкладку

rc.Tabs.Add(rt);

Рис 2. Внешний дизайн плагина

Следующей частью будет создание обработчика кнопок. Каждый обработчик открывают windows форму. Пример создания обработчика для первой кнопки:

public class CH_rb1 : ICommand {

public event EventHandler CanExecuteChanged;

public bool CanExecute(object param)

{ return true; }

public void Execute(object parameter) {

// открытие формы авторизации

Authorization author = new Authorization();

Application.ShowModalDialog(author);}

Строка подключения к БД будет хранится в отдельном файле Settings.xml, который находиться рядом с dll-файлом плагина. В любой windows формы плагина будет метод, который считывает строку и подключается к БД. Пример кода представлен ниже:

private void LoadDbConn() {

string name = "";

// объект хмл документа

XmlDocument xDoc = new XmlDocument();

// читаем файл с настройками

xDoc.Load("Settings.xml");

// ищем нужную строку, читаем атрибут, присваиваем к переменной

foreach (XmlNode node in xDoc.DocumentElement) {

name = node.Attributes[0].Value; }

conn = new SqlConnection(name);

// открываем подключение

conn.Open(); }

Так же во время открытия любой из форм, будет проверяется подключение к БД. Пример кода представлен ниже:

private void TestDbConn() {

string name = "";

// объект хмл документа

XmlDocument xDoc = new XmlDocument();

// читаем файл с настройками

xDoc.Load("Settings.xml");

// ищем нужную строку, читаем атрибут, присваиваем к переменной

foreach (XmlNode node in xDoc.DocumentElement) {

name = node.Attributes[0].Value; }

// создаем подключение

conn = new SqlConnection(name);

try {

// открываем

conn.Open(); }

catch {

// иначе открываем форму настройки подключения к бд

SettingDB dB = new SettingDB();

dB.ShowDialog(); }}

В случае неудачи установления соединения с БД, отобразится форма настройки подключения (рис. 3).

Рис 3. Форма настройки подключения к БД

В зависимости от выбора проверки подключения скроются/покажутся дополнительные настройки.

Фрагмент кода формирования строки подключения для windows проверки представлен ниже:

if (txt_ds.Text != "" && txt_ic.Text != "") {

// собираем данные и присваиваем переменной строки подключения

conn = "Data Source=" + txt_ds.Text + ";Initial Catalog=" + txt_ic.Text + ";Integrated Security=True"; }

Фрагмент кода записи строки подключения в файл:

// объект хмл-документа

XmlDocument xDoc = new XmlDocument();

// читаем файл с настройками

xDoc.Load("Settings.xml");

// получим корневой элемент

XmlElement xRoot = xDoc.DocumentElement;

// получаем первый дочерний узел

XmlNode firstNode = xRoot.FirstChild;

// удаляем дочерний узел

xRoot.RemoveChild(firstNode);

// сохраняем хмл документ

xDoc.Save("Settings.xml");

// создаем новый узел

XmlElement userElem = xDoc.CreateElement("connectionString");

// создаем атрибут

XmlAttribute nameAttr = xDoc.CreateAttribute("name");

// создаем текстовые значения для элементов и атрибута

XmlText nameText = xDoc.CreateTextNode(conn);

//добавляем узлы

nameAttr.AppendChild(nameText);

userElem.Attributes.Append(nameAttr);

xRoot.AppendChild(userElem);

// сохраняем хмл документ

xDoc.Save("Settings.xml");

В плагине будет форма авторизации (рис. 4).

Рис 4. Форма авторизации

Рис 5. Успешная авторизация

В БД хранятся учетные записи пользователей. Помимо логина и пароля, у учетной записи есть поле места работы. По нему плагин и будет решать авторизовать пользователя или нет. Фрагмент кода авторизации представлен ниже:

// если текстовые поля не пустые

if (txt_log.Text != "" && txt_pass.Text != "") {

// переменная места работы

string factory = "";

// запрос о пользователи в системе

SqlCommand cmd = new SqlCommand("SELECT MUser FROM Users WHERE Ulogin=@Ulogin AND Upassword=@Upassword", conn);

cmd.Parameters.AddWithValue("Ulogin", txt_log.Text);

cmd.Parameters.AddWithValue("Upassword", txt_pass.Text);

try {

sqlReader = await cmd.ExecuteReaderAsync();

while (await sqlReader.ReadAsync()) {

// присваиваем результат

factory = Convert.ToString(sqlReader["MUser"]); }}

Форма предусматривает скачку чертежа. Для этого достаточно выбрать запись и нажать кнопку «открыть чертеж». Фрагмент кода представлен ниже:

// если выбрана запись

if (lv_data.SelectedItems.Count > 0) {

string path = "";

string id = Convert.ToString(lv_data.SelectedItems[0].SubItems[0].Text);

if (count == 1) {

// создаем коллекцию

List<Draw_obj> cherteg = new List<Draw_obj>();

// запрос о чертеже и его названии

SqlCommand cmd4 = new SqlCommand("SELECT OName, ODrawing FROM Object WHERE OName=@Oname", conn);

cmd4.Parameters.AddWithValue("Oname", id);

try {

sqlReader = await cmd4.ExecuteReaderAsync();

while (await sqlReader.ReadAsync()){

string filename = sqlReader.GetString(0);

byte[] data = (byte[])sqlReader.GetValue(1);

// формируем объект коллекции из результата

Draw_obj drawfile = new Draw_obj(filename, data);

// помещаем объект в коллецию

cherteg.Add(drawfile); }

if (cherteg.Count > 0) {

// создаем файл

using (FileStream fs = new FileStream("E:\\MyPlagin\\Originaldraw\\" + cherteg[0].OName + ".dwg", FileMode.OpenOrCreate)) {

fs.Write(cherteg[0].ODrawing, 0, cherteg[0].ODrawing.Length); }

path = "E:\\MyPlagin\\Originaldraw\\" + cherteg[0].OName + ".dwg";}}

Плагин сможет осуществить детализацию чертежа. Для этого достаточно выделить объект на чертеже и нажать кнопку «копировать». Отобразиться форма выбора ГОСТ рамки (рис. 6).

Рис 6. Форма выбора рамки

После выбора создастся новый чертеж и на него скопируется объект. Фрагмент кода работы копирования объектов:

// ссылка на открытый документ в автокаде

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

// ссылка на базу данных открытого документа в автокаде

Database acCurDb = acDoc.Database;

// ссылка на редактор открытого документа в автокаде

Editor acEd = acDoc.Editor;

// создание коллекции для объектов чертежа

ObjectIdCollection acObjIdColl = new ObjectIdCollection();

// блокируем чертеж

using (DocumentLock acLckDocCur = acDoc.LockDocument()) {

// создаем транзакция для выполнения операций

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) {

// пользовательский выбор объектов чертежа

PromptSelectionResult acSSPrompt = acEd.GetSelection();

// если статус запроса равен ОК

if (acSSPrompt.Status == PromptStatus.OK) {

// выбираем объекты

SelectionSet acSSet = acSSPrompt.Value;

// перебор объектов в наборе

foreach (SelectedObject acSSObj in acSSet) {

// если объект получен правильно

if (acSSObj != null) {

// открываем объект для записи

Entity acEnt = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForWrite) as Entity;

// если объект открылся

if (acEnt != null) {

// помещаем в коллекцию

acObjIdColl.Add(acEnt.ObjectId); }}}}

// фиксируем изменения

acTrans.Commit(); }}

Фрагмент кода выбора шаблона для чертежа:

// переменная пути к шаблону

string strTemplatePath = "";

// если пользователь выбрал шаблон без рамки

if (rb_1.Checked == true) {

// грузим стандартный шаблон

strTemplatePath = "acad.dwt"; }

Фрагмент кода копирования объекта на новый чертеж:

// создаем чертеж

Document acNewDoc = acDocMgr.Add(strTemplatePath);

// получаем его базу данных

Database acDbNewDoc = acNewDoc.Database;

// переменная хранящая имя чертежа

string strDWGName = acNewDoc.Name;

// объект, который запрашивает названия чертежа

object obj = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("DWGTITLED");

// блокируем документ

using (DocumentLock acLckDoc = acNewDoc.LockDocument()) {

// открываем транзакцию для операций

using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction()) {

// открываем таблицу блоков для чтения

BlockTable acBlkTblNewDoc;

acBlkTblNewDoc = acTrans.GetObject(acDbNewDoc.BlockTableId, OpenMode.ForRead) as BlockTable;

// открытие записи таблицы блоков для внесения изменений

BlockTableRecord acBlkTblRecNewDoc;

acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

// копируем коллекцию с объектами в базу данных нового чертежа

IdMapping acIdMap = new IdMapping();

acCurDb.WblockCloneObjects(acObjIdColl, acBlkTblRecNewDoc.ObjectId, acIdMap, DuplicateRecordCloning.Ignore, false);

// фиксируем изменения

acTrans.Commit(); }}

В плагине будут предусмотрены две формы сохранения чертежа в БД. Первая форма для сотрудников конструкторского бюро (рис. 7). С помощью нее можно сохранить составную часть чертежа. Вторая форма для технологов цехов (рис. 8). С помощью этой формы можно сохранить результат детализации.

Рис 7. Форма для сотрудников КБ

Рис 8. Форма для технологов

Фрагмент кода для сохранения чертежа в БД для сотрудников конструкторского бюро:

// поиск файла чертежа

foreach (string file in Directory.GetFiles(path, "*.dwg")){

// создаем объект найденого файла

FileInfo fileInf = new FileInfo(file);

// присваиваем переменной название файла

string tempnamedraw = fileInf.Name;

// присваиваем переменной полный путь к файлу

string filename = path + tempnamedraw;

// создаем объект активного документа в автокаде

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

// закрываем активный документ

acDoc.CloseAndSave(filename);

// создаем поток байтов

byte[] fileData;

// получаем файл чертежа

using (FileStream fs = new FileStream(filename, FileMode.Open)) {

// преобразуем и записываем поток байтов

fileData = new byte[fs.Length];

fs.Read(fileData, 0, fileData.Length); }

// запрос о добавление детали в бд

SqlCommand cmd = new SqlCommand("INSERT INTO SplittingDraw (SDUOName, SDOName, SDDrawing, SDMName) VALUES (@SDUOName, @SDOName, @SDDrawing, @SDMName)", conn);

// собираем информацию

cmd.Parameters.AddWithValue("SDUOName", cb_unitobj.Text);

cmd.Parameters.AddWithValue("SDOName", cb_obj.Text);

cmd.Parameters.AddWithValue("SDDrawing", fileData);

cmd.Parameters.AddWithValue("SDMName", cb_fctr.Text);

try {

await cmd.ExecuteNonQueryAsync();

Последняя форма для просмотра деталей в системе (рис. 9). Она позволит найти или отсортировать нужные детали. В отличии от форм авторизации эта форма сможет не только скачивать чертежи, но и добавлять дополнительную информацию на чертеж в виде таблицы. Дополнительную информацию тоже можно отредактировать (рис. 10).

Рис 8. Форма просмотра деталей в БД

Рис 9. Всплывающая форма добавления дополнительной информации

Фрагмент кода сортировки по материалу:

// очищаем листвью

lv_data.Items.Clear();

// сортировка по конкретному материалу

SqlCommand cmd5 = new SqlCommand("SELECT * FROM Details WHERE DeMaterial=@DeMaterial", conn);

cmd5.Parameters.AddWithValue("DeMaterial",cb_mat.SelectedItem.ToString());

sqlReader = await cmd5.ExecuteReaderAsync();

Фрагмент кода запроса о количестве записей дополнительной информации у чертежа:

// если пользователь поставил галку загрузку доп. инфу

if (cb_othinf.Checked == true) {

int rows = 0;

// запрос о кол-ве записей

SqlCommand cmd9 = new SqlCommand("SELECT COUNT(*) FROM DetailsAddInfo WHERE IdDetal=@IdDetal", conn);

cmd9.Parameters.AddWithValue("IdDetal", id);

sqlReader = await cmd9.ExecuteReaderAsync();

while (await sqlReader.ReadAsync()) {

// присваиваем результат

rows = sqlReader.GetInt32(0); }

Фрагмент кода загрузки дополнительной информации из БД:

// создаем массив

string[] dopinfo = new string[rows];

// запрос о записей доп.инфы.

SqlCommand cmd10 = new SqlCommand("SELECT DAIName FROM DetailsAddInfo WHERE IdDetal=@IdDetal", conn);

cmd10.Parameters.AddWithValue("IdDetal", id);

sqlReader = await cmd10.ExecuteReaderAsync();

int i = 0;

// помещаем результат запроса в массив

while (await sqlReader.ReadAsync()) {

dopinfo[i] = Convert.ToString(sqlReader["DAIName"]);

i++; }

Фрагмент кода переноса информации из массива в таблицу:

// создаем таблицу

Autodesk.AutoCAD.DatabaseServices.Table acTb = new Autodesk.AutoCAD.DatabaseServices.Table();

// стиль таблицы

acTb.TableStyle = acCurDb.Tablestyle;

// кол-во строк в таблице

acTb.NumRows = rows;

// кол-во столбцов в таблице

acTb.NumColumns = 1;

// высота и ширина ячеек

acTb.SetRowHeight(30);

acTb.SetColumnWidth(150);

// размер текста

acTb.SetTextHeight(5, (int)RowType.TitleRow);

acTb.SetTextHeight(5, (int)RowType.HeaderRow);

acTb.SetTextHeight(5, (int)RowType.DataRow);

// цикл записи информации из массива в таблицу

for (int k = 0; k < rows; k++) {

acTb.Cells[k, 0].TextString = dopinfo[k].ToString(); }

Получившуюся таблицу (рис. 11) на чертеже можно двигать, изменять размеры, форматировать стиль.

Рис 11. Получившаяся таблица с дополнительной информации на чертеже

Подведем итоги. Результатом второй главы стало дерево папок (рис. 12). Рассмотрим подробнее:

  • Originaldraw – папка. в которую скачиваются чертежи из БД;

  • Plagin – папка, в которой находится сам файл плагина и его файл с настройками (рис. 13);

  • Tempdraw – папка, в которой хранится временный чертеж, ждущий сохранения в БД;

  • Template – последняя папка, в ней хранятся шаблоны ГОСТ рамок;

Рис 12. Структура папок проекта

Рис 13. Файл плагина с файлом настроек

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]