diff --git a/.gitignore b/.gitignore
index a8bc238..83b8011 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@
################################################################################
/ExternalModuleExample/Properties
+/ExternalModuleExample/obj/Debug
+/ExternalModuleExample/.vs/ExternalModuleExample/v14
diff --git a/ExternalModuleExample/App.config b/ExternalModuleExample/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/ExternalModuleExample/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExternalModuleExample/ExternalModuleExample.csproj b/ExternalModuleExample/ExternalModuleExample.csproj
new file mode 100644
index 0000000..d59a7c3
--- /dev/null
+++ b/ExternalModuleExample/ExternalModuleExample.csproj
@@ -0,0 +1,123 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8052604A-F1E4-48D9-AEBA-21E70547B383}
+ Library
+ Properties
+ ExternalModuleExample
+ ExternalModuleExample
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ ..\..\..\..\..\..\Program Files\LERS\Common\Plugins\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+ False
+ ..\..\..\..\..\..\Program Files\LERS\Common\Framework\bin\Lers.Plugins.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\Program Files\LERS\Common\Framework\bin\Lers.Plugins.Attributes.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\Program Files\LERS\Common\Framework\bin\Lers.Reports.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\Program Files\LERS\Common\Framework\bin\Lers.System.dll
+ False
+
+
+ False
+ ..\..\..\..\..\..\Program Files\LERS\Common\Framework\bin\Lers.UI.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ MainForm.cs
+
+
+
+
+
+ MainForm.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExternalModuleExample/ExternalModuleExample.csproj.user b/ExternalModuleExample/ExternalModuleExample.csproj.user
new file mode 100644
index 0000000..d50832d
--- /dev/null
+++ b/ExternalModuleExample/ExternalModuleExample.csproj.user
@@ -0,0 +1,7 @@
+
+
+
+ Program
+ C:\Program Files\LERS\Client\Lers.Client.exe
+
+
\ No newline at end of file
diff --git a/ExternalModuleExample/ExternalModuleExample.sln b/ExternalModuleExample/ExternalModuleExample.sln
new file mode 100644
index 0000000..241f14a
--- /dev/null
+++ b/ExternalModuleExample/ExternalModuleExample.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExternalModuleExample", "ExternalModuleExample.csproj", "{8052604A-F1E4-48D9-AEBA-21E70547B383}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8052604A-F1E4-48D9-AEBA-21E70547B383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8052604A-F1E4-48D9-AEBA-21E70547B383}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8052604A-F1E4-48D9-AEBA-21E70547B383}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8052604A-F1E4-48D9-AEBA-21E70547B383}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ExternalModuleExample/MainForm.Designer.cs b/ExternalModuleExample/MainForm.Designer.cs
new file mode 100644
index 0000000..ded7acd
--- /dev/null
+++ b/ExternalModuleExample/MainForm.Designer.cs
@@ -0,0 +1,84 @@
+namespace ExternalModuleExample
+{
+ partial class MainForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.MainView = new System.Windows.Forms.DataGridView();
+ this.MeasurePointName = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.MeasurePointType = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ ((System.ComponentModel.ISupportInitialize)(this.MainView)).BeginInit();
+ this.SuspendLayout();
+ //
+ // MainView
+ //
+ this.MainView.AllowUserToAddRows = false;
+ this.MainView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.MainView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.MainView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+ this.MeasurePointName,
+ this.MeasurePointType});
+ this.MainView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
+ this.MainView.Location = new System.Drawing.Point(12, 12);
+ this.MainView.Name = "MainView";
+ this.MainView.Size = new System.Drawing.Size(765, 376);
+ this.MainView.TabIndex = 0;
+ //
+ // MeasurePointName
+ //
+ this.MeasurePointName.HeaderText = "Название точки учёта";
+ this.MeasurePointName.Name = "MeasurePointName";
+ this.MeasurePointName.ToolTipText = "MeasurePointName";
+ //
+ // MeasurePointType
+ //
+ this.MeasurePointType.HeaderText = "Тип точки учёта";
+ this.MeasurePointType.Name = "MeasurePointType";
+ this.MeasurePointType.ToolTipText = "MeasurePointType";
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(789, 400);
+ this.Controls.Add(this.MainView);
+ this.Name = "MainForm";
+ this.Text = "MainForm";
+ ((System.ComponentModel.ISupportInitialize)(this.MainView)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.DataGridView MainView;
+ private System.Windows.Forms.DataGridViewTextBoxColumn MeasurePointName;
+ private System.Windows.Forms.DataGridViewTextBoxColumn MeasurePointType;
+ }
+}
\ No newline at end of file
diff --git a/ExternalModuleExample/MainForm.cs b/ExternalModuleExample/MainForm.cs
new file mode 100644
index 0000000..ccb98eb
--- /dev/null
+++ b/ExternalModuleExample/MainForm.cs
@@ -0,0 +1,94 @@
+using Lers.Core;
+using Lers.Plugins;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ExternalModuleExample
+{
+ ///
+ /// Класс экранной формы
+ ///
+ public partial class MainForm : Form
+ {
+ ///
+ /// Экземпляр хост-интерфейса клиента
+ ///
+ IPluginHost host;
+
+ public MainForm()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Инициализация формы
+ ///
+ ///
+ internal void Initialize(IPluginHost host)
+ {
+ // Сохраняем хост-интерфейса клиента себе в программу
+ this.host = host;
+
+ // Получам список точек учёта от сервера
+ MeasurePoint[] measurePointList = host.Server.MeasurePoints.GetList();
+
+ // Если список точек учёта не пуст
+ if (measurePointList != null)
+ {
+ // Проходим по всему списку
+ foreach (MeasurePoint measurePoint in measurePointList)
+ {
+ string measurePointType = "";
+
+ // Смотрим тип точки учёта и в соответствии со значением присваиваем название
+ switch (measurePoint.SystemType)
+ {
+ case SystemType.ColdWater:
+ measurePointType = "Холодное водоснабжение"; break;
+
+ case SystemType.Electricity:
+ measurePointType = "Электричество"; break;
+
+ case SystemType.Gas:
+ measurePointType = "Газоснабдение"; break;
+
+ case SystemType.Heat:
+ measurePointType = "Теплоснабжение"; break;
+
+ case SystemType.HotWater:
+ measurePointType = "Горячее водоснабжение"; break;
+
+ case SystemType.None:
+ measurePointType = "Нет типа"; break;
+
+ case SystemType.Steam:
+ measurePointType = "Пароснабжение"; break;
+
+ default:
+ measurePointType = "Не удалось получить тип"; break;
+ }
+
+ // Добавляем запись в таболицу MainView
+ MainView.Rows.Add(measurePoint.FullTitle, measurePointType);
+ }
+
+ // Ставим авто-ширину столбцов в такой режим, что суммарная ширина всех столбцов
+ // в точности заполняет отображаемую область MainView
+ MainView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
+ }
+
+ else
+ // Если список точек учёта пуст, выводим сообщение
+ MessageBox.Show("Список точек учёта пуст",
+ "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ }
+
+ }
+}
diff --git a/ExternalModuleExample/MainForm.resx b/ExternalModuleExample/MainForm.resx
new file mode 100644
index 0000000..21195f8
--- /dev/null
+++ b/ExternalModuleExample/MainForm.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ True
+
+
\ No newline at end of file
diff --git a/ExternalModuleExample/Plugin.cs b/ExternalModuleExample/Plugin.cs
new file mode 100644
index 0000000..c3e4f75
--- /dev/null
+++ b/ExternalModuleExample/Plugin.cs
@@ -0,0 +1,123 @@
+using Lers.Plugins;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ExternalModuleExample
+{
+ ///
+ /// Класс, реализующий интерфейс IPlugin
+ ///
+ public class Plugin : IPlugin
+ {
+ ///
+ /// Экземпляр хост-интерфейса клиента
+ ///
+ internal static IPluginHost Host { get; private set; }
+
+ ///
+ /// Список открытых окон
+ ///
+ private List visibleForms = new List();
+
+ ///
+ /// Метод, вызывающийся во время запуска клиента
+ ///
+ ///
+ public void Initialize(IPluginHost pluginHost)
+ {
+ // Копируем экземпляр хост-интерфейса клиента в нашу программу
+ Host = pluginHost;
+
+ // Ищем меню Сервис.
+ foreach (var item in Host.MainWindow.MainMenu.Items)
+ {
+ if (item.ID == (int)Lers.UI.SystemMenuId.Service)
+ {
+ // Добавляем подпункт в пункт главного меню Сервис.
+ item.AddItem("Пример внешнего модуля", Properties.Resources.Icon, true, OnItemClick);
+ }
+ }
+ }
+
+ ///
+ /// Событие выбора приложения в меню Сервис
+ ///
+ ///
+ ///
+ private void OnItemClick(object sender, EventArgs e)
+ {
+ // Проверим, открыто ли такое окно
+ MainForm currentForm = GetOpenedForm();
+
+ // Если такого окна нет, то открываем новое
+ if (currentForm == null)
+ NewForm();
+
+ //Такое окно есть, переводим фокус на него
+ else
+ {
+ currentForm.Show();
+ currentForm.Focus();
+ }
+ }
+
+ ///
+ /// Возвращает открытую форму или null если формы нет
+ ///
+ ///
+ private MainForm GetOpenedForm()
+ {
+ lock (this.visibleForms)
+ {
+ foreach (MainForm form in this.visibleForms)
+ {
+ return form;
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Открываем новое окно
+ ///
+ private void NewForm()
+ {
+ // Создаём новый экземпляр формы
+ MainForm mainForm = new MainForm() { Text = "Пример внешнего модуля" };
+
+ // Инициализируем форму
+ mainForm.Initialize(Host);
+
+ // Добавляем форму в список окон в программе
+ Host.MainWindow.AddPage(mainForm);
+
+ // Открываем форму
+ mainForm.Show();
+
+ // Добавляем событие на закрытие формы
+ mainForm.FormClosed += new System.Windows.Forms.FormClosedEventHandler(currentForm_FormClosed);
+
+ lock (this.visibleForms)
+ {
+ this.visibleForms.Add(mainForm);
+ }
+ }
+
+ ///
+ /// Закрыто окно. Удаляем его из списка открытых окон.
+ ///
+ ///
+ ///
+ void currentForm_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
+ {
+ lock (this.visibleForms)
+ {
+ this.visibleForms.Remove((MainForm)sender);
+ }
+ }
+ }
+}
diff --git a/ExternalModuleExample/Program.cs b/ExternalModuleExample/Program.cs
new file mode 100644
index 0000000..9f4f8d1
--- /dev/null
+++ b/ExternalModuleExample/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ExternalModuleExample
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+ }
+}
diff --git a/ExternalModuleExample/Resources/Icon.png b/ExternalModuleExample/Resources/Icon.png
new file mode 100644
index 0000000..908497f
Binary files /dev/null and b/ExternalModuleExample/Resources/Icon.png differ