//Пример вызова (в отладчике, табло или своем коде)
// ВнешниеОбработки.Создать("T:\Информатор_82.epf").Изучить(Новый ТаблицаЗначений)
// для исследования глобального контекста следующий вызов
// ВнешниеОбработки.Создать("T:\Информатор_82.epf").Изучить(Неопределено)
//
// Экспортные методы
// булево = Изучить(Объект) - показ формы обработки с данными объекта
// таблицаЗначений = ПолучитьТаблицуМетодов(Объект)
// таблицаЗначений = ПолучитьТаблицуСвойств(Объект)
// булево = МетодСуществует(Объект, наименованиеМетода)
// булево = СвойствоСуществует(Объект, наименованиеСвойства)
Перем СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ Экспорт;
Перем СТРОКА_МЕТОДЫ Экспорт;
Перем СТРОКА_СВОЙСТВА Экспорт;
Перем СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ; // Экспорт;
Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ; // Экспорт;
Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ;
Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ;
Перем ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА;
Перем ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ;
Перем ИМЯ_КЛАССА_DynamicWrapperX;
Перем ScrptCtrl;
Перем Wrap;
Перем ТЗ;
Перем buf;
Перем ppv;
Перем WshShell; // Экспорт;
Перем ФайлРегистратораКомпонент; // Экспорт;
Перем ИсполнительСкрытыхКомандСистемы;
Перем ПапкаВнешнихКомпонент; // Экспорт;
Перем Флаг;
Функция Версия() Экспорт
Возврат "1.12";
КонецФункции
#Если Клиент Тогда
// основной метод для внешнего использования, например, в отладчике
// если Объект = неопределено, то исследуется глобальный контекст
Функция Изучить(Объект, Модально = Ложь) Экспорт
форма = ЭтотОбъект.ПолучитьФорму(,, Новый УникальныйИдентификатор);
ИсследоватьОбъект(Объект);
форма.УстановитьЗаголовокПоОбъекту(Объект);
//форма.СпрятатьКолонкиВЗависимостиОтОбъекта(Объект);
Если Модально Тогда
форма.ОткрытьМодально();
Иначе
форма.Открыть();
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ПолучитьТаблицуСвойств(Объект) Экспорт
Если НЕ ТипДоступенДляИсследования(Объект) Тогда
ВызватьИсключение "Объект недоступен для изучения";
КонецЕсли;
ИсследоватьОбъект(Объект, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА);
резТаблица = Новый ТаблицаЗначений;
резТаблица.Колонки.Добавить("Наименование");
резТаблица.Колонки.Добавить("Тип");
резТаблица.Колонки.Добавить("Значение");
резТаблица.Колонки.Добавить("Индекс");
резТаблица.Колонки.Добавить("ИндексКонтекста");
новСтрока = ДЗ.Строки[0];
Для каждого строка Из новСтрока.Строки Цикл
НоваяСтрока = резТаблица.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, строка);
НоваяСтрока.Значение = строка.Объект;
//НоваяСтрока.Наименование = строка.Наименование;
//НоваяСтрока.Индекс = строка.Индекс;
КонецЦикла;
Возврат резТаблица;
КонецФункции
Функция ПолучитьТаблицуМетодов(Объект) Экспорт
Если НЕ ТипДоступенДляИсследования(Объект) Тогда
ВызватьИсключение "Объект недоступен для изучения";
КонецЕсли;
ИсследоватьОбъект(Объект, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ);
резТаблица = Новый ТаблицаЗначений;
резТаблица.Колонки.Добавить("Наименование");
резТаблица.Колонки.Добавить("КоличествоПараметров");
резТаблица.Колонки.Добавить("ЕстьВозвращаемоеЗначение");
//резТаблица.Колонки.Добавить("Тип");
//резТаблица.Колонки.Добавить("Значение");
резТаблица.Колонки.Добавить("Индекс");
резТаблица.Колонки.Добавить("ИндексКонтекста");
новСтрока = ДЗ.Строки[0];
Для каждого строка Из новСтрока.Строки Цикл
НоваяСтрока = резТаблица.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, строка);
//НоваяСтрока.Наименование = строка.Наименование;
//НоваяСтрока.Значение = строка.Объект;
//НоваяСтрока.КоличествоПараметров = строка.КоличествоПараметров;
//НоваяСтрока.ЕстьВозвращаемоеЗначение = строка.ЕстьВозвращаемоеЗначение = Истина;
//НоваяСтрока.Индекс = строка.ИндексМетодаСвойства;
КонецЦикла;
Возврат резТаблица;
КонецФункции
Функция СвойствоСуществует(Объект, наименованиеСвойства) Экспорт
таблица = ПолучитьТаблицуСвойств(Объект);
строка = таблица.Найти(наименованиеСвойства, "Наименование");
Возврат строка <> Неопределено;
КонецФункции
Функция МетодСуществует(Объект, наименованиеМетода) Экспорт
таблица = ПолучитьТаблицуМетодов(Объект);
строка = таблица.Найти(наименованиеМетода, "Наименование");
Возврат строка <> Неопределено;
КонецФункции
// вызывается из формы обработки
Процедура ИсследоватьОбъект(Объект, парамФлагЗаполнения = Неопределено ) Экспорт
Если Объект = Неопределено Тогда // глобальный контекст
//Если ЭтоПлатформа_81() Тогда
// ВызватьИсключение "Изучение глобального контекста для платформы 8.1 пока не реализовано!";
//КонецЕсли;
Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ;
//ElsIf Объект = ЭтотОбъект.ПолучитьФорму() Then
// Возврат;
КонецЕсли;
Перехват();
Очистить(ДЗ.Строки);
ДЗ.Строки.Очистить();
новСтрока = ДЗ.Строки.Добавить();
новСтрока.Наименование = "Значение";
новСтрока.Тип = ТипЗнч(Объект);
новСтрока.Значение = Объект;
новСтрока.Объект = Объект;
Если парамФлагЗаполнения = Неопределено Тогда
парамФлагЗаполнения = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ;
КонецЕсли;
ЗаполнитьСубДерево(Объект, новСтрока, парамФлагЗаполнения); //0
КонецПроцедуры
Функция Инит() //Экспорт
ПапкаВнешнихКомпонент = Новый Файл(КаталогВременныхФайлов());
WshShell = Новый COMОбъект("WScript.Shell");
Wrap = "НеИнициализирован";
Wrap = ПолучитьWinAPI();
ДЗ.Колонки.Добавить("Наименование");
ДЗ.Колонки.Добавить("Тип");
ДЗ.Колонки.Добавить("Значение");
ДЗ.Колонки.Добавить("Объект");
ДЗ.Колонки.Добавить("УжеЗаполняли");
ДЗ.Колонки.Добавить("ЕстьВозвращаемоеЗначение");
ДЗ.Колонки.Добавить("КоличествоПараметров");
ДЗ.Колонки.Добавить("ИндексКонтекста");
ДЗ.Колонки.Добавить("Индекс"); //ИндексМетодаСвойства");
КонецФункции
Процедура Перехват() //Экспорт
If ТипЗнч(ScrptCtrl) <> Тип("Неопределено") Then
Возврат;
EndIf;
ТекстМодуля = Public_Consts();
ТекстМодуля = ТекстМодуля + Public_Vars();
ТекстМодуля = ТекстМодуля + Class_Service();
ТекстМодуля = ТекстМодуля + Funcs();
ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language = "vbscript";
Попытка
ScrptCtrl.AddCode(ТекстМодуля);
Исключение
Сообщить(ScrptCtrl.Error.Description);
Сообщить(ScrptCtrl.Error.Source);
Сообщить(ScrptCtrl.Error.Text);
Сообщить(ScrptCtrl.Error.Line);
КонецПопытки;
buf = ScrptCtrl.Eval("oServ.buf");
ppv = ScrptCtrl.Eval("oServ.ppv");
Wrap.RegisterAddr(buf, "ImplBase_call", "i=pllp", "r=l"); //ID 20
КонецПроцедуры
Функция ЭтоПлатформа_81()
Перем локальная;
этоПлатформа_81 = Истина;
Попытка
Выполнить("локальная = Метаданные.РежимСовместимости");
этоПлатформа_81 = Ложь;
Исключение
КонецПопытки;
Возврат этоПлатформа_81;
КонецФункции
Функция Public_Consts()
ТекстМодуля = "
|Public Const S_OK = &h0
|Public Const E_NOINTERFACE = &h80004002
//|Public Const E_UNEXPECTED = &h8000FFFF
|Public Const CP_ACP = &h0
|
|Public Const HEAP_ZERO_MEMORY = &h00000008
|Public Const PAGE_EXECUTE_READWRITE = &h40
|
|Public Const VT_BSTR = &h8
|Public Const VT_DISPATCH = &h9
|
|'IID Интерфейсов
|Public Const IID_IContextExtImpBase = ""{FD7B6CC2-DC8E-11D2-B8D0-008048DA0335}""
|Public Const IID_IValueImplBase = ""{FD7B6CC3-DC8E-11D2-B8D0-008048DA0335}""
|Public Const IID_GC = ""{F7399BD5-100E-4D0A-A5CE-F97810ACFEE9}""
|
|Public Const bsl_off_13 = &h119E7AF0
|Public Const bsl_off_14 = &h11A299F0
|
|Public Const platform_offset = &h18
|";
Возврат ТекстМодуля;
КонецФункции
Функция Public_Vars()
ТекстМодуля = "
|Public oServ
|
|Public Wrap
|Public curVers 'Версия 8.2
|
|Set Wrap = CreateObject("""+ИМЯ_КЛАССА_DynamicWrapperX+""")
|";
//|Set Wrap = CreateObject(""DynamicWrapperX"")
Возврат ТекстМодуля;
КонецФункции
Функция Class_Service()
ТекстМодуля = "
//{ |Class Service
|Class Service
//{ |Vars
| Private hHeap
| Public buf 'Буфер для вызова функций
| Private buf_thiscall 'Буфер для вызова функций
|
| Private res 'Память для результата VirtualProtect
| Private pGC 'Глоб.объект
| Public ppv
| Private pIID
| Private swIID
| Private handle
|
| Public numGK 'Кол-во ГК контекстов
| Public pArray 'Массив ГК
|
| 'Для передачи параметров
| Public paramArr2 'Для печати
| Public paramArr9 'Для вызова функций
|
| Private pMes 'Контекст, с методом /Сообщить/
| Private numMes 'Номер метода /Сообщить/
|
| Private adrValue_str 'адрес ф-и __thiscall core::Value::Value(wchar_t const *)
| Private adrValue_void 'адрес ф-и __thiscall core::Value::Value(void)
//} |
//{ |Release
| Private Function Release(pObj)
| vfunc pObj, (3 - 1) * 4
| res = Wrap.IUnknown_Release(pObj)
| End Function
//} |
//{ |FindCG_Message
| Private Function FindCG_Message()
| FindCG_Message = -1
|
| 'Найдем контекст, в котором есть метод ""Сообщить""
| j = 0
| PutString(""Сообщить"")
| Do While j < numGK + 1
| pIContext = Wrap.NumGet(pArray, j * 4)
|
| vfunc pIContext, 4 * (16 - 1)
| numMes = Wrap.ImplBase_findMethod(pIContext, ppv)
| If numMes =>0 Then
| FindCG_Message = pIContext
| Exit Do
| End If
| j = j + 1
| Loop
| '=======================================================
| End Function
//} |
//{ |GetArrayGC
| Private Function GetArrayGC()
| IIDFromString IID_GC
|
| 'ГО (1)
| vfunc pGC, (15 - 1) * 4
| pObj1 = Wrap.GetObjectFromIID(pGC, pIID)
|
| 'ГО (2)
| vfunc pObj1, (13 - 1) * 4
| res = Wrap.GetObj(pObj1, ppv)
| pObj2 = Wrap.NumGet(ppv)
|
| Select Case curVers
| Case 13
| numfunc = 68
| Case 14
| numfunc = 69
| Case 15
| numfunc = 70
| Case Else
| numfunc = 70
| End Select
|
| 'ГО (3)
| vfunc pObj2, (numfunc - 1) * 4
| res1 = Wrap.GetObj(pObj2, ppv)
| pObj3 = Wrap.NumGet(ppv)
|
| 'Массив
| GetArrayGC = Wrap.NumGet(pObj3, &h10)
|
| 'Количество
| numGK = (Wrap.NumGet(pObj3, &h14) - GetArrayGC) / 4
| numGK = numGK - 1
|
| Release pObj3
| Release pObj2
| Release pObj1
| Release pGC
| End Function
//} |
//{ |Class_Initialize
| Private Sub Class_Initialize
| Wrap.Register ""Kernel32"", ""HeapAlloc"", ""i=lll"", ""r=l""
| Wrap.Register ""Kernel32"", ""GetProcessHeap"", ""r=l""
| Wrap.Register ""Kernel32"", ""HeapFree"", ""i=lll"",""r=l""
| Wrap.Register ""Kernel32"", ""VirtualProtect"" , ""i=lllp"", ""r=l""
| Wrap.Register ""Kernel32"", ""LoadLibrary"" , ""i=s"", ""r=h""
| Wrap.Register ""Kernel32"", ""GetProcAddress"" , ""i=hs"", ""r=u""
| Wrap.Register ""Kernel32"", ""MultiByteToWideChar"", ""i=llslpl"", ""r=l""
| Wrap.Register ""Ole32"" , ""IIDFromString"", ""i=pp"", ""r=l""
| Wrap.Register ""Version"", ""GetFileVersionInfoSize"", ""i=sl"", ""r=l""
| Wrap.Register ""Version"", ""GetFileVersionInfo"", ""i=sllp"", ""r=l""
| Wrap.Register ""Version"", ""VerQueryValue"", ""i=pspp"", ""r=l""
|
| hHeap = Wrap.GetProcessHeap()
| curVers = GetVersion()
|
| numGK = 0
| code_len = 10
|
| buf_thiscall= Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, code_len)
| ppv = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, &h20) 'Под внутр. нужды и строки
| pIID = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 32)
| swIID = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 100)
|
| paramArr2 = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 16 * 2 + 4 * (2 + 1) + 4 * 3) 'На 2 параметра
| paramArr9 = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 16 * 9 + 4 * (9 + 1) + 4 * 3) 'На 9 параметров
| '=======================================================
| 'Буфер для вызова функций интерфейса
| Wrap.VirtualProtect buf_thiscall, code_len, PAGE_EXECUTE_READWRITE, ppv
|
| Wrap.NumPut &hB9, buf_thiscall, 0, ""b"" 'mov ecx, .... pObj
|
| buf = buf_thiscall + 5
| Wrap.NumPut &hE9, buf, 0, ""b"" 'jmp ...Addr
| '=======================================================
| 'IUnknown
| Wrap.RegisterAddr buf, ""IUnknown_QueryInterface"", ""i=ppp"", ""r=l"" 'ID 1
| Wrap.RegisterAddr buf, ""IUnknown_AddRef"", ""i=p"", ""r=l"" 'ID 2
| Wrap.RegisterAddr buf, ""IUnknown_Release"", ""i=p"", ""r=l"" 'ID 3
|
| 'IContextExtImplBase
| Wrap.RegisterAddr buf , ""ImplBase_getName"", ""i=pll"", ""r=l"" 'ID getPropName - 5, getMethodName - 10
| Wrap.RegisterAddr buf , ""ImplBase_getN"", ""i=p"", ""r=l"" 'ID getNProps - 4, getNMethods - 9
| Wrap.RegisterAddr buf , ""ImplBase_getNParams"", ""i=pl"", ""r=l"" 'ID 11
| Wrap.RegisterAddr buf , ""ImplBase_hasRetVal"", ""i=pl"", ""r=l"" 'ID 15
| Wrap.RegisterAddr buf , ""ImplBase_findMethod"", ""i=pp"", ""r=l"" 'ID 16
| Wrap.RegisterAddr buf , ""ImplBase_getParamDefValue"", ""i=pllp"", ""r=l"" 'ID 14
| Wrap.RegisterAddr buf , ""ImplBase_call"", ""i=pllp"", ""r=l"" 'ID 20
| Wrap.RegisterAddr buf_thiscall, ""ImplBase_call_thiscall"", ""i=pllp"", ""r=l"" 'ID 20
|
| 'IValue
| Wrap.RegisterAddr buf_thiscall, ""setIValue"", ""i=p"", ""r=l"" 'ID 1
| Wrap.RegisterAddr buf_thiscall, ""getIValue"", ""i=p"", ""r=l"" 'ID 2
| Wrap.RegisterAddr buf_thiscall, ""type0"", ""i=p"", ""r=l"" 'ID 7
|
| 'ObjectTypeCore
| Wrap.RegisterAddr buf, ""getTypeCode"", ""i=p"", ""r=l"" 'ID 4
| '=======================================================
| handle = Wrap.LoadLibrary(""core82"")
| 'Функция возвращает ГК
| Addr1 = Wrap.GetProcAddress(handle, ""?current_process@core@@YAPAVSCOM_Process@1@XZ"")
|
| Wrap.RegisterAddr Addr1, ""current_process"", ""r=l"" 'core::current_process(void)
|
| 'Вот это Глобальный Контекст
| pGC = Wrap.current_process()
| '=======================================================
| 'CurProc
| 'Функция из ВТ объекта pGC
| 'возвращает какой-то глобальный объект (1)
| 'в ВТ (1) есть ф-я, возвращающая другой ГО (2)
| 'в ВТ (2) есть ф-я, возвращающая другой ГО (3)
| '(3) - содержит массив ГК IContextExtImplBase
|
| Wrap.RegisterAddr buf, ""GetObjectFromIID"", ""i=pp"", ""r=l"" 'ID 15
|
| 'Функция, получения объектов
| Wrap.RegisterAddr buf, ""GetObj"", ""i=pp"", ""r=p""
|
| 'Получим указатель на глоб. массив ГК
| pArray = GetArrayGC()
|
| 'Для вывода сообщений
| pMes = FindCG_Message()
| '=======================================================
|
| adrValue_str = Wrap.GetProcAddress(handle, ""??0Value@core@@QAE@PB_W@Z"") '__thiscall core::Value::Value(wchar_t const *)
| Wrap.RegisterAddr buf_thiscall, ""Value_str"", ""i=p"", ""r=l""
|
| adrValue_void = Wrap.GetProcAddress(handle, ""??0Value@core@@QAE@XZ"") '__thiscall core::Value::Value(void)
| Wrap.RegisterAddr buf_thiscall, ""Value_void"", ""r=l""
|
| 'Обертка 1C-х объектов в IDispatch
| Addr1 = Wrap.GetProcAddress(handle, ""?value_to_dispatch@core@@YA?AV?$InterfacePtr@UIDispatch@@@1@PAVIValue@1@PAVSCOM_ProcessData@1@@Z"")
| Wrap.RegisterAddr Addr1, ""value_to_dispatch"", ""i=ppl"", ""r=l""
|
| PrepareParams paramArr2, 2
| PrepareParams paramArr9, 9
| End Sub
//} |
//{ |Class_Terminate
| Private Sub Class_Terminate
| Wrap.HeapFree hHeap, 0, buf_thiscall
| Wrap.HeapFree hHeap, 0, ppv
| Wrap.HeapFree hHeap, 0, pIID
| Wrap.HeapFree hHeap, 0, swIID
|
| Wrap.HeapFree hHeap, 0, paramArr2
| Wrap.HeapFree hHeap, 0, paramArr9
|
| Set Wrap = Nothing
//| MsgBox ""Class_Terminate2""
| End Sub
//} |
//{ |GetString
| Private Function GetString(offset)
| ppv1 = ppv + offset
| ln = Wrap.NumGet(ppv1)
| If ln > 15 Then
| GetString = Wrap.StrGet(Wrap.NumGet(ppv1, 4) + 8)
| Else
| GetString = Wrap.StrGet(ppv1 + 4)
| End If
| End Function
//} |
//{ |PutString
| Private Function PutString(txt)
| 'Формируем структуру строки
| ln = Len(txt)
| If ln > 15 Then
| Wrap.NumPut 16, ppv, 0 'Флаг, что строка длиннее 15 символов
| Wrap.NumPut (ppv + 16), ppv, 4 'Указатель на начало строки
| Wrap.NumPut (ppv + 24) + ln * 2, ppv, 8 'Указатель на 0, за концом строки
| Wrap.NumPut 1, ppv, 12 'Не знаю, что это
|
| Wrap.NumPut 1, ppv, 16 'Это счетчик ссылок на строку
| Wrap.NumPut 1, ppv, 20 'Не знаю, что это
| res = Wrap.MultiByteToWideChar(CP_ACP, 0, txt, -1, ppv + 24, ln)
| Wrap.NumPut 0, ppv, 24 + ln * 2
| Else
| Wrap.NumPut ln, ppv, 0
| res = Wrap.MultiByteToWideChar(CP_ACP, 0, txt, -1, ppv + 4, ln)
| End If
| End Function
//} |
//{ |GetVersion
| Private Function GetVersion()
| sz = Wrap.GetFileVersionInfoSize(""core82"", 0)
|
| pbuf = Wrap.HeapAlloc(hHeap, 0, sz)
| lplpBuffer = Wrap.HeapAlloc(hHeap, 0, 4)
| puLen = Wrap.HeapAlloc(hHeap, 0, 4)
|
| res1 = Wrap.GetFileVersionInfo(""core82"",0, sz, pbuf)
| res1 = Wrap.VerQueryValue(pbuf, ""\"", lplpBuffer, puLen)
|
| VS_FIXEDFILEINFO = Wrap.NumGet(lplpBuffer)
| 'Младшая часть версии
| lpart = Wrap.NumGet(VS_FIXEDFILEINFO, &h0C, ""t"")
| 'Старшая часть версии
| hpart = Wrap.NumGet(VS_FIXEDFILEINFO, &h0E, ""t"")
|
//| GetVersion = CSTR(hpart) & ""."" & CSTR(lpart)
| GetVersion = hpart
|
| Wrap.HeapFree hHeap, 0, pbuf
| Wrap.HeapFree hHeap, 0, lplpBuffer
| Wrap.HeapFree hHeap, 0, puLen
| End Function
//} |
//{ |IIDFromString
| Private Function IIDFromString(sIDD)
| IIDFromString = Wrap.MultiByteToWideChar(CP_ACP, 0, sIDD, -1, swIID, 100)
| IIDFromString = Wrap.IIDFromString(swIID, pIID)
| End Function
//} |
//{ |QueryInterface
| Private Function QueryInterface(pObj, sIDD)
| QueryInterface = E_NOINTERFACE
| If IIDFromString(sIDD) = S_OK Then
| vfunc pObj, &h0
| QueryInterface = Wrap.IUnknown_QueryInterface(pObj, pIID, ppv)
| End If
| End Function
//} |
//{ |GetInterface
| Public Function GetInterface(pObj, sIID)
| GetInterface = QueryInterface(pObj, sIID)
| If GetInterface = S_OK Then
| GetInterface = Wrap.NumGet(ppv)
| End If
| End Function
//} |
//{ |vfunc
| Public Sub vfunc(pObj, offset)
| Addr = Wrap.NumGet(Wrap.NumGet(pObj), offset)
| Wrap.NumPut Addr - (buf + 1 + 4), buf, 1
| End Sub
//} |
//{ |this_call
| Public Sub this_call(ECX, Addr)
| Wrap.NumPut ECX, buf_thiscall,1
| Wrap.NumPut Addr - (buf + 1 + 4),buf, 1
| End Sub
//} |
//{ |SetParamsCount
| Private Function SetParamsCount(pParams, num, cnt)
| 'Указатели на начало и конец массива указателей на параметры
|
| 'Указатель на начало массива указателей на параметры
| Wrap.NumPut (pParams + num * 16), pParams, num * 16 + (num + 1) * 4
|
| 'Указатель на конец массива указателей на параметры
| Wrap.NumPut (pParams + num * 16 + cnt * 4), pParams, num * 16 + (num + 1) * 4 + 4
| Wrap.NumPut (pParams + num * 16 + cnt * 4), pParams, num * 16 + (num + 1) * 4 + 8
| End Function
//} |
//{ |PrepareParams
| Private Function PrepareParams(pParams, num)
| 'Подготовим параметры, 16 байт на параметр
| bsl_off = bsl_off_13
| If Left(curVers, 2) > ""13"" Then
| bsl_off = bsl_off_14
| End If
|
| For j = 0 To num - 1
| Wrap.NumPut bsl_off, pParams, j * 16
| Next
|
| 'Указатели на параметры
| For j = 0 To num - 1
| Wrap.NumPut (pParams + j * 16), pParams, num * 16 + j * 4
| Next
|
| 'Установим по-умолчанию 2 параметра
| SetParamsCount pParams, num, 2
| End Function
//} |
//{ |SetParam
| Private Function SetParam(pParams, num, paramType, paramValue, paramValueType)
| Wrap.NumPut paramType, pParams, (num - 1) * 16 + 4
| Wrap.NumPut paramValue, pParams, (num - 1) * 16 + 8
| Wrap.NumPut paramValueType, pParams, (num - 1) * 16 + 12
| End Function
//} |
//{ |GetParam
| Private Function GetParam(pParams, num)
| GetParam = Wrap.NumGet(pParams, 8 + num * 16)
| End Function
//} |
//{ |getParamList
| Public Function getParamList(pParams, num)
| getParamList = pParams + num * 16 + (num + 1) * 4
| End Function
//} |
//{ |getType
| Public Function getType(pIValue)
| Addr = Wrap.NumGet(Wrap.NumGet(pIValue), (7 - 1) * 4)
| this_call pIValue, Addr
| res = Wrap.type0(ppv + 8)
|
| pObjTypeCore = Wrap.NumGet(ppv + 8)
| vfunc pObjTypeCore, (4 - 1) * 4
| getType = Wrap.getTypeCode(pObjTypeCore)
//| MsgBox getType
| End Function
//} |
//{ |getIValue
| Private Function getIValue(pValue)
| Addr = Wrap.NumGet(Wrap.NumGet(pValue), (2 - 1) * 4)
|
| this_call pValue, Addr
| res = Wrap.getIValue(ppv + 8)
| getIValue = Wrap.NumGet(ppv + 8)
| End Function
//} |
//{ |setIValue
| Private Function setIValue(pIValue, pValue)
| Addr = Wrap.NumGet(Wrap.NumGet(pIValue), (1 - 1) * 4)
|
| this_call pIValue, Addr
| setIValue = Wrap.setIValue(pValue)
| End Function
//} |
//{ |Message
| Public Function Message(txt)
| '1-й параметр, строка
| '=======================================================
| this_call ppv, adrValue_str
| res = Wrap.Value_str(txt)
| IValue = getIValue(ppv)
| res = SetParam (paramArr2, 1, 0, IValue, 4)
|
| '2-й параметр, перечисление
| '=======================================================
| this_call ppv, adrValue_void
| res = Wrap.Value_void()
|
| vfunc pMes, 4 * (14 - 1)
| res = Wrap.ImplBase_getParamDefValue(pMes, numMes, 1, ppv)
| IValue = getIValue(ppv)
| res = SetParam(paramArr2, 2, 0, IValue, 0)
|
| SetParamsCount paramArr2, 2, 2
| '=======================================================
| vtable = Wrap.NumGet(pMes)
| Addr = Wrap.NumGet(vtable, 4 * (20 - 1))
|
| this_call numMes, Addr
| Wrap.ImplBase_call_thiscall pMes, numMes, 0, getParamList(paramArr2, 2)
| End Function
//} |
//{ |PrepereDefParams
|Public Function PrepareDefParams(pIContext, numFunc)
| PrepareDefParams = -1
|
| vfunc pIContext, 4 * (11 - 1)
| NParams = Wrap.ImplBase_getNParams(pIContext, numFunc)
|
| If (NParams = 0) OR (NParams > 9) Then
| Exit Function
| End If
|
| j = 0
| Do While j < NParams
| this_call ppv, adrValue_void
| res = Wrap.Value_void()
|
| vfunc pIContext, 4 * (14 - 1)
| res = Wrap.ImplBase_getParamDefValue(pIContext, numFunc, j, ppv)
| If res <> S_OK Then
| PrepareDefParams = -1
| Exit Do
| End If
| IValue = getIValue(ppv)
| typeCode = getType(ppv)
| res = SetParam(paramArr9, j + 1, 0, IValue, typeCode)
| j = j + 1
| Loop
| If PrepareDefParams = -1 Then
| Exit Function
| End If
|
| SetParamsCount paramArr9, 9, NParams
|
| this_call ppv, adrValue_void
| res = Wrap.Value_void()
|
| vfunc pIContext, 4 * (20 - 1)
| PrepareDefParams = getParamList(paramArr9, 9)
| End Function
//} |
//{ |RetValueImplBase
| Public Function RetValueImplBase()
| pCont = getIValue(ppv)
| pValueImplBase = GetInterface(pCont, IID_IValueImplBase)
|
| res = Wrap.value_to_dispatch(ppv, pValueImplBase, 0)
| pDisp = Wrap.NumGet(ppv)
|
| 'Уменьшим счетчик ссылок (незаконно - не через Release), иначе повиснет ссылка и 1С не закроется
| res = Wrap.NumGet(pDisp, 8)
| res = Wrap.NumPut(res - 1, pDisp, 8)
|
| Set RetValueImplBase = Wrap.GetObject(pDisp)
| End Function
//} |
|End Class
//} |
|Set oServ = New Service
|";
Возврат ТекстМодуля;
КонецФункции
Функция Funcs()
ТекстМодуля = "
//{ |getN
|Public Function getN(pIContext, nfunc)
| getN = 0
| If pIContext <> 0 Then
| oServ.vfunc pIContext, 4 * (nfunc - 1)
| getN = Wrap.ImplBase_getN(pIContext)
| End If
|End Function
//} |
//{ |ImplBase_getN
|Public Function ImplBase_getN(Obj, nfunc)
| ImplBase_getN = 0
| If VarType(Obj) = VT_BSTR Then
| For j = 0 To oServ.numGK
| pIContext = Wrap.NumGet(oServ.pArray, j * 4)
| ImplBase_getN = ImplBase_getN + getN(pIContext, nfunc)
| Next
| Else
| pObj = Wrap.GetIDispatch(Obj)
| pIContext = Wrap.NumGet(pObj, platform_offset)
|
//| If pIContext <> 0 Then
//| oServ.Message Hex(pIContext)
//| oServ.Message Hex(Wrap.NumGet(pIContext))
//| End If
|
| ImplBase_getN = getN(pIContext, nfunc)
| End if
|End Function
//} |
//{ |ImplBase_getName
|Public Function ImplBase_getName(pIContext, num, nfunc)
| ImplBase_getName = 0
| If pIContext <> 0 Then
| j = 1
| Do While j > -1
| oServ.vfunc pIContext, 4 * (nfunc - 1)
| pbstrName = Wrap.ImplBase_getName(pIContext, num, j)
|
| If (pbstrName <> 0) Then
| If Wrap.StrGet(pbstrName) <> """" Then
| ImplBase_getName = pbstrName
| Exit Do
| End If
| End If
| j = j - 1
| Loop
| End If
|End Function
//} |
//{ |valFill
|Public Function valFill(pIContext, num, valTable, nfunc, ContID)
| For j = 0 To num - 1
| pStr = ImplBase_getName(pIContext, j, nfunc)
| If (pStr <> 0) Then
| Set nRow = valTable.Add()
| nRow.Name = Wrap.StrGet(pStr)
|
| oServ.vfunc pIContext, 4 * (15 - 1)
| nRow.Val = Wrap.ImplBase_hasRetVal(pIContext, j)
|
| oServ.vfunc pIContext, 4 * (11 - 1)
| nRow.NParams = Wrap.ImplBase_getNParams(pIContext, j)
| nRow.ID = j
| nRow.ContID = ContID
| End If
| Next
|End Function
//} |
//{ |Fill
|Public Function Fill(Obj, valTable, nfunc)
| Fill = 0
|
| If VarType(Obj) = VT_BSTR Then
| For j = 0 To oServ.numGK
| pIContext = Wrap.NumGet(oServ.pArray, j * 4)
| num = getN(pIContext, nfunc - 1)
| Fill = Fill + num
| valFill pIContext, num, valTable, nfunc, j
| Next
| Else
| pObj = Wrap.GetIDispatch(Obj)
| pIContext = Wrap.NumGet(pObj, platform_offset)
|
| Fill = getN(pIContext, nfunc - 1)
| valFill pIContext, Fill, valTable, nfunc, 0
| End if
|End Function
//} |
//{ |GetContext
|Public Function GetContext(Obj, numCont)
| If VarType(Obj) = VT_BSTR Then
| GetContext = Wrap.NumGet(oServ.pArray, numCont * 4)
| Else
| pObj = Wrap.GetIDispatch(Obj)
| GetContext = Wrap.NumGet(pObj, platform_offset)
| End If
|End Function
//} |
//{ |PrepareDefParams
|Public Function PrepareDefParams(Obj, numFunc, numCont)
| pIContext = GetContext(Obj, numCont)
| PrepareDefParams = oServ.PrepareDefParams(pIContext, numFunc)
|End Function
//} |
//{ |RetValueImplBase
|Public Function RetValueImplBase()
| Set RetValueImplBase = oServ.RetValueImplBase()
|End Function
//} |
|";
Возврат ТекстМодуля;
КонецФункции
Функция ТипДоступенДляИсследования(Объект, Уровень = 0)
Если (Объект = Неопределено) И (Уровень = 0) Тогда // глобальный контекст
Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ;
КонецЕсли;
типОбъект = ТипЗнч(Объект);
Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда
If (типОбъект = Тип("Число"))ИЛИ
(типОбъект = Тип("Строка")) ИЛИ
(типОбъект = Тип("Дата")) ИЛИ
(типОбъект = Тип("Булево")) ИЛИ
(типОбъект = Тип("Неопределено")) ИЛИ
(типОбъект = Тип("ComОбъект")) Then
Возврат Ложь;
EndIf;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ЭтоГлобальныйКонтекст(Объект) Экспорт
Возврат Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ ИЛИ Объект = Неопределено;
КонецФункции
Функция ПолучитьОписание(Объект, ТЗ, Флаг, Уровень)
Рез = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ; //0
Если НЕ ТипДоступенДляИсследования(Объект, Уровень) Тогда Возврат Рез; КонецЕсли;
//типОбъект = ТипЗнч(Объект);
//Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда
// If (типОбъект = Тип("Число"))ИЛИ
// (типОбъект = Тип("Строка")) ИЛИ
// (типОбъект = Тип("Дата")) ИЛИ
// (типОбъект = Тип("Булево")) ИЛИ
// (типОбъект = Тип("Неопределено")) ИЛИ
// (типОбъект = Тип("ComОбъект")) Then
//
// Возврат Рез;
// EndIf;
//КонецЕсли;
If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ Then //0
Рез = ScrptCtrl.Run("ImplBase_getN",Объект, 4);
Рез = Рез + ScrptCtrl.Run("ImplBase_getN", Объект, 9);
//Адр = ScrptCtrl.CodeObject.ImplBase_pIContext(Объект);
//If (Адр <> "0") И (Адр <> "") Then
// Сообщить(""+ Объект + " :" + Адр);
//EndIf;
ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ Then //1
Рез = ScrptCtrl.Run("ImplBase_getN",Объект, 4);
ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ Then //2
Рез = ScrptCtrl.Run("ImplBase_getN", Объект, 9);
Else
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Name");
ТЗ.Колонки.Добавить("Type");
ТЗ.Колонки.Добавить("Val");
ТЗ.Колонки.Добавить("NParams");
ТЗ.Колонки.Добавить("ID");
ТЗ.Колонки.Добавить("ContID");
If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3
ScrptCtrl.Run("Fill", Объект, ТЗ, 5);
Else
ScrptCtrl.Run("Fill", Объект, ТЗ, 10);
EndIf;
//Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда
ТЗ.Сортировать("Name");
//EndIf;
EndIf;
Возврат Рез;
КонецФункции
Процедура ДобавитьВДерево(текСтрока, ТЗ, ТипТЗ, Объект)
Для каждого текСтр Из ТЗ Цикл
новСвойство = текСтрока.Строки.Добавить();
новСвойство.Наименование = текСтр.Name; //новСвойство.Наименование = текСтр.Name + " (" + ?(Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ,"", "" + текСтр.ContID + ",") + текСтр.ID + ")";
//контИД это порядковый номер контекста из массива Глобальных контекстов,
// ИД номер свойства/метода
//контИД = 0 для не ГлК
новСвойство.ИндексКонтекста = ?(Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ, "", "" + текСтр.ContID);
новСвойство.Индекс = текСтр.ID;
текОбъект = "";
If ТипТЗ = СТРОКА_СВОЙСТВА Then
Если Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Тогда
Попытка
текОбъект = Вычислить("Объект."+текСтр.Name);//Объект[текСтр.Name];
Исключение
КонецПопытки;
Иначе
текОбъект = Вычислить(текСтр.Name);
КонецЕсли;
//текОбъект = Вычислить("Объект."+текСтр.Name);//Объект[текСтр.Name];
Значение = Строка(текОбъект);
новСвойство.Тип = ТипЗнч(текОбъект);
Else
If текСтр.Val = 0 Then //Процедура
Значение = "<?>";
новСвойство.КоличествоПараметров = 0;
новСвойство.ЕстьВозвращаемоеЗначение = Ложь;
ElsIf текСтр.NParams > 0 Then
Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ;//"<Функция требует " + Строка(текСтр.NParams) + " парам.>";
новСвойство.КоличествоПараметров = текСтр.NParams;
новСвойство.ЕстьВозвращаемоеЗначение = Истина; //1;
Else
Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ;
новСвойство.КоличествоПараметров = 0;
новСвойство.ЕстьВозвращаемоеЗначение = Истина; //1;
EndIf;
EndIf;
новСвойство.Значение = Значение;
новСвойство.Объект = текОбъект;
ЗаполнитьСубДерево(текОбъект, новСвойство, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ); //0);
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьСубДерево(Объект, текСтрока, Флаг) Экспорт
Перем ТЗ;
Рез = ПолучитьОписание(Объект, ТЗ, Флаг, текСтрока.Уровень());
If Флаг < ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3
If Рез > 0 Then
новСтрока = текСтрока.Строки.Добавить();
If (Флаг > ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ) Then //0
новСтрока.Наименование = ?(Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ, СТРОКА_СВОЙСТВА, СТРОКА_МЕТОДЫ); //1
новСтрока.Объект = новСтрока.Наименование;
новСтрока.Строки.Добавить();
EndIf;
EndIf;
ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3
ДобавитьВДерево(текСтрока, ТЗ, СТРОКА_СВОЙСТВА, Объект);
Else
ДобавитьВДерево(текСтрока, ТЗ, СТРОКА_МЕТОДЫ, Объект);
EndIf;
КонецПроцедуры
Процедура Очистить(НаборСтрок) Экспорт
Для каждого текСтр Из НаборСтрок Цикл
текСтр.Объект = 0;
текСтр.Значение = 0;
Очистить(текСтр.Строки);
КонецЦикла;
КонецПроцедуры
Процедура ОбработатьСобытие_ДЗ_ПередРазворачиванием(Элемент, Строка, Отказ) Экспорт
//Уже заполняли
If Строка.УжеЗаполняли = Истина Then Возврат; EndIf; //1
Объект = Строка.Объект;
Строка.Строки.Очистить();
If (Объект = СТРОКА_СВОЙСТВА) Then
ЗаполнитьСубДерево(Строка.Родитель.Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА); //3
ElsIf (Объект = СТРОКА_МЕТОДЫ) Then
ЗаполнитьСубДерево(Строка.Родитель.Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ); //4
Else
ЗаполнитьСубДерево(Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ); //1
ЗаполнитьСубДерево(Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ); //2
EndIf;
Строка.УжеЗаполняли = Истина; //1;
КонецПроцедуры
Процедура ОбработатьСобытие_ДЗ_Выбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) Экспорт
//If Колонка.Имя = "Значение" Then
If (ВыбраннаяСтрока.ЕстьВозвращаемоеЗначение = Истина) И (ВыбраннаяСтрока.Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ) Then //1
ВычислитьФункциюВСтроке(ВыбраннаяСтрока);
EndIf;
//EndIf;
КонецПроцедуры
Процедура вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект)
ВыбраннаяСтрока.Тип = ТипЗнч(текОбъект);
ВыбраннаяСтрока.Значение = Строка(текОбъект);
ВыбраннаяСтрока.Объект = текОбъект;
ЗаполнитьСубДерево(текОбъект, ВыбраннаяСтрока, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ); //0
КонецПроцедуры
Процедура ВычислитьФункциюВСтроке(ВыбраннаяСтрока) Экспорт
текОбъект = ВыбраннаяСтрока.Родитель.Родитель.Объект;
param = ScrptCtrl.Run("PrepareDefParams", текОбъект, ВыбраннаяСтрока.Индекс, ВыбраннаяСтрока.индексКонтекста);
If param = -1 Then
Попытка
Если текОбъект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Тогда
текОбъект = Вычислить("текОбъект." + ВыбраннаяСтрока.Наименование + "()");
Иначе
текОбъект = Вычислить(ВыбраннаяСтрока.Наименование + "()");
КонецЕсли;
//текОбъект = Вычислить("текОбъект." + ВыбраннаяСтрока.Наименование + "()");
вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект);
Исключение
Ошибка = ОписаниеОшибки();
Поз = Найти(Ошибка, "Недостаточно фактических параметров");
ВыбраннаяСтрока.Значение = ?(Поз >0, Сред(Ошибка, Поз), Ошибка);
КонецПопытки;
Else
Попытка
pIContext = ScrptCtrl.Run("GetContext", текОбъект, ВыбраннаяСтрока.индексКонтекста);
res = Wrap.ImplBase_call(pIContext, ВыбраннаяСтрока.Индекс, ppv, param);
текОбъект = ScrptCtrl.Run("RetValueImplBase");
вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект);
Исключение
Ошибка = ОписаниеОшибки();
Стр = "Произошла исключительная ситуация:";
Поз = ?(Найти(Ошибка, Стр) >0, Найти(Ошибка, Стр) + СтрДлина(Стр), 1);
ВыбраннаяСтрока.Значение = Сред(Ошибка, Поз);
КонецПопытки;
EndIf;
КонецПроцедуры
#КонецЕсли
// ================================== ================================== ==================================
//
// блок кода из "Инструменты разработчика"
//
// ================================== ================================== ==================================
#Если Клиент Тогда
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьWinAPI() //Экспорт
Если Wrap = "НеИнициализирован" Тогда
Wrap = ПолучитьCOMОбъектИзМакета(ИМЯ_КЛАССА_DynamicWrapperX, ИМЯ_КЛАССА_DynamicWrapperX);
Если Wrap <> Неопределено Тогда
Wrap.Register( "KERNEL32.DLL","Sleep","i=h","f=s");
//Wrap.Register( "KERNEL32.DLL","GetTickCount64","r=l","f=s"); // обычный DynamicWrapper на x86 подключает, а этот - нет
Wrap.Register( "KERNEL32.DLL","GetTickCount","r=l","f=s");
Wrap.Register( "KERNEL32.DLL","GetProcessId","i=l","r=l","f=s");
Wrap.Register( "KERNEL32.DLL","GetCurrentProcessId","r=l","f=s");
Wrap.Register( "WINMM.DLL", "timeGetTime", "r=l", "f=s");
Wrap.Register( "WINMM.DLL", "timeBeginPeriod", "i=l", "r=l", "f=s");
Wrap.Register( "WINMM.DLL", "timeEndPeriod", "i=l", "r=l", "f=s");
Иначе
// Под пользователем ОС без админских прав сразу после установки через regsvr32 /i компонента не создается почему то.
// Нужно перезапускать приложение.
Предупреждение("Установлена новая компонента. Сеанс будет перезапущен", 5);
ПрекратитьРаботуСистемы(Истина);
КонецЕсли;
КонецЕсли;
Возврат Wrap;
КонецФункции // ПолучитьWinAPI()
#КонецЕсли
Функция ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ПолноеИмяDll) //Экспорт
// Сначала пробуем зарегистрировать для HKLM
КоманднаяСтрока = "regsvr32 /s """ + ПолноеИмяDll + """";
//КомандаСистемы(КоманднаяСтрока);
ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина);
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Исключение
КонецПопытки;
Если Компонента <> Неопределено Тогда
Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
КонецЕсли;
// Теперь пробуем зарегистрировать для HKCU
КоманднаяСтрока = "regsvr32 /s /i""" + ПолноеИмяDll + """";
//КомандаСистемы(КоманднаяСтрока);
ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина);
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Исключение
КонецПопытки;
Если Компонента <> Неопределено Тогда
Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
КонецЕсли;
Если ФайлРегистратораКомпонент = Неопределено Тогда
ФайлРегистратораКомпонент = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
ПолучитьМакет("regsvrex").Записать(ФайлРегистратораКомпонент.ПолноеИмя);
КонецЕсли;
// Теперь пробуем зарегистрировать для HKCU через сторонний регистратор
КоманднаяСтрока = """" + ФайлРегистратораКомпонент.ПолноеИмя + """ /c /s """ + ПолноеИмяDll + """";
//КомандаСистемы(КоманднаяСтрока);
ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина);
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Исключение
КонецПопытки;
Если Компонента <> Неопределено Тогда
Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
КонецЕсли;
// Теперь пробуем зарегистрировать для HKCU через сторонний регистратор
КоманднаяСтрока = """" + ФайлРегистратораКомпонент.ПолноеИмя + """ /c /s /i """ + ПолноеИмяDll + """";
//КомандаСистемы(КоманднаяСтрока);
ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина);
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Исключение
КонецПопытки;
Если Компонента <> Неопределено Тогда
Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
КонецЕсли;
Сообщить("Не удалось зарегистривать COM-компоненту " + КлассКомпоненты + ". Возможно требуются права администратора ОС",
СтатусСообщения.Внимание);
Возврат Неопределено;
КонецФункции // ЗарегистрироватьПолучитьCOMОбъект
// Возвращает нужный com-объект. Если компонента не зарегистрирована, то пытается ее сохранить из макета и зарегистрировать.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// COM-объект, Неопределено.
//
Функция ПолучитьCOMОбъектИзМакета(ИмяКомпоненты, КлассКомпоненты, КаталогУстановки = "авто") //Экспорт
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
// -- Артур -- 14.09.2011 - вставка в код ИР
Если КлассКомпоненты = ИМЯ_КЛАССА_DynamicWrapperX Тогда
Попытка
л = Компонента.GetIDispatch(Компонента);
Возврат Компонента;
Исключение
//ВызватьИсключение "Зарегистрирована старая версия COM-объекта DynamicWrapperX";
КонецПопытки;
КонецЕсли;
//Возврат Компонента;
// --завершение
Исключение
КонецПопытки;
#Если Клиент Тогда
Если КаталогУстановки = "" Тогда
Ответ = Вопрос("Для работы данной функции необходимо зарегистрировать
//|(необходимы права локального администратора)
| COM-компоненту """ + ИмяКомпоненты + """. Выполнить регистрацию?",
РежимДиалогаВопрос.ОКОтмена, 30, КодВозвратаДиалога.Отмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Неопределено;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Заголовок = "Укажите папку, куда установить компоненту.";
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
КаталогУстановки = ВыборФайла.Каталог;
ИначеЕсли Нрег(КаталогУстановки) = Нрег("авто") Тогда
КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя;
КонецЕсли;
ФайлКомпоненты = Новый Файл(КаталогУстановки + "\" + ИмяКомпоненты + ".dll");
Если Не ФайлКомпоненты.Существует() Тогда
ПолучитьМакет(ИмяКомпоненты).Записать(ФайлКомпоненты.ПолноеИмя);
КонецЕсли;
Результат = ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ФайлКомпоненты.ПолноеИмя);
#Иначе
Результат = Неопределено;
#КонецЕсли
Возврат Результат;
КонецФункции // ПолучитьCOMОбъектИзМакета()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// ИмяФайлаРезультата – Краткое имя файла, в который будет выведен выходной поток, только в текущем каталоге.
//
Процедура ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(Знач СтрокаЗапуска, ТекущийКаталог = "\.", ИспользоватьWSH = Ложь,
КраткоеИмяФайлаРезультата = "") //Экспорт
#Если Клиент Тогда
// Баг платформы здесь будет работать. Во время работы данной строки окно продолжает принимать команды!
// WSH не использовать при генерации внешних обработок
Если ИспользоватьWSH Тогда
#КонецЕсли
WshShell.CurrentDirectory = ТекущийКаталог;
СтрокаЗапуска = "cmd.exe /c """ + СтрокаЗапуска + """";
Если КраткоеИмяФайлаРезультата <> "" Тогда
СтрокаЗапуска = СтрокаЗапуска + " > " + КраткоеИмяФайлаРезультата;
СтрокаЗапуска = СтрокаЗапуска + " 2>&1"; //stderr
КонецЕсли;
Попытка
WshShell.Run(СтрокаЗапуска, 0, Истина);
Исключение
// Для x64 ОС
СтрокаЗапуска = "%windir%\Sysnative\" + СтрокаЗапуска;
WshShell.Run(СтрокаЗапуска, 0, Истина);
КонецПопытки;
#Если Клиент Тогда
Иначе
ПолучитьИсполнительСкрытыхКомандСистемы();
КонечнаяСтрока = ИсполнительСкрытыхКомандСистемы + " /nowindow /wait /silent /D=""" + ТекущийКаталог + """ " + СтрокаЗапуска;
ЗапуститьПриложение(КонечнаяСтрока, , Истина);
КонецЕсли;
#КонецЕсли
КонецПроцедуры // ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения()
Функция ПолучитьИсполнительСкрытыхКомандСистемы() //Экспорт
Если ИсполнительСкрытыхКомандСистемы = Неопределено Тогда
ДвоичныеДанные = ПолучитьОбщийМакет("hstart");
ИсполнительСкрытыхКомандСистемы = ПолучитьИмяВременногоФайла("exe");
ДвоичныеДанные.Записать(ИсполнительСкрытыхКомандСистемы);
ИсполнительСкрытыхКомандСистемы = """" + ИсполнительСкрытыхКомандСистемы + """";
КонецЕсли;
Возврат ИсполнительСкрытыхКомандСистемы;
КонецФункции
// ================================== ================================== ==================================
//
// окончание блока кода из "Инструменты разработчика"
//
// ================================== ================================== ==================================
#Если Клиент1 Тогда
// основная процедура для юнит-тестирования SnowTest
Функция ПолучитьСписокТестов() Экспорт
Результат = Я_Тест.Новый_НаборТестов();
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуСвойств");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуМетодов");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуСвойств_Глобальный");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуМетодов_Глобальный");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_СвойствоСуществует");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_МетодСуществует");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_СвойствоСуществует_Глобальный");
Я_Тест.НаборТестов_Добавить(Результат, "Тесты_МетодСуществует_Глобальный");
Возврат Результат;
КонецФункции
// ======================= ======================= ======================= =======================
//
// БЛОК ЮНИТ-ТЕСТОВ - сами тесты
//
// ======================= ======================= ======================= =======================
Процедура Тесты_ПолучитьТаблицуСвойств() Экспорт
тестТЗ = Новый ТаблицаЗначений;
тестТЗ.Колонки.Добавить("Колонка1");
НоваяСтрока = тестТЗ.Добавить();
таблицаСвойств = ЭтотОбъект.ПолучитьТаблицуСвойств(тестТЗ);
артТесты.ПроверитьБольшеИлиРавно(таблицаСвойств.Колонки.Количество(), 5, "таблицаСвойств.Колонки.Количество()");
артТесты.ПроверитьРавенство(таблицаСвойств.Количество(), 2, "таблицаСвойств.Количество()");
артТесты.ПроверитьРавенство(таблицаСвойств[0].Наименование, "Индексы", "таблицаСвойств[0].Наименование");
артТесты.ПроверитьРавенство(таблицаСвойств[1].Наименование, "Колонки", "таблицаСвойств[0].Наименование");
КонецПроцедуры
Процедура Тесты_ПолучитьТаблицуМетодов() Экспорт
тестТЗ = Новый ТаблицаЗначений;
тестТЗ.Колонки.Добавить("Колонка1");
НоваяСтрока = тестТЗ.Добавить();
таблица = ЭтотОбъект.ПолучитьТаблицуМетодов(тестТЗ);
артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()");
артТесты.ПроверитьРавенство(таблица.Количество(), 19, "таблица.Количество()");
артТесты.ПроверитьРавенство(таблица[0].Наименование, "Вставить", "таблица[0].Наименование");
артТесты.ПроверитьИстину(таблица[0].ЕстьВозвращаемоеЗначение, "таблица[0].ЕстьВозвращаемоеЗначение");
артТесты.ПроверитьРавенство(таблица[0].КоличествоПараметров, 1, "таблица[0].КоличествоПараметров");
артТесты.ПроверитьРавенство(таблица[18].Наименование, "Удалить", "таблица[Последняя].Наименование");
Если Ложь Тогда
таблица = Новый ТаблицаЗначений;
КонецЕсли;
строка = таблица.Найти("Количество", "Наименование");
артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)");
артТесты.ПроверитьИстину(строка.ЕстьВозвращаемоеЗначение, "строка.ЕстьВозвращаемоеЗначение");
артТесты.ПроверитьРавенство(строка.КоличествоПараметров, 0, "таблица[0].КоличествоПараметров");
КонецПроцедуры
Процедура Тесты_ПолучитьТаблицуСвойств_Глобальный() Экспорт
таблица = ЭтотОбъект.ПолучитьТаблицуСвойств(Неопределено);
артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()");
артТесты.ПроверитьБольшеИлиРавно(таблица.Количество(), 10, "таблица.Количество()");
строка = таблица.Найти("SelectRecordType", "Наименование");
артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)");
//артТесты.ПроверитьРавенство(таблицаСвойств[0].Наименование, "Индексы", "таблицаСвойств[0].Наименование");
//артТесты.ПроверитьРавенство(таблицаСвойств[1].Наименование, "Колонки", "таблицаСвойств[0].Наименование");
КонецПроцедуры
Процедура Тесты_ПолучитьТаблицуМетодов_Глобальный() Экспорт
таблица = ЭтотОбъект.ПолучитьТаблицуМетодов(Неопределено);
артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()");
артТесты.ПроверитьБольшеИлиРавно(таблица.Количество(), 30, "таблица.Количество()");
//артТесты.ПроверитьРавенство(таблица[0].Наименование, "Вставить", "таблица[0].Наименование");
//артТесты.ПроверитьИстину(таблица[0].ЕстьВозвращаемоеЗначение, "таблица[0].ЕстьВозвращаемоеЗначение");
//артТесты.ПроверитьРавенство(таблица[0].КоличествоПараметров, 1, "таблица[0].КоличествоПараметров");
//артТесты.ПроверитьРавенство(таблица[18].Наименование, "Удалить", "таблица[Последняя].Наименование");
Если Ложь Тогда
таблица = Новый ТаблицаЗначений;
КонецЕсли;
строка = таблица.Найти("XMLЗначение", "Наименование");
артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)");
артТесты.ПроверитьИстину(строка.ЕстьВозвращаемоеЗначение, "строка.ЕстьВозвращаемоеЗначение");
артТесты.ПроверитьРавенство(строка.КоличествоПараметров, 2, "таблица[0].КоличествоПараметров");
КонецПроцедуры
Процедура Тесты_СвойствоСуществует() Экспорт
тестТЗ = Новый ТаблицаЗначений;
тестТЗ.Колонки.Добавить("Колонка1");
НоваяСтрока = тестТЗ.Добавить();
существует = ЭтотОбъект.СвойствоСуществует(тестТЗ, "Колонки");
артТесты.ПроверитьИстину(существует, "существует Колонки");
существует = ЭтотОбъект.СвойствоСуществует(тестТЗ, "Колонки1564");
артТесты.ПроверитьЛожь(существует, "существует Колонки1564");
КонецПроцедуры
Процедура Тесты_МетодСуществует() Экспорт
тестТЗ = Новый ТаблицаЗначений;
тестТЗ.Колонки.Добавить("Колонка1");
НоваяСтрока = тестТЗ.Добавить();
существует = ЭтотОбъект.МетодСуществует(тестТЗ, "Количество");
артТесты.ПроверитьИстину(существует, "существует Количество");
существует = ЭтотОбъект.МетодСуществует(тестТЗ, "Количество1564");
артТесты.ПроверитьЛожь(существует, "существует Количество1564");
КонецПроцедуры
Процедура Тесты_СвойствоСуществует_Глобальный() Экспорт
существует = ЭтотОбъект.СвойствоСуществует(Неопределено, "SelectRecordType");
артТесты.ПроверитьИстину(существует, "существует SelectRecordType");
существует = ЭтотОбъект.СвойствоСуществует(Неопределено, "SelectRecordType1564");
артТесты.ПроверитьЛожь(существует, "существует SelectRecordType1564");
КонецПроцедуры
Процедура Тесты_МетодСуществует_Глобальный() Экспорт
существует = ЭтотОбъект.МетодСуществует(Неопределено, "XMLЗначение");
артТесты.ПроверитьИстину(существует, "существует XMLЗначение");
существует = ЭтотОбъект.МетодСуществует(Неопределено, "XMLЗначение1564");
артТесты.ПроверитьЛожь(существует, "существует XMLЗначение1564");
КонецПроцедуры
// ======================= ======================= ======================= =======================
//
// КОНЕЦ БЛОКА ЮНИТ-ТЕСТОВ
//
// ======================= ======================= ======================= =======================
#КонецЕсли
//==================================
ИМЯ_КЛАССА_DynamicWrapperX = "DynamicWrapperX";
СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ = "<Двойной клик по ячейке>";
СТРОКА_МЕТОДЫ = "Методы";
СТРОКА_СВОЙСТВА = "Свойства";
СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ = "ГлобальныйКонтекст";
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ = 0;
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ = 1;
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ = 2;
ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА = 3;
ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ = 4;
#Если Клиент Тогда
Инит();
#КонецЕсли