ISyncEvent.cs
using System;
using System.Runtime.InteropServices;
namespace V7ExtSample.AddInLib
{
[Guid("ab634004-f13d-11d0-a459-004095e1daea"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAsyncEvent
{
void SetEventBufferDepth(int lDepth);
void GetEventBufferDepth(ref int plDepth);
void ExternalEvent(string bstrSource, string bstrMessage, string bstrData);
void CleanBuffer();
}
}
IErrorLog.cs
using System;
using System.Runtime.InteropServices;
namespace V7ExtSample.AddInLib
{
[Guid("3127CA40-446E-11CE-8135-00AA004BB851"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IErrorLog
{
void AddError(string pszPropName, ExcepInfo pExepInfo);
}
//----------------------------------------------------------
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=8)]
public struct ExcepInfo
{
public short wCode;
public short wReserved;
[MarshalAs(UnmanagedType.BStr)] public string bstrSource;
[MarshalAs(UnmanagedType.BStr)] public string bstrDescription;
[MarshalAs(UnmanagedType.BStr)] public string bstrHelpFile;
public int dwHelpContext;
public System.IntPtr pvReserved;
public System.IntPtr pfnDereffered;
public int scode;
}
}
IInitDone.cs
using System;
using System.Runtime.InteropServices;
namespace V7ExtSample.AddInLib
{
[Guid("AB634001-F13D-11d0-A459-004095E1DAEA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitDone
{
void Init([MarshalAs(UnmanagedType.IDispatch)] object pConnection);
void Done();
void GetInfo(ref object pInfo);
}
}
ILanguageExtender.cs
using System;
using System.Runtime.InteropServices;
namespace V7ExtSample.AddInLib
{
[Guid("AB634003-F13D-11d0-A459-004095E1DAEA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ILanguageExtender
{
void RegisterExtensionAs(ref string bstrExtensionName);
void GetNProps(ref int plProps);
void FindProp(string bstrPropName, ref int plPropNum);
void GetPropName(int lPropNum, int lPropAlias, ref string pbstrPropName);
void GetPropVal(int lPropNum, ref object pvarPropVal);
void SetPropVal(int lPropNum, ref object varPropVal);
void IsPropReadable(int lPropNum, ref bool pboolPropRead);
void IsPropWritable(int lPropNum, ref bool pboolPropWrite);
void GetNMethods(ref int plMethods);
void FindMethod(string bstrMethodName, ref int plMethodNum);
void GetMethodName(int lMethodNum, int lMethodAlias, ref string pbstrMethodName);
void GetNParams(int lMethodNum, ref int plParams);
void GetParamDefValue(int lMethodNum, int lParamNum, ref object pvarParamDefValue);
void HasRetVal(int lMethodNum, ref bool pboolRetValue);
void CallAsProc(int lMethodNum, [MarshalAs(UnmanagedType.SafeArray)] ref System.Array paParams);
void CallAsFunc(int lMethodNum, ref object pvarRetValue, [MarshalAs(UnmanagedType.SafeArray)] ref System.Array paParam);
}
}
IStatusLine.cs
using System;
using System.Runtime.InteropServices;
namespace V7ExtSample.AddInLib
{
[Guid("ab634005-f13d-11d0-a459-004095e1daea"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStatusLine
{
void SetStatusLine(string bstrStatusLine);
void ResetStatusLine();
}
}
COMError.cs
class COMError
{
public const uint E_UNEXPECTED = 0x8000FFFF;
public const uint E_POINTER = 0x80004003;
public const uint E_FAIL = 0x80004005;
public const uint S_FALSE = 1;
public const uint S_OK = 0;
}
V7Data.cs
using System;
namespace V7ExtSample
{
internal class V7Data
{
public static object V7Object
{
get
{
return m_V7Object;
}
set
{
m_V7Object = value;
// Вызываем неявно QueryInterface
m_ErrorInfo = (AddInLib.IErrorLog)value;
m_AsyncEvent = (AddInLib.IAsyncEvent)value;
m_StatusLine = (AddInLib.IStatusLine)value;
}
}
public static AddInLib.IErrorLog ErrorLog
{
get
{
return m_ErrorInfo;
}
}
public static AddInLib.IAsyncEvent AsyncEvent
{
get
{
return m_AsyncEvent;
}
}
public static AddInLib.IStatusLine StatusLine
{
get
{
return m_StatusLine;
}
}
private static object m_V7Object;
private static AddInLib.IErrorLog m_ErrorInfo;
private static AddInLib.IAsyncEvent m_AsyncEvent;
private static AddInLib.IStatusLine m_StatusLine;
}
}
WinAPI.cs
using System;
using System.Runtime.InteropServices;
class WinAPI {
public const int SW_HIDE=0;
[DllImport("User32.dll", EntryPoint="SetParent")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
}
NetComponentSample.cs
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace V7ExtSample
{
[ComVisible(true), Guid("0339E962-6744-4844-9408-1A795828CCBF"), ProgId("AddIn.NetComponentSampleCS")]
public class NetComponentSampleCS : AddInLib.IInitDone, AddInLib.ILanguageExtender
{
const string c_AddinName = "NetComponentSampleCS";
#region "Переменные"
string strMessageBoxIcon;
string strMessageBoxButtons;
#endregion
public NetComponentSampleCS()
{
}
#region "IInitDone implementation"
public void Init([MarshalAs(UnmanagedType.IDispatch)] object pConnection)
{
V7Data.V7Object = pConnection;
this.strMessageBoxButtons = "OK";
this.strMessageBoxIcon = "None";
}
public void Done()
{
//MessageBox.Show("*Done", "", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
public void GetInfo(ref object pInfo)
{
((System.Array)pInfo).SetValue("2000", 0);
}
#endregion
public void RegisterExtensionAs(ref string bstrExtensionName)
{
bstrExtensionName = c_AddinName;
}
#region "Свойства"
enum Props
{ //Числовые идентификаторы свойств нашей внешней компоненты
propMessageBoxIcon = 0, //Пиктограмма для MessageBox'а
propMessageBoxButtons = 1, //Кнопки для MessageBox'a
LastProp = 2
}
public void GetNProps(ref int plProps)
{ //Здесь 1С получает количество доступных из ВК свойств
plProps = (int)Props.LastProp;
}
public void FindProp(string bstrPropName, ref int plPropNum)
{ //Здесь 1С ищет числовой идентификатор свойства по его текстовому имени
switch(bstrPropName)
{
case "MessageBoxIcon":
case "ПиктограммаПредупреждения":
plPropNum = (int)Props.propMessageBoxIcon;
break;
case "MessageBoxButtons":
case "КнопкиПредупреждения":
plPropNum = (int)Props.propMessageBoxButtons;
break;
default:
plPropNum = -1;
break;
}
}
public void GetPropName(int lPropNum, int lPropAlias, ref string pbstrPropName)
{ //Здесь 1С (теоретически) узнает имя свойства по его идентификатору. lPropAlias - номер псевдонима
pbstrPropName = "";
}
public void GetPropVal(int lPropNum, ref object pvarPropVal)
{ //Здесь 1С узнает значения свойств
pvarPropVal = null;
switch(lPropNum)
{
case (int)Props.propMessageBoxIcon:
pvarPropVal = strMessageBoxIcon;
break;
case (int)Props.propMessageBoxButtons:
pvarPropVal = strMessageBoxButtons;
break;
}
}
public void SetPropVal(int lPropNum, ref object varPropVal)
{ //Здесь 1С изменяет значения свойств
switch(lPropNum)
{
case (int)Props.propMessageBoxIcon:
strMessageBoxIcon = (string)varPropVal;
break;
case (int)Props.propMessageBoxButtons:
strMessageBoxButtons = (string)varPropVal;
break;
}
}
public void IsPropReadable(int lPropNum, ref bool pboolPropRead)
{ //Здесь 1С узнает, какие свойства доступны для чтения
pboolPropRead = true; // Все свойства доступны для чтения
}
public void IsPropWritable(int lPropNum, ref bool pboolPropWrite)
{ //Здесь 1С узнает, какие свойства доступны для записи
pboolPropWrite = true; // Все свойства доступны для записи
}
#endregion
#region "Методы"
enum Methods
{ //Числовые идентификаторы методов (процедур или функций) нашей внешней компоненты
methMessageBoxShow = 0, //Предупреждение, но с возможностью задавать пиктограмму и заголовок окна
methExternalEvent = 1, //Генерирует внешнее событие (1С перехватывает его в процедуре ОбработкаВнешнегоСобытия())
methShowErrorLog = 2, //Показываем ошибочное сообщение
methStatusLine = 3, //Показываем сообщение в строке состояния
methSoundGood = 4,
LastMethod = 5,
}
public void GetNMethods(ref int plMethods)
{ //Здесь 1С получает количество доступных из ВК методов
plMethods = (int)Methods.LastMethod;
}
public void FindMethod(string bstrMethodName, ref int plMethodNum)
{ //Здесь 1С получает числовой идентификатор метода (процедуры или функции) по имени (названию) процедуры или функции
plMethodNum = -1;
switch(bstrMethodName)
{
case "MessageBoxShow":
case "Предупреждение":
plMethodNum = (int)Methods.methMessageBoxShow;
break;
case "ExternalEvent":
case "ВнешнееСобытие":
plMethodNum = (int)Methods.methExternalEvent;
break;
case "ShowErrorLog":
case "Сообщить":
plMethodNum = (int)Methods.methShowErrorLog;
break;
case "StatusLine":
case"Состояние":
plMethodNum = (int)Methods.methStatusLine;
break;
case "SoundGood":
plMethodNum = (int)Methods.methSoundGood;
break;
}
}
public void GetMethodName(int lMethodNum, int lMethodAlias, ref string pbstrMethodName)
{ //Здесь 1С (теоретически) получает имя метода по его идентификатору. lMethodAlias - номер синонима.
pbstrMethodName = "";
}
public void GetNParams(int lMethodNum, ref int plParams)
{ //Здесь 1С получает количество параметров у метода (процедуры или функции)
switch(lMethodNum)
{
case (int)Methods.methMessageBoxShow:
plParams = 2;
break;
case (int)Methods.methExternalEvent:
plParams = 3;
break;
case (int)Methods.methShowErrorLog:
plParams = 1;
break;
case (int)Methods.methStatusLine:
plParams = 1;
break;
case (int)Methods.methSoundGood:
plParams = 0;
break;
}
}
public void GetParamDefValue(int lMethodNum, int lParamNum, ref object pvarParamDefValue)
{ //Здесь 1С получает значения параметров процедуры или функции по умолчанию
pvarParamDefValue = null; //Нет значений по умолчанию
}
public void HasRetVal(int lMethodNum, ref bool pboolRetValue)
{ //Здесь 1С узнает, возвращает ли метод значение (т.е. является процедурой или функцией)
pboolRetValue = true; //Все методы у нас будут функциями (т.е. будут возвращать значение).
}
public void CallAsProc(int lMethodNum, ref System.Array paParams)
{ //Здесь внешняя компонента выполняет код процедур. А процедур у нас нет.
}
public void CallAsFunc(int lMethodNum, ref object pvarRetValue, ref System.Array paParams)
{ //Здесь внешняя компонента выполняет код функций.
MessageBoxIcon icon;
pvarRetValue = 0; //Возвращаемое значение метода для 1С
switch(lMethodNum) //Порядковый номер метода
{
case (int)Methods.methSoundGood:
{
MessageBox.Show("Заработало");
break;
}
case (int)Methods.methMessageBoxShow: //Реализуем метод MessageBoxShow внешней компоненты
{
icon = MessageBoxIcon.None;
//Преобразовываем текстовое описание значка в MessageBoxIcon.ххх
switch(strMessageBoxIcon)
{
case "Asterisk":
icon = MessageBoxIcon.Asterisk;
break;
case "Error":
icon = MessageBoxIcon.Error;
break;
case "Exclamation":
icon = MessageBoxIcon.Exclamation;
break;
case "Hand":
icon = MessageBoxIcon.Hand;
break;
case "Information":
icon = MessageBoxIcon.Information;
break;
case "None":
icon = MessageBoxIcon.None;
break;
case "Question":
icon = MessageBoxIcon.Question;
break;
case "Stop":
icon = MessageBoxIcon.Stop;
break;
case "Warning":
icon = MessageBoxIcon.Warning;
break;
}
//Преобразовываем текстовое описание кнопок в MessageBoxButtons.ххх
MessageBoxButtons butt = MessageBoxButtons.OK;
switch(strMessageBoxButtons)
{
case "AbortRetryIgnore":
butt = MessageBoxButtons.AbortRetryIgnore;
break;
case "OK":
butt = MessageBoxButtons.OK;
break;
case "OKCancel":
butt = MessageBoxButtons.OKCancel;
break;
case "RetryCancel":
butt = MessageBoxButtons.RetryCancel;
break;
case "YesNo":
butt = MessageBoxButtons.YesNo;
break;
case "YesNoCancel":
butt = MessageBoxButtons.YesNoCancel;
break;
}
DialogResult res;
string strMessageBoxText;
string strMessageBoxHeader;
string strDialogResult;
strMessageBoxText = (string)paParams.GetValue(0); //Получаем первый параметр нашей функции - текст предупреждения
strMessageBoxHeader = (string)paParams.GetValue(1);//Получаем второй параметр нашей функции - заголовок предупреждения
//Показываем диалоговое окно MessageBox.Show
res = MessageBox.Show(strMessageBoxText, strMessageBoxHeader, butt, icon);
//Преобразовываем результат из DialogResult.ххх в текстовую строку
switch(res)
{
case DialogResult.Abort:
strDialogResult = "Abort";
break;
case DialogResult.Cancel:
strDialogResult = "Cancel";
break;
case DialogResult.Ignore:
strDialogResult = "Ignore";
break;
case DialogResult.No:
strDialogResult = "No";
break;
case DialogResult.None:
strDialogResult = "None";
break;
case DialogResult.OK:
strDialogResult = "OK";
break;
case DialogResult.Retry:
strDialogResult = "Retry";
break;
case DialogResult.Yes:
strDialogResult = "Yes";
break;
default:
strDialogResult = "";
break;
}
pvarRetValue = strDialogResult; //Возвращаемое значение
//Сбрасываем все свойства в исходное состояние
strMessageBoxButtons = "OK";
strMessageBoxIcon = "None";
break;
} // конец метода MessageBosIcon
//////////////////////////////////////////////////////////
case (int)Methods.methExternalEvent: //Реализуем метод для генерации внешнего события
{
string s1;
string s2;
string s3;
s1 = (string)paParams.GetValue(0);
s2 = (string)paParams.GetValue(1);
s3 = (string)paParams.GetValue(2);
V7Data.AsyncEvent.ExternalEvent(s1, s2, s3);
break;
} // конец метода ExternalEvent
//////////////////////////////////////////////////////////
case (int)Methods.methShowErrorLog: //Реализуем метод для показа сообщения об ошибке
{
string s1;
s1 = (string)paParams.GetValue(0);
AddInLib.ExcepInfo ei = new AddInLib.ExcepInfo();
ei.wCode = 1006; //Вид пиктограммы
ei.bstrDescription = s1;
ei.bstrSource = c_AddinName;
V7Data.ErrorLog.AddError("", ei);
throw new System.Exception("An exception has occurred.");
break;
} // конец метода ShowErrorLog
//////////////////////////////////////////////////////////
case (int)Methods.methStatusLine: //Реализуем тестовый метод для изменения строки состояния
{
string s1;
s1 = (string)paParams.GetValue(0);
V7Data.StatusLine.SetStatusLine(s1);
System.Threading.Thread.Sleep(1000); //Делаем паузу 1 сек
V7Data.StatusLine.ResetStatusLine();
break;
}
}
}
#endregion
}
}