├── Example ├── filename ├── Templates │ └── GraphViz1c.xml └── Forms │ ├── Form.xml │ └── Form │ └── Ext │ ├── Form.xml │ └── Form │ └── Module.bsl ├── include ├── .gitattributes ├── IMemoryManager.h ├── com.h ├── AddInDefBase.h ├── types.h └── ComponentBase.h ├── Demo ├── img │ ├── team.png │ ├── server.png │ ├── freelance.png │ ├── mechanic.png │ ├── secretary.png │ ├── businessman.png │ ├── programmer.png │ └── technician.png ├── struct.dot ├── demo.dot ├── html.dot └── jira.dot ├── src ├── AddInNative.def ├── stdafx.h ├── GraphViz1C.h ├── AddInNative.rc ├── GraphViz1C.cpp ├── AddInNative.h └── AddInNative.cpp ├── version.h ├── .gitignore ├── Compile.bat ├── appveyor.ps1 ├── tools ├── LICENSE ├── README.md ├── ZipLibrary.os ├── Decompile.os └── Compile.os ├── Example.xml ├── manifest.ps1 ├── CMakeLists.txt ├── appveyor.yml ├── README.md ├── LICENSE └── GraphViz.patch /Example/filename: -------------------------------------------------------------------------------- 1 | GraphViz1c.epf -------------------------------------------------------------------------------- /include/.gitattributes: -------------------------------------------------------------------------------- 1 | * -text 2 | -------------------------------------------------------------------------------- /Demo/img/team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/team.png -------------------------------------------------------------------------------- /Demo/img/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/server.png -------------------------------------------------------------------------------- /src/AddInNative.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | GetClassObject 3 | DestroyObject 4 | GetClassNames 5 | -------------------------------------------------------------------------------- /Demo/img/freelance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/freelance.png -------------------------------------------------------------------------------- /Demo/img/mechanic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/mechanic.png -------------------------------------------------------------------------------- /Demo/img/secretary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/secretary.png -------------------------------------------------------------------------------- /Demo/img/businessman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/businessman.png -------------------------------------------------------------------------------- /Demo/img/programmer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/programmer.png -------------------------------------------------------------------------------- /Demo/img/technician.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lintest/GraphViz1C/HEAD/Demo/img/technician.png -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #define VER_FILENAME GraphViz1c 2 | #define VERSION_FULL 2.44.2.0 3 | #define VERSION_MAJOR 2 4 | #define VERSION_MINOR 44 5 | #define VERSION_REVISION 2 6 | #define VERSION_BUILD 0 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /GraphViz 2 | /build64W 3 | /build32W 4 | /build64Win 5 | /build32Win 6 | /build64Lin 7 | /build32Lin 8 | /build64 9 | /build32 10 | /build 11 | /bin64 12 | /bin32 13 | /bin 14 | /.vc 15 | /.vs 16 | /.vscode 17 | /Autotest.log 18 | /AddIn.zip 19 | /Example/fileversion 20 | /Example/Templates/GraphViz1C/Ext/Template.bin 21 | /Decompile.bat 22 | manifest.xml 23 | *.epf 24 | *.o 25 | *.d 26 | *.so 27 | -------------------------------------------------------------------------------- /src/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | #ifndef __STDAFX_H__ 6 | #define __STDAFX_H__ 7 | 8 | #ifdef _WINDOWS 9 | #include 10 | #endif //_WINDOWS 11 | 12 | #include 13 | 14 | std::wstring MB2WC(const std::string& source); 15 | std::string WC2MB(const std::wstring& source); 16 | 17 | #endif //__STDAFX_H__ 18 | -------------------------------------------------------------------------------- /Demo/struct.dot: -------------------------------------------------------------------------------- 1 | digraph structs 2 | { 3 | rankdir = LR; 4 | node [shape=record]; 5 | 6 | hashTable [label="0|1|2|3|4|5|6|7|8"]; 7 | node_1_0 [label=" one| two | three"]; 8 | node_1_1 [label=" un | deux| trois"]; 9 | struct3 [label=" einz| swei| drei"]; 10 | 11 | {rank = same; node_1_0 node_1_1 } 12 | 13 | hashTable:f1 -> node_1_0:f0; 14 | node_1_0:f2 -> node_1_1:f0; 15 | hashTable:f4 -> struct3:f0; 16 | } -------------------------------------------------------------------------------- /src/GraphViz1C.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAPHVIZ1C_H__ 2 | #define __GRAPHVIZ1C_H__ 3 | 4 | #include "AddInNative.h" 5 | #include 6 | #include 7 | #include 8 | 9 | class GraphViz1C: 10 | public AddInNative 11 | { 12 | private: 13 | static std::stringbuf buffer; 14 | static std::vector names; 15 | GVC_t* gvc = nullptr; 16 | GraphViz1C(); 17 | ~GraphViz1C(); 18 | private: 19 | void render(VH source, const std::string& format, const std::string& layout); 20 | void formats(int64_t api = 3); 21 | public: 22 | static std::ostream errors; 23 | }; 24 | #endif //__GRAPHVIZ1C_H__ -------------------------------------------------------------------------------- /Demo/demo.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | node[shape=none label=""] 3 | Корень[image="img/root.png"] 4 | Заказчик[image="img/businessman.png"] 5 | Команда[image="img/team.png"] 6 | Фрилансер[image="img/freelance.png"] 7 | Механик[image="img/mechanic.png"] 8 | Программист[image="img/programmer.png"] 9 | Секретарь[image="img/secretary.png"] 10 | Сервер[image="img/server.png"] 11 | Техник[image="img/technician.png"] 12 | Заказчик -> Команда -> Программист [penwidth=2 color="darkgreen"] 13 | Команда -> Секретарь [penwidth=2 color="darkgreen"] 14 | Команда -> Фрилансер [penwidth=2 color="darkgreen"] 15 | Механик -> Сервер [penwidth=2 color="darkgreen"] 16 | Техник -> Сервер [penwidth=2 color="darkgreen"] 17 | } -------------------------------------------------------------------------------- /Compile.bat: -------------------------------------------------------------------------------- 1 | rem cmake -E remove_directory build32W 2 | rem cmake -E remove_directory build64W 3 | rem del bin\Release\GraphViz1cWin32.dll 4 | rem del bin\Release\GraphViz1cWin64.dll 5 | 6 | mkdir build32W 7 | cd build32W 8 | cmake .. -A Win32 -DMySuffix2=32 -DVERSION="2.44.2" -DDATE="2020-12-07" 9 | cmake --build . --config Release --target GraphViz1c 10 | cd .. 11 | 12 | mkdir build64W 13 | cd build64W 14 | cmake .. -A x64 -DMySuffix2=64 -DVERSION="2.44.2" -DDATE="2020-12-07" 15 | cmake --build . --config Release --target GraphViz1c 16 | cd .. 17 | 18 | oscript .\tools\ZipLibrary.os GraphViz1c 19 | mkdir .\Example\Templates\GraphViz1C 20 | mkdir .\Example\Templates\GraphViz1C\Ext 21 | copy /b .\AddIn.zip .\Example\Templates\GraphViz1C\Ext\Template.bin 22 | oscript .\tools\Compile.os .\ -------------------------------------------------------------------------------- /Demo/html.dot: -------------------------------------------------------------------------------- 1 | digraph structs { 2 | node [shape=plaintext] 3 | struct1 [label=< 4 | 5 | 6 |
leftmid dleright
>]; 7 | struct2 [label=< 8 | 9 | 10 |
onetwo
>]; 11 | struct3 [label=< 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
hello
world
bgh
cde
f
>]; 26 | struct1:f1 -> struct2:f0; 27 | struct1:f2 -> struct3:here; 28 | } -------------------------------------------------------------------------------- /Demo/jira.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node[fontname="Arial" shape="box" style="rounded,filled" fontcolor="white" width=3] 3 | graph [nodesep=1 ranksep=0.5 splines=ortho] 4 | Старт[label="" shape="circle" color="gray" width=0.5] 5 | Открыто[color="deepskyblue4" group="g 0"] 6 | Анализ[color="gold1" fontcolor="black" group="g1"] 7 | Согласование[color="deepskyblue4" group="g2"] 8 | Разработка[color="gold1" fontcolor="black" group="g1"] 9 | Тестирование[color="gold1" fontcolor="black" group="g1"] 10 | Закрыто[color="darkgreen" group="g1"] 11 | Ожидание[color="deepskyblue4" group="g0"] 12 | Отклонено[color="firebrick"] 13 | Старт -> Открыто 14 | Анализ -> Разработка -> Тестирование -> Закрыто 15 | Согласование -> Отклонено 16 | Тестирование -> Ожидание -> Разработка 17 | Согласование -> Разработка 18 | {rank=same rankdir=RL Открыто Анализ Согласование} 19 | {rank=same rankdir=RL Закрыто Отклонено} 20 | {rank=same rankdir=RL Разработка Ожидание} 21 | Открыто -> Анализ -> Согласование 22 | } -------------------------------------------------------------------------------- /include/IMemoryManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Warning!!! 3 | * DO NOT ALTER THIS FILE! 4 | */ 5 | 6 | 7 | #ifndef __IMEMORY_MANAGER_H__ 8 | #define __IMEMORY_MANAGER_H__ 9 | 10 | /////////////////////////////////////////////////////////////////////////////// 11 | /** 12 | * The given class allocates and releases memory for a component 13 | */ 14 | /// Interface representing memory manager. 15 | class IMemoryManager 16 | { 17 | public: 18 | virtual ~IMemoryManager() {} 19 | /// Allocates memory of specified size 20 | /** 21 | * @param pMemory - the double pointer to variable, that will hold newly 22 | * allocated block of memory of NULL if allocation fails. 23 | * @param ulCountByte - memory size 24 | * @return the result of 25 | */ 26 | virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0; 27 | /// Releases memory 28 | /** 29 | * @param pMemory - The double pointer to the memory block being released 30 | */ 31 | virtual void ADDIN_API FreeMemory (void** pMemory) = 0; 32 | }; 33 | 34 | #endif //__IMEMORY_MANAGER_H__ 35 | -------------------------------------------------------------------------------- /Example/Templates/GraphViz1c.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /appveyor.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string]$account = $env:APPVEYOR_ACCOUNT_NAME, 3 | [string]$project = $env:APPVEYOR_PROJECT_NAME, 4 | [string]$name = $env:APPVEYOR_PROJECT_NAME 5 | ) 6 | 7 | $path = $env:APPVEYOR_BUILD_FOLDER 8 | $version = $env:APPVEYOR_BUILD_VERSION 9 | $postfix = '_' + $version -replace '\.', '-' 10 | 11 | $apiUrl = 'https://ci.appveyor.com/api' 12 | $data = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$account/$project/build/$version" 13 | $jobId = $data.build.jobs[0].jobId 14 | 15 | Invoke-RestMethod -Method Get -OutFile "$path\Linux.zip" ` 16 | -Uri "$apiUrl/buildjobs/$jobId/artifacts/AddIn.zip" 17 | 18 | Expand-Archive -Force -Path "$path\Linux.zip" -DestinationPath $path 19 | Rename-Item "$path\lib${name}Win32.dll" "${name}Win32$postfix.dll" 20 | Rename-Item "$path\lib${name}Win64.dll" "${name}Win64$postfix.dll" 21 | Rename-Item "$path\lib${name}Lin32.so" "${name}Lin32$postfix.so" 22 | Rename-Item "$path\lib${name}Lin64.so" "${name}Lin64$postfix.so" 23 | 24 | $compress = @{ 25 | Path = "$path\$name*.dll", "$path\$name*.so", "$path\manifest.xml" 26 | DestinationPath = "$path\AddIn.zip" 27 | } 28 | Compress-Archive @compress 29 | 30 | New-Item -ItemType Directory -Force -Path "$path\Example\Templates\$name\Ext\" | Out-Null 31 | Copy-Item -Path "$path\AddIn.zip" -Destination "$path\Example\Templates\$name\Ext\Template.bin" 32 | -------------------------------------------------------------------------------- /Example/Forms/Form.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | Form 6 | 7 | 8 | ru 9 | Form 10 | 11 | 12 | 13 | Managed 14 | false 15 | 16 | PersonalComputer 17 | MobileDevice 18 | 19 | 20 | 21 |
22 |
-------------------------------------------------------------------------------- /tools/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Pautov Leonid 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # External modules converter for 1C 2 | 3 | Данный инструмент предназначен для быстрой у удобной конвертации внешних обработок (epf файлов) и внешних отчетов (erf файлов) в формат xml и обратно. 4 | 5 | Для работы инструмента вам понадобится установить [OneScript](http://oscript.io) версии 1.0.20 или выше. 6 | 7 | ## Пример использования 8 | 1. Допустим у вас есть каталог/каталоги внешних отчетов и обработок. 9 | 2. Чтобы сконвертировать все файлы из каталога и его подкаталогов в xml формат нужно выполнить команду 10 | ``` 11 | oscript Decompile.os МойКаталог 12 | ``` 13 | 14 | 3. Чтобы сконвертировать все файлы из каталога из xml формата обратно в бинарый надо выполнить команду 15 | ``` 16 | oscript Compile.os МойКаталог 17 | ``` 18 | 19 | ## Для работы скриптов необходимо 20 | 1. Установить [OneScript](http://oscript.io) версии 1.0.20 или выше. 21 | 2. Также, чтобы работала сборка epf/erf надо установить платформу [1С:Предприятие 8.3.10](https://releases.1c.ru). 22 | 23 | 24 | ## Особенности использования 25 | 1. При первой распаковке файла будет создан служебный файл "filename". Он нужен, т.к. имя xml файла и имя epf/erf файла в общем случае могут различаться. 26 | 2. Файл filename лучше не добавлять в .gitignore, если вы планируете хранить исходники в git. 27 | 3. Также будет создан служебный файл "fileversion". Он нужен для того, чтобы делать конвертацию в xml и обратно только тех файлов, которые реально изменились. 28 | 4. Файл fileversion надо добавить в .gitignore. 29 | 5. Также пример использования данного инструмента можно увидеть в проекте Vanessa-Automation версии [1.2.001](https://github.com/Pr-Mex/vanessa-automation) и выше. 30 | -------------------------------------------------------------------------------- /Example.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | c3831ec8-d8d5-4f93-8a22-f9bfae07327f 7 | cade56ae-0599-4925-86d1-ab5c709029d6 8 | 9 | 10 | 8ec06d92-be24-405a-80e2-06fa6d9456a6 11 | 753c61a9-d6f9-41a9-802e-bedd59816a74 12 | 13 | 14 | 15 | Example 16 | 17 | 18 | ru 19 | GraphViz for 1C 20 | 21 | 22 | 23 | ExternalDataProcessor.Example.Form.Form 24 | 25 | 26 | 27 |
Form
28 | 29 |
30 |
31 |
-------------------------------------------------------------------------------- /manifest.ps1: -------------------------------------------------------------------------------- 1 | Param ( 2 | [string]$project = $env:APPVEYOR_PROJECT_NAME, 3 | [string]$version = $env:APPVEYOR_BUILD_VERSION 4 | ) 5 | 6 | $postfix = '_' + $version -replace '\.','-' 7 | $v1,$v2,$v3,$v4 = $version.split('.') 8 | Set-Content 'version.h' "#define VER_FILENAME $project" 9 | Add-Content 'version.h' "#define VERSION_FULL $version" 10 | Add-Content 'version.h' "#define VERSION_MAJOR $v1" 11 | Add-Content 'version.h' "#define VERSION_MINOR $v2" 12 | Add-Content 'version.h' "#define VERSION_REVISION $v3" 13 | Add-Content 'version.h' "#define VERSION_BUILD $v4" 14 | 15 | $encoding = [System.Text.Encoding]::UTF8 16 | $writer = New-Object System.XMl.XmlTextWriter('./manifest.xml', $encoding) 17 | $writer.Formatting = 'Indented' 18 | $writer.Indentation = 1 19 | $writer.IndentChar = "`t" 20 | $writer.WriteStartDocument() 21 | $writer.WriteStartElement('bundle') 22 | $writer.WriteAttributeString('xmlns', 'http://v8.1c.ru/8.2/addin/bundle') 23 | 24 | $writer.WriteStartElement('component') 25 | $writer.WriteAttributeString('type', 'native') 26 | $writer.WriteAttributeString('os', 'Windows') 27 | $writer.WriteAttributeString('arch', 'i386') 28 | $writer.WriteAttributeString('path', "${project}Win32${postfix}.dll") 29 | $writer.WriteEndElement(); 30 | 31 | $writer.WriteStartElement('component') 32 | $writer.WriteAttributeString('type', 'native') 33 | $writer.WriteAttributeString('os', 'Windows') 34 | $writer.WriteAttributeString('arch', 'x86_64') 35 | $writer.WriteAttributeString('path', "${project}Win64${postfix}.dll") 36 | $writer.WriteEndElement(); 37 | 38 | $writer.WriteStartElement('component') 39 | $writer.WriteAttributeString('type', 'native') 40 | $writer.WriteAttributeString('os', 'Linux') 41 | $writer.WriteAttributeString('arch', 'i386') 42 | $writer.WriteAttributeString('path', "${project}Lin32${postfix}.so") 43 | $writer.WriteEndElement(); 44 | 45 | $writer.WriteStartElement('component') 46 | $writer.WriteAttributeString('type', 'native') 47 | $writer.WriteAttributeString('os', 'Linux') 48 | $writer.WriteAttributeString('arch', 'x86_64') 49 | $writer.WriteAttributeString('path', "${project}Lin64${postfix}.so") 50 | $writer.WriteEndElement(); 51 | 52 | $writer.WriteEndElement(); 53 | $writer.WriteEndDocument() 54 | $writer.Flush() 55 | $writer.Close() 56 | -------------------------------------------------------------------------------- /src/AddInNative.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../version.h" 3 | 4 | #define STRINGIZE2(s) #s 5 | #define STRINGIZE(s) STRINGIZE2(s) 6 | 7 | #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD 8 | #define VER_FILE_VERSION_STR STRINGIZE(VERSION_MAJOR) \ 9 | "." STRINGIZE(VERSION_MINOR) \ 10 | "." STRINGIZE(VERSION_REVISION) \ 11 | "." STRINGIZE(VERSION_BUILD) 12 | 13 | #define VER_FILE_DESCRIPTION_STR "Native AddIn for 1C" 14 | #define VER_COPYRIGHT_STR "Kandrashin Denis, 2020" 15 | #define VER_FILE_EXT ".dll" 16 | #define VER_FILE_STR STRINGIZE(VER_FILENAME) 17 | 18 | ///////////////////////////////////////////////////////////////////////////// 19 | 20 | #define APSTUDIO_READONLY_SYMBOLS 21 | 22 | #define VER_PRODUCTNAME_STR VER_FILE_STR 23 | #define VER_PRODUCT_VERSION VER_FILE_VERSION 24 | #define VER_PRODUCT_VERSION_STR VER_FILE_VERSION_STR 25 | #define VER_ORIGINAL_FILENAME_STR VER_FILE_STR VER_FILE_EXT 26 | #define VER_INTERNAL_NAME_STR VER_ORIGINAL_FILENAME_STR 27 | 28 | #ifdef _DEBUG 29 | #define VER_VER_DEBUG VS_FF_DEBUG 30 | #else 31 | #define VER_VER_DEBUG 0 32 | #endif 33 | 34 | #define VER_FILEOS VOS_NT_WINDOWS32 35 | #define VER_FILEFLAGS VER_VER_DEBUG 36 | 37 | ///////////////////////////////////////////////////////////////////////////// 38 | // 39 | // Version 40 | // 41 | VS_VERSION_INFO VERSIONINFO 42 | FILEVERSION VER_FILE_VERSION 43 | PRODUCTVERSION VER_PRODUCT_VERSION 44 | FILEFLAGSMASK 0x3fL 45 | FILEFLAGS VER_FILEFLAGS 46 | FILEOS VER_FILEOS 47 | FILETYPE VFT_DLL 48 | FILESUBTYPE 0x0L 49 | BEGIN 50 | BLOCK "StringFileInfo" 51 | BEGIN 52 | BLOCK "041904B0" 53 | BEGIN 54 | VALUE "FileDescription", VER_FILE_DESCRIPTION_STR "\0" 55 | VALUE "FileVersion", VER_FILE_VERSION_STR "\0" 56 | VALUE "InternalName", VER_INTERNAL_NAME_STR "\0" 57 | VALUE "LegalCopyright", VER_COPYRIGHT_STR "\0" 58 | VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR "\0" 59 | VALUE "ProductName", VER_PRODUCTNAME_STR 60 | VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0" 61 | END 62 | END 63 | BLOCK "VarFileInfo" 64 | BEGIN 65 | VALUE "Translation", 0x0419, 0x04B0 66 | END 67 | END 68 | -------------------------------------------------------------------------------- /tools/ZipLibrary.os: -------------------------------------------------------------------------------- 1 | Перем ЗаписьXML, ЗаписьZIP, КаталогСкрипта, КаталогПакета, СуффиксВерсии; 2 | 3 | Процедура ДобавитьЭлемент(Система, Архитектура, ИмяФайла) 4 | 5 | Файл = Новый Файл(ИмяФайла); 6 | Если Не Файл.Существует() Тогда 7 | Сообщить("ОШИБКА - Не найден файл: " + ИмяФайла); 8 | Возврат; 9 | КонецЕсли; 10 | 11 | Если Лев(Файл.ИмяБезРасширения, 3) = "lib" Тогда 12 | НовоеИмяФайла = Сред(Файл.ИмяБезРасширения, 4); 13 | Иначе 14 | НовоеИмяФайла = Файл.ИмяБезРасширения; 15 | КонецЕсли; 16 | НовоеИмяФайла = НовоеИмяФайла + СуффиксВерсии + Файл.Расширение; 17 | 18 | ЗаписьXML.ЗаписатьНачалоЭлемента("component"); 19 | ЗаписьXML.ЗаписатьАтрибут("type", "native"); 20 | ЗаписьXML.ЗаписатьАтрибут("os", Система); 21 | ЗаписьXML.ЗаписатьАтрибут("arch", Архитектура); 22 | ЗаписьXML.ЗаписатьАтрибут("path", НовоеИмяФайла); 23 | ЗаписьXML.ЗаписатьКонецЭлемента(); 24 | 25 | КопироватьФайл(КаталогСкрипта + ИмяФайла, КаталогПакета + НовоеИмяФайла); 26 | ЗаписьZIP.Добавить(КаталогПакета + НовоеИмяФайла, РежимСохраненияПутейZIP.НеСохранятьПути); 27 | 28 | КонецПроцедуры 29 | 30 | Процедура MakePackage(ИмяПроекта) 31 | 32 | КаталогСкрипта = ТекущийСценарий().Каталог + "/../"; 33 | КаталогПакета = КаталогСкрипта + "bin/"; 34 | СоздатьКаталог(КаталогПакета); 35 | 36 | НомерВерсии = ""; 37 | СуффиксВерсии = ""; 38 | ТекстовыйДокумент = Новый ТекстовыйДокумент; 39 | ТекстовыйДокумент.Прочитать(КаталогСкрипта + "version.h"); 40 | Для НомерСтроки = 1 По 4 Цикл 41 | Стр = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки); 42 | Если СтрНайти(Стр, "VERSION_FULL") > 0 Тогда 43 | НаборСтрок = СтрРазделить(СтрЗаменить(Стр, Символы.Таб, " "), " ", Ложь); 44 | НомерВерсии = НаборСтрок.Получить(НаборСтрок.Количество() - 1); 45 | СуффиксВерсии = "_" + СтрЗаменить(НомерВерсии, ".", "_"); 46 | Прервать; 47 | КонецЕсли; 48 | КонецЦикла; 49 | 50 | Сообщить("Номер версии: " + НомерВерсии); 51 | 52 | ИмяПакета = КаталогСкрипта + "AddIn.zip"; 53 | ИмяФайла = КаталогПакета + "MANIFEST.XML"; 54 | 55 | УдалитьФайлы(ИмяПакета); 56 | ЗаписьZIP = Новый ЗаписьZipФайла(ИмяПакета); 57 | 58 | ЗаписьXML = Новый ЗаписьXML; 59 | ЗаписьXML.ОткрытьФайл(ИмяФайла, "UTF-8", Истина); 60 | ЗаписьXML.ЗаписатьБезОбработки(""); 61 | ЗаписьXML.ЗаписатьНачалоЭлемента("bundle"); 62 | ЗаписьXML.ЗаписатьАтрибут("xmlns", "http://v8.1c.ru/8.2/addin/bundle"); 63 | 64 | ДобавитьЭлемент("Windows" , "i386" , "bin32/Release/lib" + ИмяПроекта + "Win32.dll"); 65 | ДобавитьЭлемент("Windows" , "x86_64" , "bin64/Release/lib" + ИмяПроекта + "Win64.dll"); 66 | ДобавитьЭлемент("Linux" , "i386" , "bin32/lib" + ИмяПроекта + "Lin32.so"); 67 | ДобавитьЭлемент("Linux" , "x86_64" , "bin64/lib" + ИмяПроекта + "Lin64.so"); 68 | 69 | ЗаписьXML.ЗаписатьКонецЭлемента(); 70 | ЗаписьXML.Закрыть(); 71 | 72 | ЗаписьZIP.Добавить(ИмяФайла, РежимСохраненияПутейZIP.НеСохранятьПути); 73 | ЗаписьZIP.Записать(); 74 | 75 | КонецПроцедуры 76 | 77 | Если АргументыКоманднойСтроки.Количество() = 0 Тогда 78 | Сообщить("ОШИБКА - Не переданы параметры!"); 79 | Иначе 80 | Сообщить(АргументыКоманднойСтроки[0]); 81 | MakePackage(АргументыКоманднойСтроки[0]); 82 | КонецЕсли; -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(GraphViz1c) 3 | set(TARGET GraphViz1c) 4 | 5 | add_library(${TARGET} SHARED 6 | src/AddInNative.cpp 7 | src/AddInNative.def 8 | src/AddInNative.h 9 | src/AddInNative.rc 10 | src/GraphViz1C.cpp 11 | src/GraphViz1C.h 12 | src/stdafx.h) 13 | 14 | target_compile_definitions(${TARGET} PRIVATE UNICODE _UNICODE) 15 | target_include_directories(${TARGET} PRIVATE include) 16 | 17 | if (UNIX) 18 | if (APPLE) 19 | set(MySuffix1 "Mac") 20 | else(APPLE) 21 | set(MySuffix1 "Lin") 22 | endif(APPLE) 23 | if (TARGET_PLATFORM_32) 24 | set(MySuffix2 "32") 25 | else() 26 | set(MySuffix2 "64") 27 | endif() 28 | else(UNIX) 29 | if (NOT MSVC) 30 | message(FATAL_ERROR "Must be compiled with MSVC on Windows") 31 | endif(NOT MSVC) 32 | set(MyPrefix "lib") 33 | set(MySuffix1 "Win") 34 | endif(UNIX) 35 | 36 | set (LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin${MySuffix2}) 37 | set (EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH}) 38 | set (CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}) 39 | 40 | set_target_properties( ${PROJECT_NAME} PROPERTIES 41 | OUTPUT_NAME ${MyPrefix}${PROJECT_NAME}${MySuffix1}${MySuffix2} 42 | POSITION_INDEPENDENT_CODE ON 43 | CXX_STANDARD_REQUIRED ON 44 | CXX_STANDARD 17 45 | ) 46 | 47 | if (UNIX) 48 | if (TARGET_PLATFORM_32) 49 | set(CMAKE_LIBRARY_PATH "/usr/lib/i386-linux-gnu" CACHE PATH "") 50 | SET(ARCH_FLAG "-m32") 51 | else() 52 | SET(ARCH_FLAG "-m64") 53 | endif() 54 | foreach(flag 55 | CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS ) 56 | if(NOT ${flag} MATCHES ${ARCH_FLAG}) 57 | set(${flag} ${${flag}} ${ARCH_FLAG} CACHE "STRING" "Linker flags" FORCE) 58 | endif() 59 | endforeach() 60 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s") 61 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") 62 | else(UNIX) 63 | add_definitions(/MT) 64 | set(CMAKE_SUPPRESS_REGENERATION 1) 65 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) 66 | target_compile_definitions(${TARGET} PRIVATE _WINDOWS 67 | _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) 68 | target_compile_options(${TARGET} PRIVATE /utf-8) 69 | set(CompilerFlags 70 | CMAKE_CXX_FLAGS 71 | CMAKE_CXX_FLAGS_DEBUG 72 | CMAKE_CXX_FLAGS_RELEASE 73 | CMAKE_C_FLAGS 74 | CMAKE_C_FLAGS_DEBUG 75 | CMAKE_C_FLAGS_RELEASE 76 | ) 77 | foreach(CompilerFlag ${CompilerFlags}) 78 | string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") 79 | endforeach() 80 | endif(UNIX) 81 | 82 | add_definitions(-DXML_STATIC) 83 | add_definitions(-DXML_BUILDING_EXPAT) 84 | set(GRAPHVIZ_LIB_DIR "${CMAKE_SOURCE_DIR}/GraphViz/lib") 85 | add_subdirectory(./GraphViz) 86 | 87 | include_directories( 88 | ${GRAPHVIZ_LIB_DIR} 89 | ${CMAKE_CURRENT_BINARY_DIR} 90 | ${GRAPHVIZ_LIB_DIR}/cdt 91 | ${GRAPHVIZ_LIB_DIR}/cgraph 92 | ${GRAPHVIZ_LIB_DIR}/common 93 | ${GRAPHVIZ_LIB_DIR}/gvc 94 | ${GRAPHVIZ_LIB_DIR}/pathplan 95 | ) 96 | 97 | add_dependencies(${TARGET} 98 | common 99 | pack_obj 100 | ) 101 | 102 | target_link_libraries(${TARGET} 103 | gvplugin_core 104 | gvplugin_dot_layout 105 | gvplugin_neato_layout 106 | gvplugin_gdiplus 107 | ) 108 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 2.44.2.{build} 2 | configuration: Release 3 | platform: x64 4 | 5 | branches: 6 | only: 7 | - develop 8 | - master 9 | 10 | skip_branch_with_pr: true 11 | skip_tags: true 12 | 13 | environment: 14 | global: 15 | KEY_1CV8T: 16 | secure: OolAVEKkEg1cGCpG/VK2FaM0LWrPgMR/Kn4nTLYyKR0= 17 | API_TOKEN: 18 | secure: 85XpT8I1bxRTZaiIA+co0b5GS05J2VOn7PzunkYlL40= 19 | 20 | matrix: 21 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 22 | job_name: Windows 23 | 24 | matrix: 25 | fast_finish: true 26 | 27 | install: 28 | - git clone -q --branch=platform https://github.com/lintest/tools1c.git bin 29 | - cd bin 30 | - 7z x tools1c.part01.rar -p%KEY_1CV8T% 31 | - cd %APPVEYOR_BUILD_FOLDER% 32 | 33 | - git clone -q --branch=master https://github.com/lintest/GraphViz.git GraphViz 34 | - cd GraphViz 35 | - git submodule update --init 36 | - cd %APPVEYOR_BUILD_FOLDER% 37 | 38 | - git clone -q --branch=master https://github.com/libexpat/libexpat.git Expat 39 | - cd Expat 40 | - git checkout -b version R_2_2_10 41 | - mkdir build32 42 | - cd build32 43 | - cmake ../expat -A Win32 -DEXPAT_MSVC_STATIC_CRT=ON -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=../../GraphViz/windows/dependencies/libraries/x86/ 44 | - cmake --build . --config Release --target INSTALL 45 | - cd .. 46 | - mkdir build64 47 | - cd build64 48 | - cmake ../expat -A x64 -DEXPAT_MSVC_STATIC_CRT=ON -DEXPAT_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=../../GraphViz/windows/dependencies/libraries/x64/ 49 | - cmake --build . --config Release --target INSTALL 50 | - cd %APPVEYOR_BUILD_FOLDER% 51 | 52 | - cd GraphViz/windows/dependencies/libraries/x86/lib 53 | - del expat.lib 54 | - ren libexpat*.lib expat.lib 55 | - cd %APPVEYOR_BUILD_FOLDER% 56 | - cd GraphViz/windows/dependencies/libraries/x64/lib 57 | - del expat.lib 58 | - ren libexpat*.lib expat.lib 59 | - cd %APPVEYOR_BUILD_FOLDER% 60 | 61 | init: 62 | - cmake --version 63 | - msbuild /version 64 | - echo. 65 | 66 | build_script: 67 | - powershell -File manifest.ps1 68 | 69 | - mkdir build32 70 | - cd build32 71 | - cmake .. -A Win32 -DMySuffix2=32 -DVERSION="%APPVEYOR_BUILD_VERSION%" -DDATE="2020-12-07" 72 | - cmake --build . --config Release --target GraphViz1c 73 | - cd .. 74 | 75 | - mkdir build64 76 | - cd build64 77 | - cmake .. -A x64 -DMySuffix2=64 -DVERSION="%APPVEYOR_BUILD_VERSION%" -DDATE="2020-12-07" 78 | - cmake --build . --config Release --target GraphViz1c 79 | - cd .. 80 | 81 | - copy .\bin32\Release\libGraphViz1cWin32.dll . 82 | - copy .\bin64\Release\libGraphViz1cWin64.dll . 83 | - Powershell -File appveyor.ps1 84 | 85 | for: 86 | - matrix: 87 | only: 88 | - job_name: Windows 89 | 90 | after_build: 91 | - appveyor PushArtifact AddIn.zip 92 | - mkdir database 93 | - bin\1cv8t.exe CREATEINFOBASE File=%CD%/database 94 | - bin\1cv8t.exe DESIGNER /F %CD%/database /LoadExternalDataProcessorOrReportFromFiles Example.xml GraphViz1c.epf /Out example.log 95 | 96 | artifacts: 97 | - path: AddIn.zip 98 | - path: GraphViz1c.epf 99 | - path: autotest.log 100 | - path: example.log 101 | 102 | deploy: 103 | - provider: GitHub 104 | auth_token: 105 | secure: v7P89NQ2I5+WGNNdhpFrZEt6OCTPf8A8VSC5rttZMXh3DJ2fTChNEjZ1Wvm3kfBt 106 | repository: lintest/GraphViz1c 107 | artifact: AddIn.zip, GraphViz1c.epf 108 | draft: true 109 | prerelease: true 110 | force_update: true 111 | on: 112 | branch: master 113 | -------------------------------------------------------------------------------- /include/com.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __COM_H__ 3 | #define __COM_H__ 4 | 5 | #if defined(__linux__) || defined(__APPLE__) || defined(__ANDROID__) 6 | 7 | #ifdef __ANDROID__ 8 | 9 | typedef struct { 10 | unsigned int Data1; 11 | unsigned short Data2; 12 | unsigned short Data3; 13 | unsigned char Data4[ 8 ]; 14 | } uuid_t; 15 | 16 | #else 17 | #include 18 | #endif //__ANDROID__ 19 | 20 | #ifndef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ // iOS 21 | #include 22 | #endif //!__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ 23 | 24 | #pragma GCC system_header 25 | 26 | typedef long HRESULT; 27 | 28 | #ifdef __GNUC__ 29 | #define STDMETHODCALLTYPE __attribute__ ((__stdcall__)) 30 | #define DECLSPEC_NOTHROW __attribute__ ((nothrow)) 31 | #define STDMETHOD(method) virtual DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE method 32 | #else 33 | #define STDMETHODCALLTYPE 34 | #endif 35 | 36 | #define __stdcall STDMETHODCALLTYPE 37 | #define near 38 | #define far 39 | #define CONST const 40 | #define FAR far 41 | 42 | typedef unsigned long DWORD; 43 | #ifndef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ // iOS 44 | typedef int BOOL; 45 | #elif defined(__LP64__) 46 | typedef bool BOOL; 47 | #else 48 | typedef signed char BOOL; 49 | #endif //!__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ 50 | 51 | typedef void VOID; 52 | typedef short SHORT; 53 | typedef unsigned char BYTE; 54 | typedef unsigned short WORD; 55 | typedef float FLOAT; 56 | typedef FLOAT *PFLOAT; 57 | typedef BOOL near *PBOOL; 58 | typedef BOOL far *LPBOOL; 59 | typedef BYTE near *PBYTE; 60 | typedef BYTE far *LPBYTE; 61 | typedef int near *PINT; 62 | typedef int far *LPINT; 63 | typedef WORD near *PWORD; 64 | typedef WORD far *LPWORD; 65 | typedef long far *LPLONG; 66 | typedef DWORD near *PDWORD; 67 | typedef DWORD far *LPDWORD; 68 | typedef void far *LPVOID; 69 | typedef CONST void far *LPCVOID; 70 | typedef wchar_t *BSTR; 71 | typedef long SCODE; 72 | typedef int INT; 73 | typedef unsigned int UINT; 74 | typedef unsigned int *PUINT; 75 | typedef wchar_t WCHAR; 76 | typedef wchar_t OLECHAR; 77 | typedef wchar_t *LPOLESTR; 78 | typedef const wchar_t *LPCOLESTR; 79 | typedef DWORD LCID; 80 | typedef PDWORD PLCID; 81 | typedef long LONG; 82 | typedef unsigned long ULONG; 83 | typedef long long LONGLONG; 84 | typedef unsigned long long ULONGLONG; 85 | typedef LONG DISPID; 86 | typedef double DOUBLE; 87 | typedef double DATE; 88 | typedef short VARIANT_BOOL; 89 | typedef void *PVOID; 90 | typedef char CHAR; 91 | typedef CONST CHAR *LPCSTR; 92 | typedef unsigned short USHORT; 93 | typedef void *HMODULE; 94 | #define OLESTR(str) L##str 95 | 96 | typedef uuid_t GUID; 97 | typedef uuid_t IID; 98 | typedef uuid_t UUID; 99 | #define REFIID const IID & 100 | #define MAX_PATH 260 101 | 102 | #define IsEqualIID(x,y) uuid_compare((x),(y)) 103 | #ifdef __GNUC__ 104 | #define LoadLibraryA(x) dlopen((x), RTLD_LAZY) 105 | #define FreeLibrary(x) dlclose((x)) 106 | #define GetProcAddress(x, y) dlsym((x), (y)) 107 | #endif //__GNUC__ 108 | 109 | #define E_FAIL 0x80004005L 110 | #define S_OK 0L 111 | #define S_FALSE 1L 112 | #define E_NOINTERFACE 0x80004002L 113 | #define E_NOTIMPL 0x80004001L 114 | #define E_INVALIDARG 0x80070057L 115 | #define E_UNEXPECTED 0x8000FFFFL 116 | #define E_OUTOFMEMORY 0x8007000EL 117 | #define DISP_E_UNKNOWNNAME 0x80020006L 118 | #define DISPID_UNKNOWN ( -1 ) 119 | #define TRUE 1 120 | #define FALSE 0 121 | 122 | typedef long ITypeInfo; 123 | 124 | #if defined (__GNUC__) && !defined (NONAMELESSUNION) 125 | __extension__ /* no named members */ 126 | #endif 127 | union tCY { 128 | __extension__ struct 129 | { 130 | unsigned long Lo; 131 | long Hi; 132 | }; 133 | long long int64; 134 | }; 135 | typedef union tagCY CY; 136 | #define CLSIDFromString(x,y) uuid_parse((x),(unsigned char*)(y)) 137 | 138 | #endif //defined(__linux__) || defined(__APPLE__) 139 | 140 | #endif //__COM_H__ 141 | -------------------------------------------------------------------------------- /include/AddInDefBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Warning!!! 3 | * DO NOT ALTER THIS FILE! 4 | */ 5 | 6 | #ifndef __ADAPTER_DEF_H__ 7 | #define __ADAPTER_DEF_H__ 8 | #include "types.h" 9 | 10 | struct IInterface 11 | { 12 | }; 13 | 14 | 15 | enum Interfaces 16 | { 17 | eIMsgBox = 0, 18 | eIPlatformInfo, 19 | 20 | #if defined(__ANDROID__) 21 | 22 | eIAndroidComponentHelper, 23 | 24 | #endif 25 | 26 | }; 27 | 28 | //////////////////////////////////////////////////////////////////////////////// 29 | /** 30 | * This class serves as representation of a platform for external 31 | * components External components use it to communicate with a platform. 32 | * 33 | */ 34 | /// Base interface for object components. 35 | class IAddInDefBase 36 | { 37 | public: 38 | virtual ~IAddInDefBase() {} 39 | /// Adds the error message 40 | /** 41 | * @param wcode - error code 42 | * @param source - source of error 43 | * @param descr - description of error 44 | * @param scode - error code (HRESULT) 45 | * @return the result of 46 | */ 47 | virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source, 48 | const WCHAR_T* descr, long scode) = 0; 49 | 50 | /// Reads a property value 51 | /** 52 | * @param wszPropName -property name 53 | * @param pVal - value being returned 54 | * @param pErrCode - error code (if any error occured) 55 | * @param errDescriptor - error description (if any error occured) 56 | * @return the result of read. 57 | */ 58 | virtual bool ADDIN_API Read(WCHAR_T* wszPropName, 59 | tVariant* pVal, 60 | long *pErrCode, 61 | WCHAR_T** errDescriptor) = 0; 62 | /// Writes a property value 63 | /** 64 | * @param wszPropName - property name 65 | * @param pVar - new property value 66 | * @return the result of write. 67 | */ 68 | virtual bool ADDIN_API Write(WCHAR_T* wszPropName, 69 | tVariant *pVar) = 0; 70 | 71 | ///Registers profile components 72 | /** 73 | * @param wszProfileName - profile name 74 | * @return the result of 75 | */ 76 | virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName) = 0; 77 | 78 | /// Changes the depth of event buffer 79 | /** 80 | * @param lDepth - new depth of event buffer 81 | * @return the result of 82 | */ 83 | virtual bool ADDIN_API SetEventBufferDepth(long lDepth) = 0; 84 | /// Returns the depth of event buffer 85 | /** 86 | * @return the depth of event buffer 87 | */ 88 | virtual long ADDIN_API GetEventBufferDepth() = 0; 89 | /// Registers external event 90 | /** 91 | * @param wszSource - source of event 92 | * @param wszMessage - event message 93 | * @param wszData - message parameters 94 | * @return the result of 95 | */ 96 | virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, 97 | WCHAR_T* wszMessage, 98 | WCHAR_T* wszData) = 0; 99 | /// Clears event buffer 100 | /** 101 | */ 102 | virtual void ADDIN_API CleanEventBuffer() = 0; 103 | 104 | /// Sets status line contents 105 | /** 106 | * @param wszStatusLine - new status line contents 107 | * @return the result of 108 | */ 109 | virtual bool ADDIN_API SetStatusLine(WCHAR_T* wszStatusLine) = 0; 110 | /// Resets the status line contents 111 | /** 112 | * @return the result of 113 | */ 114 | virtual void ADDIN_API ResetStatusLine() = 0; 115 | }; 116 | 117 | class IAddInDefBaseEx : 118 | public IAddInDefBase 119 | { 120 | public: 121 | virtual ~IAddInDefBaseEx() {} 122 | 123 | virtual IInterface* ADDIN_API GetInterface(Interfaces iface) = 0; 124 | }; 125 | 126 | struct IMsgBox : 127 | public IInterface 128 | { 129 | virtual bool ADDIN_API Confirm(const WCHAR_T* queryText, tVariant* retVal) = 0; 130 | 131 | virtual bool ADDIN_API Alert(const WCHAR_T* text) = 0; 132 | }; 133 | 134 | struct IPlatformInfo : 135 | public IInterface 136 | { 137 | enum AppType 138 | { 139 | eAppUnknown = -1, 140 | eAppThinClient = 0, 141 | eAppThickClient, 142 | eAppWebClient, 143 | eAppServer, 144 | eAppExtConn, 145 | eAppMobileClient, 146 | eAppMobileServer, 147 | }; 148 | 149 | struct AppInfo 150 | { 151 | const WCHAR_T* AppVersion; 152 | const WCHAR_T* UserAgentInformation; 153 | AppType Application; 154 | }; 155 | 156 | virtual const AppInfo* ADDIN_API GetPlatformInfo() = 0; 157 | }; 158 | 159 | #endif //__ADAPTER_DEF_H__ 160 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## GraphViz1C - внешняя компонента 1С для построения графов 2 | 3 | Предназначена для Windows, разработана по технологии Native API. 4 | 5 | [![Build status](https://ci.appveyor.com/api/projects/status/ydd0mry1m8848wp1?svg=true)](https://ci.appveyor.com/project/lintest/graphviz1c) 6 | 7 | Поддерживаемые форматы экспорта: bmp, canon, cmap, cmapx, cmapx_np, dot, dot_json, emf, 8 | emfplus, eps, fig, gif, gv, imap, imap_np, ismap, jpe, jpeg, jpg, json, json0, metafile, mp, pic, 9 | plain, plain-ext, png, ps, ps2, svg, tif, tiff, tk, vml, xdot, xdot1.2, xdot1.4, xdot_json. 10 | 11 | Для двоичных данных DOT-файлов реализована поддержка только кодировки UTF-8. Если исходный файл 12 | в другой кодировке, рекомендуется прочитать файл в строку посредством объекта ЧтениеТекста. 13 | 14 | ### Подключение внешней компоненты 15 | 16 | ```bsl 17 | &НаКлиенте 18 | Перем ИдентификаторКомпоненты, ВнешняяКомпонента; 19 | 20 | &НаСервере 21 | Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) 22 | ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); 23 | МакетКомпоненты = ОбработкаОбъект.ПолучитьМакет("GraphViz1C"); 24 | АдресКомпоненты = ПоместитьВоВременноеХранилище(МакетКомпоненты, УникальныйИдентификатор); 25 | КонецПроцедуры 26 | 27 | &НаКлиенте 28 | Процедура ПриОткрытии(Отказ) 29 | ИдентификаторКомпоненты = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); 30 | ВыполнитьПодключениеВнешнейКомпоненты(Истина); 31 | КонецПроцедуры 32 | 33 | &НаКлиенте 34 | Процедура ВыполнитьПодключениеВнешнейКомпоненты(ДопПараметры) Экспорт 35 | НачатьПодключениеВнешнейКомпоненты( 36 | Новый ОписаниеОповещения("ПодключенаВнешняяКомпонента", ЭтаФорма, ДопПараметры), 37 | АдресКомпоненты, ИдентификаторКомпоненты, ТипВнешнейКомпоненты.Native); 38 | КонецПроцедуры 39 | 40 | &НаКлиенте 41 | Процедура ПодключенаВнешняяКомпонента(Подключение, ДополнительныеПараметры) Экспорт 42 | Если Подключение Тогда 43 | ВнешняяКомпонента = Новый("AddIn." + ИдентификаторКомпоненты + ".GraphViz1C"); 44 | ИначеЕсли ДополнительныеПараметры = Истина Тогда 45 | НачатьУстановкуВнешнейКомпоненты( 46 | Новый ОписаниеОповещения("ВыполнитьПодключениеВнешнейКомпоненты", ЭтаФорма, Ложь), 47 | АдресКомпоненты); 48 | КонецЕсли; 49 | КонецПроцедуры 50 | ``` 51 | 52 | ## Методы 53 | ### Сформировать(Данные, ФорматКартинки, ВариантРазмещения) / Render 54 | Возвращает картинку в виде двоичных данных, либо строку с текстом ошибки. 55 | 56 | Параметры функции: 57 | - **Данные** (обязательный), Тип: Двоичные данные или строка 58 | - **ФорматКартинки** (необязательный), Тип: Строка, по умолчанию "svg" 59 | - **ВариантРазмещения** (необязательный), Тип: Строка, по умолчанию "dot" 60 | 61 | Тип возвращаемого значения: двоичные данные или строка 62 | - Содержит картинку в виде двоичных данных, либо строку с текстом ошибки. 63 | 64 | ```bsl 65 | &НаКлиенте 66 | Процедура СформироватьКартинку(Команда) 67 | ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла); 68 | ОписаниеОповещения = Новый ОписаниеОповещения("ПолученаКартинка", ЭтаФорма); 69 | ВнешняяКомпонента.НачатьВызовСформировать(ОписаниеОповещения, ДвоичныеДанные, "svg"); 70 | КонецПроцедуры 71 | 72 | &НаКлиенте 73 | Процедура ПолученаКартинка(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт 74 | Если ТипЗнч(РезультатВызова) = Тип("ДвоичныеДанные") Тогда 75 | АдресКартинки = ПоместитьВоВременноеХранилище(РезультатВызова, УникальныйИдентификатор); 76 | ИначеЕсли ТипЗнч(РезультатВызова) = Тип("Строка") Тогда 77 | Сообщить(РезультатВызова); 78 | КонецЕсли; 79 | КонецПроцедуры 80 | ``` 81 | 82 | ### Формат(Идентификатор) / Format 83 | Возвращает список доступных форматов по идентификатору API. 84 | 85 | Параметры функции: 86 | - **Идентификатор** (необязательный), Тип: Целое число, по умолчанию: 3 87 | * API_render = 0 88 | * API_layout = 1 89 | * API_textlayout = 2 90 | * API_device = 3 91 | * API_loadimage = 4 92 | 93 | Тип возвращаемого значения: строка 94 | - Содержит строку со списком идентификаторов доступных форматов, разделенных пробелами. 95 | 96 | ```bsl 97 | &НаКлиенте 98 | Процедура ВывестиДоступныеФорматы(Команда) 99 | ОписаниеОповещения = Новый ОписаниеОповещения("ПолученыФорматы", ЭтаФорма); 100 | ВнешняяКомпонента.НачатьВызовФормат(ОписаниеОповещения); 101 | КонецПроцедуры 102 | 103 | &НаКлиенте 104 | Процедура ПолученыФорматы(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт 105 | Сообщить("Доступные форматы: " + РезультатВызова); 106 | КонецПроцедуры 107 | ``` 108 | ## Свойства 109 | 110 | ### ПутиКартинок / ImagePath 111 | Тип значения: Строка (только чтение) 112 | - Список папок, где осуществляется поиск используемых в графе картинок. 113 | Соответствует переменной окружения [GV_FILE_PATH](https://graphviz.org/doc/info/command.html#d:GV_FILE_PATH). 114 | Для среды Windows значения разделяются точкой с запятой, для Linux разделяются двоеточием. 115 | -------------------------------------------------------------------------------- /src/GraphViz1C.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphViz1C.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | extern "C" { 9 | extern char* gvplugin_list(GVC_t* gvc, api_t api, const char* str); 10 | extern gvplugin_library_t gvplugin_dot_layout_LTX_library; 11 | extern gvplugin_library_t gvplugin_neato_layout_LTX_library; 12 | extern gvplugin_library_t gvplugin_core_LTX_library; 13 | extern gvplugin_library_t gvplugin_gdiplus_LTX_library; 14 | extern char* Gvfilepath; /* Per-process path of files allowed in image attributes (also ps libs) */ 15 | extern char* Gvimagepath; /* Per-graph path of files allowed in image attributes (also ps libs) */ 16 | } 17 | 18 | namespace AddIn1C { 19 | 20 | static int error(char* errMsg) 21 | { 22 | GraphViz1C::errors << errMsg; 23 | return 0; 24 | } 25 | 26 | lt_symlist_t lt_preloaded_symbols[] = { 27 | { "gvplugin_dot_layout_LTX_library", (void*)(&gvplugin_dot_layout_LTX_library) }, 28 | { "gvplugin_neato_layout_LTX_library", (void*)(&gvplugin_neato_layout_LTX_library) }, 29 | { "gvplugin_core_LTX_library", (void*)(&gvplugin_core_LTX_library) }, 30 | { "gvplugin_gdiplus_LTX_library", (void*)(&gvplugin_gdiplus_LTX_library) }, 31 | { 0, 0 } 32 | }; 33 | 34 | typedef struct { 35 | const char* data; 36 | int len; 37 | int cur; 38 | } rdr_t; 39 | 40 | static int memiofread(void* chan, char* buf, int bufsize) 41 | { 42 | if (bufsize == 0) return 0; 43 | rdr_t* s = (rdr_t*)chan; 44 | if (s->cur >= s->len) 45 | return 0; 46 | int l = 0; 47 | const char* ptr = s->data + s->cur; 48 | char* optr = buf; 49 | char c = *ptr++; 50 | do { 51 | *optr++ = c; 52 | l++; 53 | } while ((c != '\n') && (l < bufsize) && (c = *ptr++)); 54 | s->cur += l; 55 | return l; 56 | } 57 | 58 | static Agraph_t* read(const char* data, unsigned int size) 59 | { 60 | rdr_t rdr{ data, size, 0 }; 61 | Agiodisc_t memIoDisc = { memiofread, AgIoDisc.putstr, AgIoDisc.flush }; 62 | Agdisc_t disc{ &AgMemDisc, &AgIdDisc, &memIoDisc }; 63 | agsetfile(NULL); 64 | return agread(&rdr, &disc); 65 | } 66 | } 67 | 68 | #pragma comment(lib, "vcruntime.lib") 69 | 70 | std::vector GraphViz1C::names = { 71 | AddComponent(u"GraphViz1C", []() { return new GraphViz1C; }), 72 | }; 73 | 74 | GraphViz1C::GraphViz1C() 75 | { 76 | static std::string imagepath; 77 | 78 | AddProperty( 79 | u"ImagePath", u"ПутиКартинок", 80 | [&](VH var) { var = imagepath; }, 81 | [&](VH var) { 82 | imagepath = var; 83 | Gvfilepath = (char*)imagepath.c_str(); 84 | Gvimagepath = (char*)imagepath.c_str(); 85 | } 86 | ); 87 | AddProperty( 88 | u"Errors", u"Ошибки", 89 | [&](VH var) { var = buffer.str(); } 90 | ); 91 | AddFunction(u"Render", u"Сформировать", 92 | [&](VH source, VH format, VH layout) { this->render(source, format, layout); }, 93 | { { 1, u"svg"}, { 2, u"dot" } } 94 | ); 95 | AddFunction(u"Format", u"Формат", 96 | [&](VH api) { this->formats(api); }, 97 | { { 0, (int64_t)3 } } 98 | ); 99 | 100 | gvc = gvContextPlugins(AddIn1C::lt_preloaded_symbols, 0); 101 | } 102 | 103 | GraphViz1C::~GraphViz1C() 104 | { 105 | if (gvc) gvFreeContext(gvc); 106 | } 107 | 108 | std::stringbuf GraphViz1C::buffer; 109 | 110 | std::ostream GraphViz1C::errors(&buffer); 111 | 112 | void GraphViz1C::render(VH source, const std::string& format, const std::string& layout) 113 | { 114 | buffer.str({}); 115 | agseterrf(AddIn1C::error); 116 | 117 | std::string text; 118 | const char* input = nullptr; 119 | char* output = nullptr; 120 | unsigned int size = 0; 121 | switch (source.type()) { 122 | case VTYPE_BLOB: 123 | input = source.data(); 124 | size = source.size(); 125 | break; 126 | case VTYPE_PWSTR: 127 | text = source; 128 | input = text.c_str(); 129 | size = text.size(); 130 | break; 131 | default: 132 | result = "Unsupported data type"; 133 | return; 134 | } 135 | 136 | if (!gvc) { 137 | result = "Failed to initialize context plugins"; 138 | return; 139 | } 140 | 141 | agmemread("\0"); 142 | auto g = AddIn1C::read(input, size); 143 | if (g) { 144 | if (gvLayout(gvc, g, layout.c_str()) == 0) { 145 | if (gvRenderData(gvc, g, format.c_str(), &output, &size) == 0) { 146 | try { 147 | result.AllocMemory(size); 148 | memcpy(result.data(), output, size); 149 | } 150 | catch (...) { 151 | result = "Memory allocation error"; 152 | } 153 | gvFreeRenderData(output); 154 | } 155 | } 156 | gvFreeLayout(gvc, g); 157 | agclose(g); 158 | } 159 | if (result.type() == VTYPE_EMPTY) { 160 | result = buffer.str(); 161 | } 162 | } 163 | 164 | void GraphViz1C::formats(int64_t api) 165 | { 166 | if (gvc) { 167 | auto str = gvplugin_list(gvc, (api_t)api, ""); 168 | if (str) result = std::string(str); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Example/Forms/Form/Ext/Form.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | false 4 | 5 | 6 | 11 | 20 | 25 | 30 | 31 | 32 | 33 | ПриОткрытии 34 | ПриСозданииНаСервере 35 | 36 | 37 | 38 | ТекстHTML 39 | None 40 | 41 | 42 | 43 | ТекстHTMLДокументСформирован 44 | 45 | 46 | 47 | 48 | 49 | 50 | cfg:ExternalDataProcessorObject.Example 51 | 52 | true 53 | 54 | 55 | 56 | <v8:item> 57 | <v8:lang>ru</v8:lang> 58 | <v8:content>Картинка</v8:content> 59 | </v8:item> 60 | 61 | 62 | xs:string 63 | 64 | 0 65 | Variable 66 | 67 | 68 | 69 | 70 | 71 | <v8:item> 72 | <v8:lang>ru</v8:lang> 73 | <v8:content>Адрес компоненты</v8:content> 74 | </v8:item> 75 | 76 | 77 | xs:string 78 | 79 | 0 80 | Variable 81 | 82 | 83 | 84 | 85 | 86 | <v8:item> 87 | <v8:lang>ru</v8:lang> 88 | <v8:content>Текст HTML</v8:content> 89 | </v8:item> 90 | 91 | 92 | xs:string 93 | 94 | 0 95 | Variable 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | <v8:item> 104 | <v8:lang>ru</v8:lang> 105 | <v8:content>Сформировать</v8:content> 106 | </v8:item> 107 | 108 | 109 | 110 | ru 111 | Сформировать 112 | 113 | 114 | Сформировать 115 | 116 | 117 | 118 | <v8:item> 119 | <v8:lang>ru</v8:lang> 120 | <v8:content>Экспорт в Visio</v8:content> 121 | </v8:item> 122 | 123 | 124 | 125 | ru 126 | Экспорт visio 127 | 128 | 129 | ЭкспортVisio 130 | 131 | 132 | 133 | <v8:item> 134 | <v8:lang>ru</v8:lang> 135 | <v8:content>Доступные форматы</v8:content> 136 | </v8:item> 137 | 138 | 139 | 140 | ru 141 | Доступные форматы 142 | 143 | 144 | ДоступныеФорматы 145 | 146 | 147 | 148 | <v8:item> 149 | <v8:lang>ru</v8:lang> 150 | <v8:content>Сохранить как…</v8:content> 151 | </v8:item> 152 | 153 | 154 | 155 | ru 156 | Сохранить как 157 | 158 | 159 | СохранитьКак 160 | TextPicture 161 | 162 | 163 | 164 | <v8:item> 165 | <v8:lang>ru</v8:lang> 166 | <v8:content>Открыть файл</v8:content> 167 | </v8:item> 168 | 169 | 170 | 171 | ru 172 | Открыть файл 173 | 174 | 175 | 176 | StdPicture.OpenFile 177 | true 178 | 179 | ОткрытьФайл 180 | TextPicture 181 | 182 | 183 |
-------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CON_TYPES_H__ 3 | #define __CON_TYPES_H__ 4 | 5 | #if defined(_WINDOWS) || defined(WINAPI_FAMILY) 6 | #include 7 | #endif 8 | 9 | #if defined(WINAPI_FAMILY) 10 | #include 11 | #endif 12 | 13 | #if __GNUC__ >=3 14 | #pragma GCC system_header 15 | #endif 16 | 17 | #include "com.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define EXTERN_C extern "C" 24 | 25 | #ifdef __GNUC__ 26 | #define _ANONYMOUS_UNION __extension__ 27 | #define _ANONYMOUS_STRUCT __extension__ 28 | #else 29 | #define _ANONYMOUS_UNION 30 | #define _ANONYMOUS_STRUCT 31 | #endif //__GNUC__ 32 | 33 | #ifdef NONAMELESSUNION 34 | #define __VARIANT_NAME_1 u 35 | #define __VARIANT_NAME_2 iface 36 | #define __VARIANT_NAME_3 str 37 | #define __VARIANT_NAME_4 wstr 38 | #else 39 | #define __VARIANT_NAME_1 40 | #define __VARIANT_NAME_2 41 | #define __VARIANT_NAME_3 42 | #define __VARIANT_NAME_4 43 | #endif //NONAMELESSUNION 44 | 45 | #define RESULT_FROM_ERRNO(x) ((long)(x) <= 0 ? ((long)(x)) \ 46 | : ((long) (((x) & 0x0000FFFF) | (BASE_ERRNO << 16) | 0x80000000))) 47 | 48 | #define ADDIN_E_NONE 1000 49 | #define ADDIN_E_ORDINARY 1001 50 | #define ADDIN_E_ATTENTION 1002 51 | #define ADDIN_E_IMPORTANT 1003 52 | #define ADDIN_E_VERY_IMPORTANT 1004 53 | #define ADDIN_E_INFO 1005 54 | #define ADDIN_E_FAIL 1006 55 | #define ADDIN_E_MSGBOX_ATTENTION 1007 56 | #define ADDIN_E_MSGBOX_INFO 1008 57 | #define ADDIN_E_MSGBOX_FAIL 1009 58 | 59 | #ifndef ADDIN_API 60 | #ifdef _WINDOWS 61 | #define ADDIN_API __stdcall 62 | #else 63 | //#define ADDIN_API __attribute__ ((__stdcall__)) 64 | #define ADDIN_API 65 | #endif //_WINDOWS 66 | #endif //ADDIN_API 67 | 68 | #include 69 | 70 | #ifdef _WINDOWS 71 | #define WCHAR_T wchar_t 72 | #else 73 | #define WCHAR_T uint16_t 74 | #endif //_WINDOWS 75 | typedef unsigned short TYPEVAR; 76 | enum ENUMVAR 77 | { 78 | VTYPE_EMPTY = 0, 79 | VTYPE_NULL, 80 | VTYPE_I2, //int16_t 81 | VTYPE_I4, //int32_t 82 | VTYPE_R4, //float 83 | VTYPE_R8, //double 84 | VTYPE_DATE, //DATE (double) 85 | VTYPE_TM, //struct tm 86 | VTYPE_PSTR, //struct str string 87 | VTYPE_INTERFACE, //struct iface 88 | VTYPE_ERROR, //int32_t errCode 89 | VTYPE_BOOL, //bool 90 | VTYPE_VARIANT, //struct _tVariant * 91 | VTYPE_I1, //int8_t 92 | VTYPE_UI1, //uint8_t 93 | VTYPE_UI2, //uint16_t 94 | VTYPE_UI4, //uint32_t 95 | VTYPE_I8, //int64_t 96 | VTYPE_UI8, //uint64_t 97 | VTYPE_INT, //int Depends on architecture 98 | VTYPE_UINT, //unsigned int Depends on architecture 99 | VTYPE_HRESULT, //long hRes 100 | VTYPE_PWSTR, //struct wstr 101 | VTYPE_BLOB, //means in struct str binary data contain 102 | VTYPE_CLSID, //UUID 103 | VTYPE_STR_BLOB = 0xfff, 104 | VTYPE_VECTOR = 0x1000, 105 | VTYPE_ARRAY = 0x2000, 106 | VTYPE_BYREF = 0x4000, //Only with struct _tVariant * 107 | VTYPE_RESERVED = 0x8000, 108 | VTYPE_ILLEGAL = 0xffff, 109 | VTYPE_ILLEGALMASKED = 0xfff, 110 | VTYPE_TYPEMASK = 0xfff 111 | } ; 112 | #if defined (__GNUC__) && !defined (NONAMELESSUNION) 113 | __extension__ /* no named members */ 114 | #endif 115 | struct _tVariant 116 | { 117 | _ANONYMOUS_UNION union 118 | { 119 | int8_t i8Val; 120 | int16_t shortVal; 121 | int32_t lVal; 122 | int intVal; 123 | unsigned int uintVal; 124 | int64_t llVal; 125 | uint8_t ui8Val; 126 | uint16_t ushortVal; 127 | uint32_t ulVal; 128 | uint64_t ullVal; 129 | int32_t errCode; 130 | long hRes; 131 | float fltVal; 132 | double dblVal; 133 | bool bVal; 134 | char chVal; 135 | wchar_t wchVal; 136 | DATE date; 137 | IID IDVal; 138 | struct _tVariant *pvarVal; 139 | struct tm tmVal; 140 | _ANONYMOUS_STRUCT struct 141 | { 142 | void* pInterfaceVal; 143 | IID InterfaceID; 144 | } __VARIANT_NAME_2/*iface*/; 145 | _ANONYMOUS_STRUCT struct 146 | { 147 | char* pstrVal; 148 | uint32_t strLen; //count of bytes 149 | } __VARIANT_NAME_3/*str*/; 150 | _ANONYMOUS_STRUCT struct 151 | { 152 | WCHAR_T* pwstrVal; 153 | uint32_t wstrLen; //count of symbol 154 | } __VARIANT_NAME_4/*wstr*/; 155 | } __VARIANT_NAME_1; 156 | uint32_t cbElements; //Dimension for an one-dimensional array in pvarVal 157 | TYPEVAR vt; 158 | }; 159 | typedef struct _tVariant tVariant; 160 | typedef tVariant tVariantArg; 161 | 162 | 163 | #if defined(NONAMELESSUNION) 164 | #define TV_JOIN(X, Y) ((X)->u.Y) 165 | #else 166 | #define TV_JOIN(X, Y) ((X)->Y) 167 | #endif 168 | 169 | #define TV_VT(X) ((X)->vt) 170 | #define TV_ISBYREF(X) (TV_VT(X)&VT_BYREF) 171 | #define TV_ISARRAY(X) (TV_VT(X)&VT_ARRAY) 172 | #define TV_ISVECTOR(X) (TV_VT(X)&VT_VECTOR) 173 | #define TV_NONE(X) TV_I2(X) 174 | 175 | #define TV_UI1(X) TV_JOIN(X, ui8Val) 176 | #define TV_I2(X) TV_JOIN(X, shortVal) 177 | #define TV_I4(X) TV_JOIN(X, lVal) 178 | #define TV_I8(X) TV_JOIN(X, llVal) 179 | #define TV_R4(X) TV_JOIN(X, fltVal) 180 | #define TV_R8(X) TV_JOIN(X, dblVal) 181 | #define TV_I1(X) TV_JOIN(X, i8Val) 182 | #define TV_UI2(X) TV_JOIN(X, ushortVal) 183 | #define TV_UI4(X) TV_JOIN(X, ulVal) 184 | #define TV_UI8(X) TV_JOIN(X, ullVal) 185 | #define TV_INT(X) TV_JOIN(X, intVal) 186 | #define TV_UINT(X) TV_JOIN(X, uintVal) 187 | 188 | #ifdef _WIN64 189 | #define TV_INT_PTR(X) TV_JOIN(X, llVal) 190 | #define TV_UINT_PTR(X) TV_JOIN(X, ullVal) 191 | #else 192 | #define TV_INT_PTR(X) TV_JOIN(X, lVal) 193 | #define TV_UINT_PTR(X) TV_JOIN(X, ulVal) 194 | #endif 195 | 196 | 197 | #define TV_DATE(X) TV_JOIN(X, date) 198 | #define TV_STR(X) TV_JOIN(X, pstrVal) 199 | #define TV_WSTR(X) TV_JOIN(X, pwstrVal) 200 | #define TV_BOOL(X) TV_JOIN(X, bVal) 201 | #define TV_UNKNOWN(X) TV_JOIN(X, pInterfaceVal) 202 | #define TV_VARIANTREF(X) TV_JOIN(X, pvarVal) 203 | 204 | void tVarInit(tVariant* tvar); 205 | 206 | inline 207 | void tVarInit(tVariant* tvar) 208 | { 209 | assert(tvar != NULL); 210 | memset(tvar, 0, sizeof(tVariant)); 211 | TV_VT(tvar) = VTYPE_EMPTY; 212 | } 213 | //----------------------------------------------------------------------------// 214 | // static setter functions... 215 | 216 | #define DATA_SET_BEGIN(data_) \ 217 | tVarInit(data_); 218 | 219 | #define DATA_SET_END(data_, type_) \ 220 | TV_VT(data_) = type_; 221 | 222 | 223 | #define DATA_SET(data_, type_, member_, value_) \ 224 | DATA_SET_BEGIN(data_) \ 225 | TV_JOIN(data_, member_) = value_; \ 226 | DATA_SET_END(data_, type_) 227 | 228 | #define DATA_SET_WITH_CAST(data_, type_, member_, cast_, value_) \ 229 | DATA_SET_BEGIN(data_) \ 230 | TV_JOIN(data_, member_) = cast_ value_; \ 231 | DATA_SET_END(data_, type_) 232 | 233 | #endif //__CON_TYPES_H__ 234 | -------------------------------------------------------------------------------- /src/AddInNative.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADDINNATIVE_H__ 2 | #define __ADDINNATIVE_H__ 3 | 4 | #ifdef _WINDOWS 5 | #include 6 | #endif //_WINDOWS 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "ComponentBase.h" 15 | #include "AddInDefBase.h" 16 | #include "IMemoryManager.h" 17 | 18 | class AddInNative; 19 | 20 | class DefaultHelper { 21 | private: 22 | class EmptyValue {}; 23 | public: 24 | std::variant< 25 | EmptyValue, 26 | std::u16string, 27 | int64_t, 28 | double, 29 | bool 30 | > variant; 31 | public: 32 | DefaultHelper() : variant(EmptyValue()) {} 33 | DefaultHelper(const std::u16string& s) : variant(s) {} 34 | DefaultHelper(int64_t value) : variant(value) {} 35 | DefaultHelper(double value) : variant(value) {} 36 | DefaultHelper(bool value) : variant(value) {} 37 | DefaultHelper(const char16_t* value) { 38 | if (value) variant = std::u16string(value); 39 | else variant = EmptyValue(); 40 | } 41 | }; 42 | 43 | using CompFunction = std::function; 44 | 45 | class AddInNative : public IComponentBase 46 | { 47 | private: 48 | struct Prop; 49 | struct Meth; 50 | protected: 51 | class VarinantHelper { 52 | private: 53 | tVariant* pvar = nullptr; 54 | AddInNative* addin = nullptr; 55 | Prop* prop = nullptr; 56 | Meth* meth = nullptr; 57 | long number = -1; 58 | private: 59 | std::exception error(TYPEVAR vt) const; 60 | public: 61 | void AllocMemory(unsigned long size); 62 | VarinantHelper(const VarinantHelper& va) :pvar(va.pvar), addin(va.addin), prop(va.prop), meth(va.meth), number(va.number) {} 63 | VarinantHelper(tVariant* pvar, AddInNative* addin) :pvar(pvar), addin(addin) {} 64 | VarinantHelper(tVariant* pvar, AddInNative* addin, Prop* prop) :pvar(pvar), addin(addin), prop(prop) {} 65 | VarinantHelper(tVariant* pvar, AddInNative* addin, Meth* meth, long number) :pvar(pvar), addin(addin), meth(meth), number(number) {} 66 | VarinantHelper& operator<<(const VarinantHelper& va) { pvar = va.pvar; addin = va.addin; prop = va.prop, meth = va.meth, number = va.number; return *this; } 67 | VarinantHelper& operator=(const VarinantHelper& va) = delete; 68 | VarinantHelper& operator=(const std::string& str); 69 | VarinantHelper& operator=(const std::wstring& str); 70 | VarinantHelper& operator=(const std::u16string& str); 71 | VarinantHelper& operator=(int64_t value); 72 | VarinantHelper& operator=(double value); 73 | VarinantHelper& operator=(bool value); 74 | operator std::string() const; 75 | operator std::wstring() const; 76 | operator std::u16string() const; 77 | operator int64_t() const; 78 | operator double() const; 79 | operator bool() const; 80 | operator int() const; 81 | uint32_t size(); 82 | TYPEVAR type(); 83 | char* data(); 84 | void clear(); 85 | }; 86 | 87 | using VH = VarinantHelper; 88 | using MethDefaults = std::map; 89 | using PropFunction = std::function; 90 | using MethFunction0 = std::function; 91 | using MethFunction1 = std::function; 92 | using MethFunction2 = std::function; 93 | using MethFunction3 = std::function; 94 | using MethFunction4 = std::function; 95 | using MethFunction5 = std::function; 96 | using MethFunction6 = std::function; 97 | using MethFunction7 = std::function; 98 | 99 | using MethFunction = std::variant< 100 | MethFunction0, 101 | MethFunction1, 102 | MethFunction2, 103 | MethFunction3, 104 | MethFunction4, 105 | MethFunction5, 106 | MethFunction6, 107 | MethFunction7 108 | >; 109 | 110 | void AddProperty(const std::u16string& nameEn, const std::u16string& nameRu, const PropFunction &getter, const PropFunction &setter = nullptr); 111 | void AddProcedure(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction &handler, const MethDefaults &defs = {}); 112 | void AddFunction(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction &handler, const MethDefaults &defs = {}); 113 | static std::u16string AddComponent(const std::u16string& name, CompFunction creator); 114 | VarinantHelper result; 115 | 116 | static std::u16string upper(std::u16string& str); 117 | static std::wstring upper(std::wstring& str); 118 | static std::string WCHAR2MB(std::basic_string_view src); 119 | static std::wstring WCHAR2WC(std::basic_string_view src); 120 | static std::u16string MB2WCHAR(std::string_view src); 121 | WCHAR_T* W(const char16_t* str) const; 122 | static std::string version(); 123 | 124 | private: 125 | struct Prop { 126 | std::vector names; 127 | PropFunction getter; 128 | PropFunction setter; 129 | }; 130 | 131 | struct Meth { 132 | std::vector names; 133 | MethFunction handler; 134 | MethDefaults defs; 135 | bool hasRetVal; 136 | }; 137 | 138 | bool CallMethod(MethFunction* function, tVariant* paParams, Meth* meth, const long lSizeArray); 139 | VarinantHelper VA(tVariant* pvar) { return VarinantHelper(pvar, this); } 140 | VarinantHelper VA(tVariant* pvar, Prop* prop) { return VarinantHelper(pvar, this, prop); } 141 | VarinantHelper VA(tVariant* pvar, Meth* meth, long number) { return VarinantHelper(pvar + number, this, meth, number); } 142 | bool ADDIN_API AllocMemory(void** pMemory, unsigned long ulCountByte) const; 143 | void ADDIN_API FreeMemory(void** pMemory) const; 144 | bool AddError(const std::u16string& descr, long scode = 0); 145 | 146 | friend const WCHAR_T* GetClassNames(); 147 | static std::u16string getComponentNames(); 148 | friend long GetClassObject(const WCHAR_T*, IComponentBase**); 149 | static AddInNative* CreateObject(const std::u16string& name); 150 | 151 | static std::map components; 152 | std::vector properties; 153 | std::vector methods; 154 | std::u16string name; 155 | bool alias = false; 156 | 157 | public: 158 | AddInNative(void) ; 159 | virtual ~AddInNative() {} 160 | // IInitDoneBase 161 | virtual bool ADDIN_API Init(void*) override final; 162 | virtual bool ADDIN_API setMemManager(void* mem) override final; 163 | virtual long ADDIN_API GetInfo() override final; 164 | virtual void ADDIN_API Done() override final; 165 | // ILanguageExtenderBase 166 | virtual bool ADDIN_API RegisterExtensionAs(WCHAR_T** wsLanguageExt) override final; 167 | virtual long ADDIN_API GetNProps() override final; 168 | virtual long ADDIN_API FindProp(const WCHAR_T* wsPropName) override final; 169 | virtual const WCHAR_T* ADDIN_API GetPropName(long lPropNum, long lPropAlias) override final; 170 | virtual bool ADDIN_API GetPropVal(const long lPropNum, tVariant* pvarPropVal) override final; 171 | virtual bool ADDIN_API SetPropVal(const long lPropNum, tVariant* pvarPropVal) override final; 172 | virtual bool ADDIN_API IsPropReadable(const long lPropNum) override final; 173 | virtual bool ADDIN_API IsPropWritable(const long lPropNum) override final; 174 | virtual long ADDIN_API GetNMethods() override final; 175 | virtual long ADDIN_API FindMethod(const WCHAR_T* wsMethodName) override final; 176 | virtual const WCHAR_T* ADDIN_API GetMethodName(const long lMethodNum, const long lMethodAlias) override final; 177 | virtual long ADDIN_API GetNParams(const long lMethodNum) override final; 178 | virtual bool ADDIN_API GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant* pvarParamDefValue) override final; 179 | virtual bool ADDIN_API HasRetVal(const long lMethodNum) override final; 180 | virtual bool ADDIN_API CallAsProc(const long lMethodNum, tVariant* paParams, const long lSizeArray) override final; 181 | virtual bool ADDIN_API CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) override final; 182 | operator IComponentBase* () { return (IComponentBase*)this; }; 183 | // LocaleBase 184 | virtual void ADDIN_API SetLocale(const WCHAR_T* loc) override final; 185 | private: 186 | IMemoryManager* m_iMemory = nullptr; 187 | IAddInDefBase* m_iConnect = nullptr; 188 | }; 189 | #endif //__ADDINNATIVE_H__ 190 | -------------------------------------------------------------------------------- /include/ComponentBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Warning!!! 3 | * DO NOT ALTER THIS FILE! 4 | */ 5 | 6 | 7 | #ifndef __COMPONENT_BASE_H__ 8 | #define __COMPONENT_BASE_H__ 9 | 10 | #include "types.h" 11 | //////////////////////////////////////////////////////////////////////////////// 12 | /** 13 | * The given interface is intended for initialization and 14 | * uninitialization of component and its adjustments 15 | */ 16 | /// Interface of component initialization. 17 | class IInitDoneBase 18 | { 19 | public: 20 | virtual ~IInitDoneBase() {} 21 | /// Initializes component 22 | /** 23 | * @param disp - 1C:Enterpise interface 24 | * @return the result of 25 | */ 26 | virtual bool ADDIN_API Init(void* disp) = 0; 27 | /// Sets the memory manager 28 | /* 29 | * @param mem - pointer to memory manager interface. 30 | * @return the result of 31 | */ 32 | virtual bool ADDIN_API setMemManager(void* mem) = 0; 33 | 34 | /// Returns component version 35 | /** 36 | * @return - component version (2000 - version 2) 37 | */ 38 | virtual long ADDIN_API GetInfo() = 0; 39 | 40 | /// Uninitializes component 41 | /** 42 | * Component here should release all consumed resources. 43 | */ 44 | virtual void ADDIN_API Done() = 0; 45 | 46 | }; 47 | /////////////////////////////////////////////////////////////////////////// 48 | /** 49 | * The given interface defines methods that are intented to be used by the Platform 50 | */ 51 | /// Interface describing extension of language. 52 | class ILanguageExtenderBase 53 | { 54 | public: 55 | virtual ~ILanguageExtenderBase(){} 56 | /// Registers language extension 57 | /** 58 | * @param wsExtensionName - extension name 59 | * @return the result of 60 | */ 61 | virtual bool ADDIN_API RegisterExtensionAs(WCHAR_T** wsExtensionName) = 0; 62 | 63 | /// Returns number of component properties 64 | /** 65 | * @return number of properties 66 | */ 67 | virtual long ADDIN_API GetNProps() = 0; 68 | 69 | /// Finds property by name 70 | /** 71 | * @param wsPropName - property name 72 | * @return property index or -1, if it is not found 73 | */ 74 | virtual long ADDIN_API FindProp(const WCHAR_T* wsPropName) = 0; 75 | 76 | /// Returns property name 77 | /** 78 | * @param lPropNum - property index (starting with 0) 79 | * @param lPropAlias - 0 - international alias, 80 | * 1 - russian alias. (International alias is required) 81 | * @return proeprty name or 0 if it is not found 82 | */ 83 | virtual const WCHAR_T* ADDIN_API GetPropName(long lPropNum, 84 | long lPropAlias) = 0; 85 | 86 | /// Returns property value 87 | /** 88 | * @param lPropNum - property index (starting with 0) 89 | * @param pvarPropVal - the pointer to a variable for property value 90 | * @return the result of 91 | */ 92 | virtual bool ADDIN_API GetPropVal(const long lPropNum, 93 | tVariant* pvarPropVal) = 0; 94 | 95 | /// Sets the property value 96 | /** 97 | * @param lPropNum - property index (starting with 0) 98 | * @param varPropVal - the pointer to a variable for property value 99 | * @return the result of 100 | */ 101 | virtual bool ADDIN_API SetPropVal(const long lPropNum, 102 | tVariant* varPropVal) = 0; 103 | 104 | /// Is property readable? 105 | /** 106 | * @param lPropNum - property index (starting with 0) 107 | * @return true if property is readable 108 | */ 109 | virtual bool ADDIN_API IsPropReadable(const long lPropNum) = 0; 110 | 111 | /// Is property writable? 112 | /** 113 | * @param lPropNum - property index (starting with 0) 114 | * @return true if property is writable 115 | */ 116 | virtual bool ADDIN_API IsPropWritable(const long lPropNum) = 0; 117 | 118 | /// Returns number of component methods 119 | /** 120 | * @return number of component methods 121 | */ 122 | virtual long ADDIN_API GetNMethods() = 0; 123 | 124 | /// Finds a method by name 125 | /** 126 | * @param wsMethodName - method name 127 | * @return - method index 128 | */ 129 | virtual long ADDIN_API FindMethod(const WCHAR_T* wsMethodName) = 0; 130 | 131 | /// Returns method name 132 | /** 133 | * @param lMethodNum - method index(starting with 0) 134 | * @param lMethodAlias - 0 - international alias, 135 | * 1 - russian alias. (International alias is required) 136 | * @return method name or 0 if method is not found 137 | */ 138 | virtual const WCHAR_T* ADDIN_API GetMethodName(const long lMethodNum, 139 | const long lMethodAlias) = 0; 140 | 141 | /// Returns number of method parameters 142 | /** 143 | * @param lMethodNum - method index (starting with 0) 144 | * @return number of parameters 145 | */ 146 | virtual long ADDIN_API GetNParams(const long lMethodNum) = 0; 147 | 148 | /// Returns default value of method parameter 149 | /** 150 | * @param lMethodNum - method index(starting with 0) 151 | * @param lParamNum - parameter index (starting with 0) 152 | * @param pvarParamDefValue - the pointer to a variable for default value 153 | * @return the result of 154 | */ 155 | virtual bool ADDIN_API GetParamDefValue(const long lMethodNum, 156 | const long lParamNum, 157 | tVariant *pvarParamDefValue) = 0; 158 | 159 | /// Does the method have a return value? 160 | /** 161 | * @param lMethodNum - method index (starting with 0) 162 | * @return true if the method has a return value 163 | */ 164 | virtual bool ADDIN_API HasRetVal(const long lMethodNum) = 0; 165 | 166 | /// Calls the method as a procedure 167 | /** 168 | * @param lMethodNum - method index (starting with 0) 169 | * @param paParams - the pointer to array of method parameters 170 | * @param lSizeArray - the size of array 171 | * @return the result of 172 | */ 173 | virtual bool ADDIN_API CallAsProc(const long lMethodNum, 174 | tVariant* paParams, 175 | const long lSizeArray) = 0; 176 | 177 | /// Calls the method as a function 178 | /** 179 | * @param lMethodNum - method index (starting with 0) 180 | * @param pvarRetValue - the pointer to returned value 181 | * @param paParams - the pointer to array of method parameters 182 | * @param lSizeArray - the size of array 183 | * @return the result of 184 | */ 185 | virtual bool ADDIN_API CallAsFunc(const long lMethodNum, 186 | tVariant* pvarRetValue, 187 | tVariant* paParams, 188 | const long lSizeArray) = 0; 189 | }; 190 | /////////////////////////////////////////////////////////////////////////// 191 | /** 192 | * This interface is used to change component locale 193 | */ 194 | /// Base interface for component localization. 195 | class LocaleBase 196 | { 197 | public: 198 | virtual ~LocaleBase(){} 199 | /// Changes component locale 200 | /** 201 | * @param loc - new locale (for Windows - rus_RUS, 202 | * for Linux - ru_RU, etc...) 203 | */ 204 | virtual void ADDIN_API SetLocale(const WCHAR_T* loc) = 0; 205 | }; 206 | 207 | /////////////////////////////////////////////////////////////////////////// 208 | /** 209 | * The given interface is generalized, for its obligatory inheritance 210 | * in implementing components. 211 | */ 212 | /// Base interface describing object as a set of properties and methods. 213 | class IComponentBase : 214 | public IInitDoneBase, 215 | public ILanguageExtenderBase, 216 | public LocaleBase 217 | { 218 | public: 219 | virtual ~IComponentBase(){} 220 | }; 221 | 222 | enum AppCapabilities 223 | { 224 | eAppCapabilitiesInvalid = -1, 225 | eAppCapabilities1 = 1, 226 | eAppCapabilitiesLast = eAppCapabilities1, 227 | }; 228 | 229 | /// Announcements of exported functions 230 | /** 231 | * These functions should be implemented that component can be loaded and created. 232 | */ 233 | extern "C" long GetClassObject(const WCHAR_T*, IComponentBase** pIntf); 234 | extern "C" long DestroyObject(IComponentBase** pIntf); 235 | extern "C" const WCHAR_T* GetClassNames(); 236 | extern "C" AppCapabilities SetPlatformCapabilities(const AppCapabilities capabilities); 237 | 238 | typedef long (*GetClassObjectPtr)(const WCHAR_T* wsName, IComponentBase** pIntf); 239 | typedef long (*DestroyObjectPtr)(IComponentBase** pIntf); 240 | typedef const WCHAR_T* (*GetClassNamesPtr)(); 241 | typedef AppCapabilities (*SetPlatformCapabilitiesPtr)(const AppCapabilities capabilities); 242 | 243 | #endif //__COMPONENT_BASE_H__ 244 | -------------------------------------------------------------------------------- /tools/Decompile.os: -------------------------------------------------------------------------------- 1 | #Использовать v8runner 2 | #Использовать logos 3 | 4 | Перем Лог; 5 | Перем УправлениеКонфигуратором; 6 | 7 | Функция ДатуКСтроке(Дат) 8 | Возврат Формат(Дат,"ДФ=yyyy.MM.dd.HH.mm.ss"); 9 | КонецФункции 10 | 11 | // Перемещаят найденные по маскам файлы с сохранением пути. 12 | // 13 | // Параметры: 14 | // КаталогКуда - Строка - Путь к каталогу в который переносятся файлы; 15 | // КаталогиОткуда - Массив - Пути к каталогам в которых осуществляется поиск файлов; 16 | // МассивМасок - Массив - Маски, по которым осуществляется поиск файлов. 17 | // УдалятьВременныеКаталоги - Булево - удалять служебные каталоги разборки файлов в исходном месте. 18 | // 19 | // Взято из https://infostart.ru/public/537028/ 20 | Процедура ПереместитьФайлыВКаталог(КаталогКуда, КаталогиОткуда, МассивМасок, УдалятьВременныеКаталоги = Ложь) 21 | 22 | Для Каждого КаталогПоиска Из КаталогиОткуда Цикл 23 | 24 | КаталогПоискаОбъект = Новый Файл(КаталогПоиска); 25 | 26 | Если НЕ КаталогПоискаОбъект.Существует() Тогда 27 | 28 | Лог.Ошибка(НСтр("ru = 'Каталог не найден.'")); 29 | Продолжить; 30 | 31 | КонецЕсли; 32 | 33 | Для Каждого Маска Из МассивМасок Цикл 34 | 35 | МассивФайлов = НайтиФайлы(КаталогПоиска, Маска, Истина); 36 | 37 | Для Каждого НайденныйФайл Из МассивФайлов Цикл 38 | 39 | НовыйПуть = СтрЗаменить(НайденныйФайл.Путь, КаталогПоиска, КаталогКуда); 40 | НовоеИмя = НайденныйФайл.Имя; 41 | 42 | Если НЕ ОбеспечитьКаталог(НовыйПуть) Тогда 43 | Продолжить; 44 | КонецЕсли; 45 | 46 | Если НайденныйФайл.ЭтоКаталог() Тогда 47 | Продолжить; 48 | КонецЕсли; 49 | 50 | 51 | ИмяФайлаДляПеремещения = ОбъединитьПути(НовыйПуть, НовоеИмя); 52 | УдалитьФайлы(ИмяФайлаДляПеремещения); 53 | 54 | Попытка 55 | ПереместитьФайл(НайденныйФайл.ПолноеИмя,ИмяФайлаДляПеремещения); 56 | Исключение 57 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось переместить файл: 58 | |%1'"), ОписаниеОшибки())); 59 | Продолжить; 60 | КонецПопытки; 61 | 62 | ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя)); 63 | Если НЕ ФайлНаДиске.Существует() Тогда 64 | Лог.Ошибка(НСтр("ru = 'Не удалось корректно переместить файл.'")); 65 | Продолжить; 66 | КонецЕсли; 67 | 68 | КонецЦикла; 69 | 70 | КонецЦикла; 71 | 72 | КонецЦикла; 73 | 74 | КонецПроцедуры 75 | 76 | // Проверяет наличия каталога и в случае его отсутствия создает новый. 77 | // 78 | // Параметры: 79 | // Каталог - Строка - Путь к каталогу, существование которого нужно проверить. 80 | // 81 | // Возвращаемое значение: 82 | // Булево - признак существования каталога. 83 | // 84 | // Взято из https://infostart.ru/public/537028/ 85 | Функция ОбеспечитьКаталог(Знач Каталог) 86 | 87 | Файл = Новый Файл(Каталог); 88 | Если Не Файл.Существует() Тогда 89 | Попытка 90 | СоздатьКаталог(Каталог); 91 | Исключение 92 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1. 93 | |%2'"), Каталог, ИнформацияОбОшибке())); 94 | Возврат Ложь; 95 | КонецПопытки; 96 | ИначеЕсли Не Файл.ЭтоКаталог() Тогда 97 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Каталог %1 не является каталогом.'"), Каталог)); 98 | Возврат Ложь; 99 | КонецЕсли; 100 | 101 | Возврат Истина; 102 | 103 | КонецФункции 104 | 105 | Процедура ВыгрузитьФайлВXML(ИмяФайла,ВерсииВсехФайлов) 106 | ФайлОбработкиИлиОтчета = Новый Файл(ИмяФайла); 107 | ВремяИзменения = ДатуКСтроке(ФайлОбработкиИлиОтчета.ПолучитьВремяИзменения()); 108 | 109 | Если ВремяИзменения = ВерсииВсехФайлов[НРег(ФайлОбработкиИлиОтчета.ПолноеИмя)] Тогда 110 | Лог.Информация("Файл уже распакован."); 111 | Возврат; 112 | КонецЕсли; 113 | 114 | 115 | ВременныйКаталог = ПолучитьИмяВременногоФайла(); 116 | СоздатьКаталог(ВременныйКаталог); 117 | 118 | ПараметрыЗапуска = УправлениеКонфигуратором.ПолучитьПараметрыЗапуска(); 119 | ПараметрыЗапуска.Добавить("/DumpExternalDataProcessorOrReportToFiles """ + ВременныйКаталог + """ """ + ИмяФайла + """"); 120 | 121 | ИмяФайлаOut = ПолучитьИмяВременногоФайла("txt"); 122 | ПараметрыЗапуска.Добавить("/Out """ + ИмяФайлаOut + """"); 123 | 124 | 125 | Попытка 126 | УправлениеКонфигуратором.ВыполнитьКоманду(ПараметрыЗапуска); 127 | Исключение 128 | Лог.Ошибка(ОписаниеОшибки()); 129 | Лог.Ошибка(УправлениеКонфигуратором.ВыводКоманды()); 130 | ВызватьИсключение "Выгрузка обработок в xml прервана."; 131 | КонецПопытки; 132 | 133 | 134 | ФайлXMLВКаталогеРаспаковки = НайтиФайлы(ВременныйКаталог,"*.xml",Ложь); 135 | Если ФайлXMLВКаталогеРаспаковки.Количество() <> 1 Тогда 136 | ВызватьИсключение "В каталоге распаковки найдено " + ФайлXMLВКаталогеРаспаковки.Количество() + " файлов xml, а должен быть только один."; 137 | КонецЕсли; 138 | 139 | ФайлXmlОбработки = ФайлXMLВКаталогеРаспаковки[0]; 140 | ИмяКаталогаОбработки = ФайлXmlОбработки.ИмяБезРасширения; 141 | 142 | КаталогиОткуда = Новый Массив; 143 | КаталогиОткуда.Добавить(ВременныйКаталог); 144 | МассивМасок = Новый Массив; 145 | МассивМасок.Добавить("*.*"); 146 | ПереместитьФайлыВКаталог(ФайлОбработкиИлиОтчета.Путь,КаталогиОткуда,МассивМасок); 147 | 148 | 149 | //запишем реальное имя файла 150 | ИмяОбработкиИлиОтчета = ФайлОбработкиИлиОтчета.Имя; 151 | 152 | 153 | КаталогГдеЛежатФайлыОбработкиИлиОтчета = ФайлОбработкиИлиОтчета.Путь + ПолучитьРазделительПути()+ ИмяКаталогаОбработки; 154 | ФайлКаталогГдеЛежатФайлыОбработкиИлиОтчета = Новый Файл(КаталогГдеЛежатФайлыОбработкиИлиОтчета); 155 | Если Не ФайлКаталогГдеЛежатФайлыОбработкиИлиОтчета.Существует() Тогда 156 | СоздатьКаталог(КаталогГдеЛежатФайлыОбработкиИлиОтчета); 157 | КонецЕсли; 158 | 159 | ИмяФайлаИмяОбработкиИлиОтчета = ФайлОбработкиИлиОтчета.Путь + ПолучитьРазделительПути()+ ИмяКаталогаОбработки + ПолучитьРазделительПути() + "filename"; 160 | ФайлИмяФайлаИмяОбработкиИлиОтчета = Новый Файл(ИмяФайлаИмяОбработкиИлиОтчета); 161 | Если ФайлИмяФайлаИмяОбработкиИлиОтчета.Существует() Тогда 162 | УдалитьФайлы(ИмяФайлаИмяОбработкиИлиОтчета); 163 | КонецЕсли; 164 | 165 | 166 | 167 | ЗТ = Новый ЗаписьТекста(ИмяФайлаИмяОбработкиИлиОтчета,"UTF-8",,Истина); 168 | ЗТ.Записать(ИмяОбработкиИлиОтчета); 169 | ЗТ.Закрыть(); 170 | 171 | //запишем версию файла 172 | ЗаписатьВерсиюОбработкиИлиОчета(ФайлОбработкиИлиОтчета,ИмяКаталогаОбработки,ИмяОбработкиИлиОтчета); 173 | 174 | 175 | Попытка 176 | УдалитьФайлы(ВременныйКаталог); 177 | Исключение 178 | КонецПопытки; 179 | 180 | КонецПроцедуры 181 | 182 | Функция ПолучитьВерсииФайловВКаталоге(Каталог) 183 | //Сообщить("Каталог="+Каталог); 184 | 185 | ТаблицаФайлов = Новый ТаблицаЗначений; 186 | ТаблицаФайлов.Колонки.Добавить("ПолноеИмя"); 187 | ТаблицаФайлов.Колонки.Добавить("ЧастьПути"); 188 | ТаблицаФайлов.Колонки.Добавить("ЭтоКаталог"); 189 | ТаблицаФайлов.Колонки.Добавить("ВремяИзменения"); 190 | 191 | Файлы = НайтиФайлы(Каталог,"*",Истина); 192 | Для Каждого Файл Из Файлы Цикл 193 | Если Нрег(Файл.Имя) = "filename" Тогда 194 | Продолжить; 195 | ИначеЕсли Нрег(Файл.Имя) = "fileversion" Тогда 196 | Продолжить; 197 | КонецЕсли; 198 | 199 | СтрокаТаблицаФайлов = ТаблицаФайлов.Добавить(); 200 | СтрокаТаблицаФайлов.ПолноеИмя = Файл.ПолноеИмя; 201 | СтрокаТаблицаФайлов.ЭтоКаталог = Файл.ЭтоКаталог(); 202 | СтрокаТаблицаФайлов.ЧастьПути = Сред(Файл.ПолноеИмя,СтрДлина(Каталог)); 203 | 204 | //Сообщить("СтрокаТаблицаФайлов.ЧастьПути="+СтрокаТаблицаФайлов.ЧастьПути); 205 | 206 | Если СтрокаТаблицаФайлов.ЭтоКаталог Тогда 207 | Продолжить; 208 | КонецЕсли; 209 | 210 | СтрокаТаблицаФайлов.ВремяИзменения = ДатуКСтроке(Файл.ПолучитьВремяИзменения()); 211 | КонецЦикла; 212 | 213 | Возврат ТаблицаФайлов; 214 | КонецФункции 215 | 216 | Процедура ЗаписатьВерсиюОбработкиИлиОчета(ФайлОбработкиИлиОтчета,ИмяКаталогаОбработки,ИмяОбработкиИлиОтчета) 217 | ИмяФайлаВерсии = ФайлОбработкиИлиОтчета.Путь + ИмяКаталогаОбработки + ПолучитьРазделительПути() + "fileversion"; 218 | УдалитьФайлы(ИмяФайлаВерсии); 219 | ВремяИзменения = ДатуКСтроке(ФайлОбработкиИлиОтчета.ПолучитьВремяИзменения()); 220 | 221 | ВерсииФайлов = ПолучитьВерсииФайловВКаталоге(ФайлОбработкиИлиОтчета.Путь + ИмяКаталогаОбработки + ПолучитьРазделительПути()); 222 | 223 | ЗТ = Новый ЗаписьТекста(ИмяФайлаВерсии,"UTF-8",,Истина); 224 | ЗТ.ЗаписатьСтроку(ВремяИзменения + "|" + ИмяОбработкиИлиОтчета); 225 | 226 | Для Каждого СтрокаВерсииФайлов Из ВерсииФайлов Цикл 227 | Если СтрокаВерсииФайлов.ЭтоКаталог Тогда 228 | Продолжить; 229 | КонецЕсли; 230 | 231 | Стр = "" + СтрокаВерсииФайлов.ВремяИзменения + "|" + СтрокаВерсииФайлов.ЧастьПути; 232 | ЗТ.ЗаписатьСтроку(Стр); 233 | КонецЦикла; 234 | 235 | ЗТ.Закрыть(); 236 | КонецПроцедуры 237 | 238 | Функция ВерсииВсехФайлов(Файлы) 239 | Версии = Новый Соответствие; 240 | 241 | Для Каждого Файл Из Файлы Цикл 242 | Текст = Новый ЧтениеТекста; 243 | Текст.Открыть(Файл.ПолноеИмя,"UTF-8"); 244 | 245 | 246 | Массив = Новый Массив; 247 | 248 | Пока Истина Цикл 249 | Стр = Текст.ПрочитатьСтроку(); 250 | Если Стр = Неопределено Тогда 251 | Прервать; 252 | КонецЕсли; 253 | 254 | Массив.Добавить(Стр); 255 | КонецЦикла; 256 | 257 | Текст.Закрыть(); 258 | 259 | Если Массив.Количество() < 1 Тогда 260 | ВызватьИсключение "Не смог прочитать файл версии: " + Файл.ПолноеИм; 261 | КонецЕсли; 262 | 263 | Поз = Найти(Массив[0],"|"); 264 | ВерсияСтрокой = Лев(Массив[0],Поз-1); 265 | ИмяИзСтроки = Сред(Массив[0],Поз+1); 266 | 267 | ПутьКОбработкеИлиОтчету = Новый Файл(Файл.Путь); 268 | 269 | ИмяОбработкиИлиОтчета = НРег(ПутьКОбработкеИлиОтчету.Путь + ИмяИзСтроки); 270 | 271 | Версии.Вставить(ИмяОбработкиИлиОтчета,ВерсияСтрокой); 272 | КонецЦикла; 273 | 274 | Возврат Версии; 275 | КонецФункции 276 | 277 | Процедура РаспаковатьФайлыПоМаске(Путь,Маска,ИскатьВПодкаталогах) 278 | Файлы = НайтиФайлы(Путь,Маска,ИскатьВПодкаталогах); 279 | Файлыfileversion = НайтиФайлы(Путь,"fileversion",ИскатьВПодкаталогах); 280 | ВерсииВсехФайлов = ВерсииВсехФайлов(Файлыfileversion); 281 | 282 | КоличествоФайлов = Файлы.Количество(); 283 | НомерФайла = 0; 284 | Для Каждого Файл Из Файлы Цикл 285 | НомерФайла = НомерФайла + 1; 286 | Лог.Информация("Файл " + НомерФайла + " из " + КоличествоФайлов + ": " + Файл.ПолноеИмя); 287 | 288 | ВыгрузитьФайлВXML(Файл.ПолноеИмя,ВерсииВсехФайлов); 289 | КонецЦикла; 290 | 291 | КонецПроцедуры 292 | 293 | Процедура РазобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(Путь) 294 | Файл = Новый Файл(Путь); 295 | Если НЕ Файл.Существует() Тогда 296 | ВызватьИсключение "Каталог <" + Путь + "> не существует."; 297 | КонецЕсли; 298 | 299 | РаспаковатьФайлыПоМаске(Путь,"*.erf",Истина); 300 | РаспаковатьФайлыПоМаске(Путь,"*.epf",Истина); 301 | КонецПроцедуры 302 | 303 | Функция ПереместитьФайлыДляРазборки(КаталогКудаОбъект, КаталогОткудаОбъект, Маска, МассивУдаляемыхВременныхФайлов) 304 | 305 | МассивПеремещения = НайтиФайлы(КаталогОткудаОбъект.ПолноеИмя, Маска, Истина); 306 | 307 | Для каждого ЭлементМассиваПеремещения из МассивПеремещения Цикл 308 | 309 | ПолноеИмяФайлаОткуда = ЭлементМассиваПеремещения.ПолноеИмя; 310 | КороткоеИмяФайлаОткуда = ЭлементМассиваПеремещения.Имя; 311 | ОтносительноеИмя = СтрЗаменить(ПолноеИмяФайлаОткуда, КаталогОткудаОбъект.ПолноеИмя, ""); 312 | ИмяНовогоКаталога = СтрЗаменить(КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя, КороткоеИмяФайлаОткуда, ""); 313 | 314 | Если НЕ ОбеспечитьКаталог(ИмяНовогоКаталога) Тогда 315 | Продолжить; 316 | КонецЕсли; 317 | 318 | КопироватьФайл(ПолноеИмяФайлаОткуда, КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя); 319 | МассивУдаляемыхВременныхФайлов.Добавить(КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя); 320 | //Лог.Информация("Копируем " + ПолноеИмяФайлаОткуда + " в " + КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя); 321 | КонецЦикла; 322 | 323 | Возврат МассивУдаляемыхВременныхФайлов; 324 | 325 | КонецФункции 326 | 327 | Лог = Логирование.ПолучитьЛог("vb.decompile.log"); 328 | Лог.УстановитьУровень(УровниЛога.Отладка); 329 | 330 | Если АргументыКоманднойСтроки.Количество() = 0 Тогда 331 | Лог.Ошибка("Не переданы параметры!"); 332 | ИначеЕсли АргументыКоманднойСтроки.Количество() > 2 Тогда 333 | Лог.Ошибка("Скрипт принимает не больше двух параметров!"); 334 | Иначе 335 | УправлениеКонфигуратором = Новый УправлениеКонфигуратором(); 336 | 337 | ПутьКВерсииПлатформы8310 = УправлениеКонфигуратором.ПолучитьПутьКВерсииПлатформы("8.3.10"); 338 | УправлениеКонфигуратором.ПутьКПлатформе1С(ПутьКВерсииПлатформы8310); 339 | 340 | КаталогБазы = ПолучитьИмяВременногоФайла(); 341 | УправлениеКонфигуратором.СоздатьФайловуюБазу(КаталогБазы); 342 | УправлениеКонфигуратором.УстановитьКонтекст("/F""" + КаталогБазы + """","",""); 343 | 344 | Если АргументыКоманднойСтроки.Количество() = 2 Тогда 345 | 346 | МассивУдаляемыхВременныхФайлов = Новый Массив; 347 | КаталогКудаОбъект = Новый Файл(АргументыКоманднойСтроки[1]); 348 | КаталогОткудаОбъект = Новый Файл(АргументыКоманднойСтроки[0]); 349 | МассивУдаляемыхВременныхФайлов = ПереместитьФайлыДляРазборки(КаталогКудаОбъект,КаталогОткудаОбъект, "*.epf", МассивУдаляемыхВременныхФайлов); 350 | МассивУдаляемыхВременныхФайлов = ПереместитьФайлыДляРазборки(КаталогКудаОбъект,КаталогОткудаОбъект, "*.erf", МассивУдаляемыхВременныхФайлов); 351 | РазобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(КаталогКудаОбъект.ПолноеИмя); 352 | 353 | Для каждого ВременныйФайл из МассивУдаляемыхВременныхФайлов Цикл 354 | УдалитьФайлы(ВременныйФайл); 355 | КонецЦикла; 356 | 357 | Иначе 358 | РазобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(АргументыКоманднойСтроки[0]); 359 | КонецЕсли; 360 | 361 | КонецЕсли; 362 | 363 | Сообщить("Обработка завершена."); 364 | 365 | 366 | 367 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 2.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 5 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial content 12 | Distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | i) changes to the Program, and 16 | ii) additions to the Program; 17 | where such changes and/or additions to the Program originate from 18 | and are Distributed by that particular Contributor. A Contribution 19 | "originates" from a Contributor if it was added to the Program by 20 | such Contributor itself or anyone acting on such Contributor's behalf. 21 | Contributions do not include changes or additions to the Program that 22 | are not Modified Works. 23 | 24 | "Contributor" means any person or entity that Distributes the Program. 25 | 26 | "Licensed Patents" mean patent claims licensable by a Contributor which 27 | are necessarily infringed by the use or sale of its Contribution alone 28 | or when combined with the Program. 29 | 30 | "Program" means the Contributions Distributed in accordance with this 31 | Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement 34 | or any Secondary License (as applicable), including Contributors. 35 | 36 | "Derivative Works" shall mean any work, whether in Source Code or other 37 | form, that is based on (or derived from) the Program and for which the 38 | editorial revisions, annotations, elaborations, or other modifications 39 | represent, as a whole, an original work of authorship. 40 | 41 | "Modified Works" shall mean any work in Source Code or other form that 42 | results from an addition to, deletion from, or modification of the 43 | contents of the Program, including, for purposes of clarity any new file 44 | in Source Code form that contains any contents of the Program. Modified 45 | Works shall not include works that contain only declarations, 46 | interfaces, types, classes, structures, or files of the Program solely 47 | in each case in order to link to, bind by name, or subclass the Program 48 | or Modified Works thereof. 49 | 50 | "Distribute" means the acts of a) distributing or b) making available 51 | in any manner that enables the transfer of a copy. 52 | 53 | "Source Code" means the form of a Program preferred for making 54 | modifications, including but not limited to software source code, 55 | documentation source, and configuration files. 56 | 57 | "Secondary License" means either the GNU General Public License, 58 | Version 2.0, or any later versions of that license, including any 59 | exceptions or additional permissions as identified by the initial 60 | Contributor. 61 | 62 | 2. GRANT OF RIGHTS 63 | 64 | a) Subject to the terms of this Agreement, each Contributor hereby 65 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 66 | license to reproduce, prepare Derivative Works of, publicly display, 67 | publicly perform, Distribute and sublicense the Contribution of such 68 | Contributor, if any, and such Derivative Works. 69 | 70 | b) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free patent 72 | license under Licensed Patents to make, use, sell, offer to sell, 73 | import and otherwise transfer the Contribution of such Contributor, 74 | if any, in Source Code or other form. This patent license shall 75 | apply to the combination of the Contribution and the Program if, at 76 | the time the Contribution is added by the Contributor, such addition 77 | of the Contribution causes such combination to be covered by the 78 | Licensed Patents. The patent license shall not apply to any other 79 | combinations which include the Contribution. No hardware per se is 80 | licensed hereunder. 81 | 82 | c) Recipient understands that although each Contributor grants the 83 | licenses to its Contributions set forth herein, no assurances are 84 | provided by any Contributor that the Program does not infringe the 85 | patent or other intellectual property rights of any other entity. 86 | Each Contributor disclaims any liability to Recipient for claims 87 | brought by any other entity based on infringement of intellectual 88 | property rights or otherwise. As a condition to exercising the 89 | rights and licenses granted hereunder, each Recipient hereby 90 | assumes sole responsibility to secure any other intellectual 91 | property rights needed, if any. For example, if a third party 92 | patent license is required to allow Recipient to Distribute the 93 | Program, it is Recipient's responsibility to acquire that license 94 | before distributing the Program. 95 | 96 | d) Each Contributor represents that to its knowledge it has 97 | sufficient copyright rights in its Contribution, if any, to grant 98 | the copyright license set forth in this Agreement. 99 | 100 | e) Notwithstanding the terms of any Secondary License, no 101 | Contributor makes additional grants to any Recipient (other than 102 | those set forth in this Agreement) as a result of such Recipient's 103 | receipt of the Program under the terms of a Secondary License 104 | (if permitted under the terms of Section 3). 105 | 106 | 3. REQUIREMENTS 107 | 108 | 3.1 If a Contributor Distributes the Program in any form, then: 109 | 110 | a) the Program must also be made available as Source Code, in 111 | accordance with section 3.2, and the Contributor must accompany 112 | the Program with a statement that the Source Code for the Program 113 | is available under this Agreement, and informs Recipients how to 114 | obtain it in a reasonable manner on or through a medium customarily 115 | used for software exchange; and 116 | 117 | b) the Contributor may Distribute the Program under a license 118 | different than this Agreement, provided that such license: 119 | i) effectively disclaims on behalf of all other Contributors all 120 | warranties and conditions, express and implied, including 121 | warranties or conditions of title and non-infringement, and 122 | implied warranties or conditions of merchantability and fitness 123 | for a particular purpose; 124 | 125 | ii) effectively excludes on behalf of all other Contributors all 126 | liability for damages, including direct, indirect, special, 127 | incidental and consequential damages, such as lost profits; 128 | 129 | iii) does not attempt to limit or alter the recipients' rights 130 | in the Source Code under section 3.2; and 131 | 132 | iv) requires any subsequent distribution of the Program by any 133 | party to be under a license that satisfies the requirements 134 | of this section 3. 135 | 136 | 3.2 When the Program is Distributed as Source Code: 137 | 138 | a) it must be made available under this Agreement, or if the 139 | Program (i) is combined with other material in a separate file or 140 | files made available under a Secondary License, and (ii) the initial 141 | Contributor attached to the Source Code the notice described in 142 | Exhibit A of this Agreement, then the Program may be made available 143 | under the terms of such Secondary Licenses, and 144 | 145 | b) a copy of this Agreement must be included with each copy of 146 | the Program. 147 | 148 | 3.3 Contributors may not remove or alter any copyright, patent, 149 | trademark, attribution notices, disclaimers of warranty, or limitations 150 | of liability ("notices") contained within the Program from any copy of 151 | the Program which they Distribute, provided that Contributors may add 152 | their own appropriate notices. 153 | 154 | 4. COMMERCIAL DISTRIBUTION 155 | 156 | Commercial distributors of software may accept certain responsibilities 157 | with respect to end users, business partners and the like. While this 158 | license is intended to facilitate the commercial use of the Program, 159 | the Contributor who includes the Program in a commercial product 160 | offering should do so in a manner which does not create potential 161 | liability for other Contributors. Therefore, if a Contributor includes 162 | the Program in a commercial product offering, such Contributor 163 | ("Commercial Contributor") hereby agrees to defend and indemnify every 164 | other Contributor ("Indemnified Contributor") against any losses, 165 | damages and costs (collectively "Losses") arising from claims, lawsuits 166 | and other legal actions brought by a third party against the Indemnified 167 | Contributor to the extent caused by the acts or omissions of such 168 | Commercial Contributor in connection with its distribution of the Program 169 | in a commercial product offering. The obligations in this section do not 170 | apply to any claims or Losses relating to any actual or alleged 171 | intellectual property infringement. In order to qualify, an Indemnified 172 | Contributor must: a) promptly notify the Commercial Contributor in 173 | writing of such claim, and b) allow the Commercial Contributor to control, 174 | and cooperate with the Commercial Contributor in, the defense and any 175 | related settlement negotiations. The Indemnified Contributor may 176 | participate in any such claim at its own expense. 177 | 178 | For example, a Contributor might include the Program in a commercial 179 | product offering, Product X. That Contributor is then a Commercial 180 | Contributor. If that Commercial Contributor then makes performance 181 | claims, or offers warranties related to Product X, those performance 182 | claims and warranties are such Commercial Contributor's responsibility 183 | alone. Under this section, the Commercial Contributor would have to 184 | defend claims against the other Contributors related to those performance 185 | claims and warranties, and if a court requires any other Contributor to 186 | pay any damages as a result, the Commercial Contributor must pay 187 | those damages. 188 | 189 | 5. NO WARRANTY 190 | 191 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 192 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 193 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 194 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 195 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 196 | PURPOSE. Each Recipient is solely responsible for determining the 197 | appropriateness of using and distributing the Program and assumes all 198 | risks associated with its exercise of rights under this Agreement, 199 | including but not limited to the risks and costs of program errors, 200 | compliance with applicable laws, damage to or loss of data, programs 201 | or equipment, and unavailability or interruption of operations. 202 | 203 | 6. DISCLAIMER OF LIABILITY 204 | 205 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 206 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 207 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 209 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 210 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 211 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 212 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 213 | POSSIBILITY OF SUCH DAMAGES. 214 | 215 | 7. GENERAL 216 | 217 | If any provision of this Agreement is invalid or unenforceable under 218 | applicable law, it shall not affect the validity or enforceability of 219 | the remainder of the terms of this Agreement, and without further 220 | action by the parties hereto, such provision shall be reformed to the 221 | minimum extent necessary to make such provision valid and enforceable. 222 | 223 | If Recipient institutes patent litigation against any entity 224 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 225 | Program itself (excluding combinations of the Program with other software 226 | or hardware) infringes such Recipient's patent(s), then such Recipient's 227 | rights granted under Section 2(b) shall terminate as of the date such 228 | litigation is filed. 229 | 230 | All Recipient's rights under this Agreement shall terminate if it 231 | fails to comply with any of the material terms or conditions of this 232 | Agreement and does not cure such failure in a reasonable period of 233 | time after becoming aware of such noncompliance. If all Recipient's 234 | rights under this Agreement terminate, Recipient agrees to cease use 235 | and distribution of the Program as soon as reasonably practicable. 236 | However, Recipient's obligations under this Agreement and any licenses 237 | granted by Recipient relating to the Program shall continue and survive. 238 | 239 | Everyone is permitted to copy and distribute copies of this Agreement, 240 | but in order to avoid inconsistency the Agreement is copyrighted and 241 | may only be modified in the following manner. The Agreement Steward 242 | reserves the right to publish new versions (including revisions) of 243 | this Agreement from time to time. No one other than the Agreement 244 | Steward has the right to modify this Agreement. The Eclipse Foundation 245 | is the initial Agreement Steward. The Eclipse Foundation may assign the 246 | responsibility to serve as the Agreement Steward to a suitable separate 247 | entity. Each new version of the Agreement will be given a distinguishing 248 | version number. The Program (including Contributions) may always be 249 | Distributed subject to the version of the Agreement under which it was 250 | received. In addition, after a new version of the Agreement is published, 251 | Contributor may elect to Distribute the Program (including its 252 | Contributions) under the new version. 253 | 254 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 255 | receives no rights or licenses to the intellectual property of any 256 | Contributor under this Agreement, whether expressly, by implication, 257 | estoppel or otherwise. All rights in the Program not expressly granted 258 | under this Agreement are reserved. Nothing in this Agreement is intended 259 | to be enforceable by any entity that is not a Contributor or Recipient. 260 | No third-party beneficiary rights are created under this Agreement. 261 | 262 | Exhibit A - Form of Secondary Licenses Notice 263 | 264 | "This Source Code may also be made available under the following 265 | Secondary Licenses when the conditions for such availability set forth 266 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 267 | version(s), and exceptions or additional permissions here}." 268 | 269 | Simply including a copy of this Agreement, including this Exhibit A 270 | is not sufficient to license the Source Code under Secondary Licenses. 271 | 272 | If it is not possible or desirable to put the notice in a particular 273 | file, then You may include the notice in a location (such as a LICENSE 274 | file in a relevant directory) where a recipient would be likely to 275 | look for such a notice. 276 | 277 | You may add additional accurate notices of copyright ownership. 278 | -------------------------------------------------------------------------------- /Example/Forms/Form/Ext/Form/Module.bsl: -------------------------------------------------------------------------------- 1 | &НаКлиенте 2 | Перем ИдентификаторКомпоненты, ВнешняяКомпонента, ДанныеГрафа, ТекущийПуть; 3 | 4 | &НаСервере 5 | Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) 6 | 7 | ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); 8 | МакетКомпоненты = ОбработкаОбъект.ПолучитьМакет("GraphViz1C"); 9 | АдресКомпоненты = ПоместитьВоВременноеХранилище(МакетКомпоненты, УникальныйИдентификатор); 10 | 11 | КонецПроцедуры 12 | 13 | &НаКлиенте 14 | Процедура ПриОткрытии(Отказ) 15 | 16 | ИдентификаторКомпоненты = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); 17 | ВыполнитьПодключениеВнешнейКомпоненты(Истина); 18 | 19 | ДанныеГрафа = " 20 | |digraph G { 21 | | node [shape=box]; 22 | | Корень -> Распознать -> Выполнить; 23 | | Корень -> Инициализация; 24 | | Корень -> Очистить; 25 | | Выполнить -> Получить; 26 | | Выполнить -> Распечатать 27 | | Инициализация -> Получить; 28 | | Корень -> Распечатать; 29 | | Выполнить -> Сравнить; 30 | |} 31 | |"; 32 | 33 | КонецПроцедуры 34 | 35 | &НаКлиенте 36 | Процедура ВыполнитьПодключениеВнешнейКомпоненты(ДополнительныеПараметры) Экспорт 37 | 38 | ОписаниеОповещения = Новый ОписаниеОповещения("ПодключениеВнешнейКомпонентыЗавершение", ЭтаФорма, ДополнительныеПараметры); 39 | НачатьПодключениеВнешнейКомпоненты(ОписаниеОповещения, АдресКомпоненты, ИдентификаторКомпоненты, ТипВнешнейКомпоненты.Native); 40 | 41 | КонецПроцедуры 42 | 43 | &НаКлиенте 44 | Процедура ПодключениеВнешнейКомпонентыЗавершение(Подключение, ДополнительныеПараметры) Экспорт 45 | 46 | Если Подключение Тогда 47 | ВнешняяКомпонента = Новый("AddIn." + ИдентификаторКомпоненты + ".GraphViz1C"); 48 | ОписаниеОповещения = Новый ОписаниеОповещения("ПолученаВерсияКомпоненты", ЭтаФорма); 49 | ВнешняяКомпонента.НачатьПолучениеВерсия(ОписаниеОповещения); 50 | ИначеЕсли ДополнительныеПараметры = Истина Тогда 51 | ОписаниеОповещения = Новый ОписаниеОповещения("ВыполнитьПодключениеВнешнейКомпоненты", ЭтаФорма, Ложь); 52 | НачатьУстановкуВнешнейКомпоненты(ОписаниеОповещения, АдресКомпоненты); 53 | КонецЕсли; 54 | 55 | КонецПроцедуры 56 | 57 | &НаКлиенте 58 | Процедура ПолученаВерсияКомпоненты(Значение, ДополнительныеПараметры) Экспорт 59 | 60 | Заголовок = "GraphViz1C, версия " + Значение; 61 | СформироватьКартинку(); 62 | 63 | КонецПроцедуры 64 | 65 | &НаКлиенте 66 | Процедура СформироватьКартинку() 67 | 68 | ОписаниеОповещения = Новый ОписаниеОповещения("ПолученаКартинка", ЭтаФорма); 69 | ВнешняяКомпонента.НачатьВызовСформировать(ОписаниеОповещения, ДанныеГрафа, "svg"); 70 | 71 | КонецПроцедуры 72 | 73 | &НаКлиенте 74 | Процедура ПолученаКартинка(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт 75 | 76 | Если ТипЗнч(РезультатВызова) = Тип("ДвоичныеДанные") Тогда 77 | СформироватьHTML(РезультатВызова); 78 | ИначеЕсли ТипЗнч(РезультатВызова) = Тип("Строка") Тогда 79 | Сообщить(РезультатВызова); 80 | КонецЕсли; 81 | 82 | КонецПроцедуры 83 | 84 | &НаКлиенте 85 | Процедура СформироватьHTML(ДанныеКартинки) Экспорт 86 | 87 | Картинка = ПоместитьВоВременноеХранилище(ДанныеКартинки, УникальныйИдентификатор); 88 | Поток = ДанныеКартинки.ОткрытьПотокДляЧтения(); 89 | ЧтениеТекста = Новый ЧтениеТекста(Поток, КодировкаТекста.UTF8); 90 | ТекстHTML = 91 | " 92 | | 93 | | 101 | | 102 | | 103 | | 104 | | 105 | |
106 | |
107 | |" + ЧтениеТекста.Прочитать() + " 108 | |
109 | |
110 | | 111 | |"; 112 | 113 | КонецПроцедуры 114 | 115 | &НаКлиенте 116 | Процедура ТекстHTMLДокументСформирован(Элемент) 117 | 118 | Элементы.ТекстHTML.Документ.defaultView.setBasePath(ТекущийПуть); 119 | 120 | КонецПроцедуры 121 | 122 | &НаКлиенте 123 | Процедура Сформировать(Команда) 124 | 125 | Если Не ПустаяСтрока(Картинка) Тогда 126 | УдалитьИзВременногоХранилища(Картинка); 127 | ТекстHTML = Неопределено; 128 | Картинка = Неопределено; 129 | КонецЕсли; 130 | 131 | СформироватьКартинку(); 132 | 133 | КонецПроцедуры 134 | 135 | &НаКлиенте 136 | Процедура ЭкспортVisio(Команда) 137 | 138 | Попытка 139 | Visio = Новый COMОбъект("Visio.Application"); 140 | Исключение 141 | Сообщить("Не удалось создать объект Visio по причине: " + ОписаниеОшибки()); 142 | Возврат; 143 | КонецПопытки; 144 | 145 | Visio.Application.ScreenUpdating = False; 146 | Попытка 147 | ДвоичныеДанные = ПолучитьИзВременногоХранилища(Картинка); 148 | ПостроитьДиаграммуVisio(Visio, ДвоичныеДанные); 149 | Исключение 150 | Сообщить("Ошибка Visio по причине: " + ОписаниеОшибки()); 151 | КонецПопытки; 152 | 153 | Visio.Application.ScreenUpdating = True; 154 | Visio.ActiveDocument.Saved = True; 155 | Visio = Неопределено; 156 | 157 | КонецПроцедуры 158 | 159 | &НаКлиенте 160 | Функция СконвертироватьТочки(Текст) 161 | 162 | РазрешениеЭкрана = 96; 163 | Координаты = СтрРазделить(Текст, " ", Ложь); 164 | Для Номер = 0 По Координаты.Количество() - 1 Цикл 165 | Точка = СтрРазделить(Координаты[номер], ","); 166 | Координаты[номер] = Новый Структура("X,Y" 167 | , Число(Точка[0]) / РазрешениеЭкрана + 1 168 | , -Число(Точка[1]) / РазрешениеЭкрана + 1 169 | ); 170 | КонецЦикла; 171 | 172 | Возврат Координаты; 173 | 174 | КонецФункции 175 | 176 | &НаКлиенте 177 | Функция МаксимумМассива(Массив, Поле) 178 | 179 | Количество = Массив.Количество(); 180 | Если Количество = 0 Тогда 181 | Возврат Неопределено; 182 | КонецЕсли; 183 | 184 | Результат = Массив[0][Поле]; 185 | Для Номер = 1 По Количество - 1 Цикл 186 | Значение = Массив[Номер][Поле]; 187 | Если Значение > Результат Тогда 188 | Результат = Значение; 189 | КонецЕсли; 190 | КонецЦикла; 191 | 192 | Возврат Результат; 193 | 194 | КонецФункции 195 | 196 | &НаКлиенте 197 | Функция МинимумМассива(Массив, Поле) 198 | 199 | Количество = Массив.Количество(); 200 | Если Количество = 0 Тогда 201 | Возврат Неопределено; 202 | КонецЕсли; 203 | 204 | Результат = Массив[0][Поле]; 205 | Для Номер = 1 По Количество - 1 Цикл 206 | Значение = Массив[Номер][Поле]; 207 | Если Значение < Результат Тогда 208 | Результат = Значение; 209 | КонецЕсли; 210 | КонецЦикла; 211 | 212 | Возврат Результат; 213 | 214 | КонецФункции 215 | 216 | &НаКлиенте 217 | Процедура ПостроитьДиаграммуVisio(Visio, ДвоичныеДанные) 218 | 219 | VisioNewFile = Visio.Documents.Add(""); 220 | Попытка 221 | Visio.Application.ActivePage.SetTheme(1, 1, 1, 1, 1); // тема MS Visio 2016 222 | Исключение 223 | // MS Visio 2010 224 | Visio.Application.ActivePage.ThemeColors = "visThemeColorsBasic"; 225 | Visio.Application.ActivePage.ThemeEffects = "visThemeEffectsBasicShadow"; 226 | КонецПопытки; 227 | 228 | visSectionObject = 1; 229 | visRowShapeLayout = 23; 230 | visSLORouteStyle = 10; 231 | visLORouteCenterToCenter = 16; 232 | visSLOLineRouteExt = 19; 233 | visLORouteExtStraight = 1; 234 | visRowLine = 2; 235 | visLinePattern = 2; 236 | visLineWeight = 0; 237 | 238 | Поток = ДвоичныеДанные.ОткрытьПотокДляЧтения(); 239 | ЧтениеXML = Новый ЧтениеXML; 240 | ЧтениеXML.ОткрытьПоток(Поток); 241 | ПостроительDOM = Новый ПостроительDOM; 242 | ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML); 243 | 244 | СоответствиеПространств = Новый Соответствие; 245 | СоответствиеПространств.Вставить("svg", "http://www.w3.org/2000/svg"); 246 | Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПространств); 247 | 248 | Соответствие = Новый Соответствие; 249 | Результат = ДокументDOM.ВычислитьВыражениеXPath("//svg:g[@class=""node""]", ДокументDOM, Разыменователь); 250 | Пока Истина Цикл 251 | ТекущийУзел = Результат.ПолучитьСледующий(); 252 | Если ТекущийУзел = Неопределено Тогда 253 | Прервать; 254 | КонецЕсли; 255 | ИмяОбъекта = ПолучитьЗначение(ТекущийУзел, "title"); 256 | Представление = ПолучитьЗначение(ТекущийУзел, "text"); 257 | КоординатыСтр = ПолучитьАтрибут(ТекущийУзел, "polygon", "points"); 258 | Если Не ПустаяСтрока(КоординатыСтр) Тогда 259 | ЦветЗаливки = ПолучитьАтрибут(ТекущийУзел, "polygon", "fill"); 260 | Координаты = СконвертироватьТочки(КоординатыСтр); 261 | НовыйОбъект = Visio.ActiveWindow.Page.DrawRectangle( 262 | Координаты[0].X, Координаты[0].Y, 263 | Координаты[2].X, Координаты[2].Y); 264 | Иначе 265 | КоординатыСтр = ПолучитьАтрибут(ТекущийУзел, "path", "d"); 266 | ЦветЗаливки = ПолучитьАтрибут(ТекущийУзел, "path", "fill"); 267 | КоординатыСтр = СтрЗаменить(КоординатыСтр, "M", " "); 268 | КоординатыСтр = СтрЗаменить(КоординатыСтр, "C", " "); 269 | Координаты = СконвертироватьТочки(КоординатыСтр); 270 | НовыйОбъект = Visio.ActiveWindow.Page.DrawRectangle( 271 | МинимумМассива(Координаты, "X"), 272 | МинимумМассива(Координаты, "Y"), 273 | МаксимумМассива(Координаты, "X"), 274 | МаксимумМассива(Координаты, "Y")); 275 | НовыйОбъект.Cells("Rounding").Formula = 0.1; 276 | КонецЕсли; 277 | НовыйОбъект.Name = ИмяОбъекта; 278 | НовыйОбъект.Text = Представление; 279 | Если ЦветЗаливки = "gold" Тогда 280 | ФормулаЦвета = "RGB(255, 215, 0)"; 281 | ИначеЕсли ЦветЗаливки = "#a82f00" Тогда 282 | ФормулаЦвета = "RGB(168, 47, 0)"; 283 | Иначе 284 | ФормулаЦвета = "RGB(255, 255, 255)"; 285 | КонецЕсли; 286 | НовыйОбъект.CellsU("Fillforegnd").FormulaU = ФормулаЦвета; 287 | Соответствие.Вставить(ИмяОбъекта, НовыйОбъект); 288 | КонецЦикла; 289 | 290 | Результат = ДокументDOM.ВычислитьВыражениеXPath("//svg:g[@class=""edge""]", ДокументDOM, Разыменователь); 291 | Пока Истина Цикл 292 | Директор = Ложь; 293 | ТекущийУзел = Результат.ПолучитьСледующий(); 294 | Если ТекущийУзел = Неопределено Тогда 295 | Прервать; 296 | КонецЕсли; 297 | ИмяОбъекта = ПолучитьЗначение(ТекущийУзел, "title"); 298 | Представление = ПолучитьЗначение(ТекущийУзел, "text"); 299 | Если НРег(СокрЛП(Представление)) = "директор" 300 | ИЛИ Нрег(СокрЛП(Представление)) = "генеральный директор" Тогда 301 | Директор = Истина; 302 | КонецЕсли; 303 | Позиция = СтрНайти(ИмяОбъекта, "->"); 304 | ЛевыйОбъект = Лев(ИмяОбъекта, Позиция - 1); 305 | ЛевыйОбъект = СтрЗаменить(ЛевыйОбъект, ":", ""); 306 | ПравыйОбъект = Сред(ИмяОбъекта, Позиция + 2); 307 | ПравыйОбъект = СтрЗаменить(ПравыйОбъект, ":", ""); 308 | ЛевыйОбъект = Соответствие.Получить(ЛевыйОбъект); 309 | ПравыйОбъект = Соответствие.Получить(ПравыйОбъект); 310 | Коннектор = Visio.Application.ActiveWindow.Page.Drop(Visio.Application.ConnectorToolDataObject, 0, 1); 311 | Если НЕ Директор Тогда 312 | Коннектор.CellsU("BeginX").GlueTo(ЛевыйОбъект.CellsSRC(1, 1, 0)); 313 | Коннектор.CellsU("EndX").GlueTo(ПравыйОбъект.CellsSRC(1, 1, 0)); 314 | Иначе 315 | Коннектор.CellsU("BeginX").GlueTo(ПравыйОбъект.CellsSRC(1, 1, 0)); 316 | Коннектор.CellsU("EndX").GlueTo(ЛевыйОбъект.CellsSRC(1, 1, 0)); 317 | КонецЕсли; 318 | Директор = Ложь; 319 | Коннектор.CellsSRC(visSectionObject, visRowShapeLayout, visSLORouteStyle).FormulaU = "16"; 320 | Коннектор.CellsSRC(visSectionObject, visRowShapeLayout, visSLOLineRouteExt).FormulaU = "2"; 321 | Коннектор.CellsSRC(visSectionObject, visRowLine, visLineWeight).FormulaU = "1 pt"; 322 | ФормаЛинии = ПолучитьАтрибут(ТекущийУзел, "path", "stroke-dasharray"); 323 | Если НЕ ПустаяСтрока(ФормаЛинии) Тогда 324 | Коннектор.CellsSRC(visSectionObject, visRowLine, visLinePattern).FormulaU = "2"; 325 | КонецЕсли; 326 | Коннектор.Text = Представление; 327 | КонецЦикла; 328 | 329 | КонецПроцедуры 330 | 331 | &НаКлиенте 332 | Функция ПолучитьЗначение(ТекущийУзел, ИмяУзла) 333 | 334 | Для каждого ДочернийУзел Из ТекущийУзел.ДочерниеУзлы Цикл 335 | Если ДочернийУзел.ИмяУзла = ИмяУзла Тогда 336 | Возврат ДочернийУзел.ТекстовоеСодержимое; 337 | КонецЕсли; 338 | КонецЦикла; 339 | 340 | КонецФункции 341 | 342 | &НаКлиенте 343 | Функция ПолучитьАтрибут(ТекущийУзел, ИмяУзла, ИмяАтрибута) 344 | 345 | Для каждого ДочернийУзел Из ТекущийУзел.ДочерниеУзлы Цикл 346 | Если ДочернийУзел.ИмяУзла = ИмяУзла Тогда 347 | Возврат ДочернийУзел.ПолучитьАтрибут(ИмяАтрибута); 348 | КонецЕсли; 349 | КонецЦикла; 350 | 351 | КонецФункции 352 | 353 | &НаКлиенте 354 | Процедура ДоступныеФорматы(Команда) 355 | 356 | ФорматыAPI = Новый Массив; 357 | ФорматыAPI.Добавить("render"); 358 | ФорматыAPI.Добавить("layout"); 359 | ФорматыAPI.Добавить("textlayout"); 360 | ФорматыAPI.Добавить("device"); 361 | ФорматыAPI.Добавить("loadimage"); 362 | 363 | Для Номер = 0 По 4 Цикл 364 | ОписаниеОповещения = Новый ОписаниеОповещения("ПолученыФорматы", ЭтаФорма, ФорматыAPI[Номер]); 365 | ВнешняяКомпонента.НачатьВызовФормат(ОписаниеОповещения, Номер); 366 | КонецЦикла; 367 | 368 | КонецПроцедуры 369 | 370 | &НаКлиенте 371 | Процедура ПолученыФорматы(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт 372 | 373 | Сообщить(ДополнительныеПараметры + ": " + РезультатВызова); 374 | 375 | КонецПроцедуры 376 | 377 | &НаКлиенте 378 | Процедура ОткрытьФайл(Команда) 379 | 380 | ОписаниеОповещения = Новый ОписаниеОповещения("ОбработкаОткрытияФайла", ЭтаФорма); 381 | ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); 382 | ДиалогВыбораФайла.Фильтр = "*.dot"; 383 | ДиалогВыбораФайла.Показать(ОписаниеОповещения); 384 | 385 | КонецПроцедуры 386 | 387 | &НаКлиенте 388 | Процедура ОбработкаОткрытияФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт 389 | 390 | Если ВыбранныеФайлы <> Неопределено Тогда 391 | ТекущийФайл = ВыбранныеФайлы[0]; 392 | Файл = Новый Файл(ТекущийФайл); 393 | ТекущийПуть = Файл.Путь; 394 | ВнешняяКомпонента.НачатьУстановкуПутиКартинок(Новый ОписаниеОповещения, ТекущийПуть); 395 | ДанныеГрафа = Новый ДвоичныеДанные(ТекущийФайл); 396 | СформироватьКартинку(); 397 | КонецЕсли; 398 | 399 | КонецПроцедуры 400 | 401 | &НаКлиенте 402 | Процедура СохранитьКак(Команда) 403 | 404 | ОписаниеОповещения = Новый ОписаниеОповещения("ОбработкаВыбораФайла", ЭтаФорма); 405 | ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение); 406 | ДиалогВыбораФайла.Фильтр = "Файлы изображений (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png|Все файлы|*.*"; 407 | ДиалогВыбораФайла.Показать(ОписаниеОповещения); 408 | 409 | КонецПроцедуры 410 | 411 | &НаКлиенте 412 | Процедура ОбработкаВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт 413 | 414 | Если ВыбранныеФайлы <> Неопределено Тогда 415 | ИмяФайла = ВыбранныеФайлы[0]; 416 | Файл = Новый Файл(ИмяФайла); 417 | ФорматЗаписи = Сред(Файл.Расширение, 2); 418 | ОписаниеОповещения = Новый ОписаниеОповещения("ОбработкаЗаписиФайла", ЭтаФорма, Файл.ПолноеИмя); 419 | ВнешняяКомпонента.НачатьВызовСформировать(ОписаниеОповещения, ДанныеГрафа, ФорматЗаписи); 420 | КонецЕсли; 421 | 422 | КонецПроцедуры 423 | 424 | &НаКлиенте 425 | Процедура ОбработкаЗаписиФайла(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт 426 | 427 | Если ТипЗнч(РезультатВызова) = Тип("ДвоичныеДанные") Тогда 428 | РезультатВызова.Записать(ДополнительныеПараметры); 429 | ИначеЕсли ТипЗнч(РезультатВызова) = Тип("Строка") Тогда 430 | Сообщить(РезультатВызова); 431 | КонецЕсли; 432 | 433 | КонецПроцедуры -------------------------------------------------------------------------------- /GraphViz.patch: -------------------------------------------------------------------------------- 1 | diff --git a/CMakeLists.txt b/CMakeLists.txt 2 | index 16c1c08389648e46fb014be53ba1f522fe469450..29a9facd96fdeb79b52c5e966dd3f85fedee776f 100644 3 | --- a/CMakeLists.txt 4 | +++ b/CMakeLists.txt 5 | @@ -4,13 +4,16 @@ project (Graphviz) 6 | include(FeatureSummary) 7 | 8 | # =============================== Build options ================================ 9 | -option(enable_ltdl "Support on-demand plugin loading" ON) 10 | +option(enable_ltdl "Support on-demand plugin loading" OFF ) 11 | +option(with_expat "Expat required for HTML-like labels" OFF ) 12 | option(with_digcola "DIGCOLA features in neato layout engine" ON ) 13 | option(with_ipsepcola "IPSEPCOLA features in neato layout engine (disabled by default - C++ portability issues)." OFF ) 14 | option(with_ortho "ORTHO features in neato layout engine." ON ) 15 | option(with_sfdp "sfdp layout engine." ON ) 16 | option(with_smyrna "SMYRNA large graph viewer (disabled by default - experimental)" OFF) 17 | 18 | +option(BUILD_SHARED_LIBS "Build shared library" ON) 19 | + 20 | if (enable_ltdl) 21 | add_definitions(-DENABLE_LTDL) 22 | endif (enable_ltdl) 23 | @@ -40,6 +43,12 @@ endif (with_smyrna) 24 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 25 | 26 | # ============================= Build dependencies ============================= 27 | +if (WIN32) 28 | + set(AWK_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/windows/dependencies/graphviz-build-utilities/awk.exe" CACHE PATH "AWK executable") 29 | + set(BISON_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/windows/dependencies/graphviz-build-utilities/winflexbison/win_bison.exe" CACHE PATH "Bison executable") 30 | + set(FLEX_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/windows/dependencies/graphviz-build-utilities/winflexbison/win_flex.exe" CACHE PATH "Flex executable") 31 | +endif(WIN32) 32 | + 33 | find_package(AWK REQUIRED) 34 | find_package(BISON REQUIRED) 35 | find_package(FLEX REQUIRED) 36 | @@ -82,7 +91,11 @@ endif() 37 | 38 | find_package(ANN) 39 | find_package(Cairo) 40 | -find_package(EXPAT) 41 | + 42 | +if (with_expat) 43 | + find_package(EXPAT) 44 | +endif() 45 | + 46 | find_package(GD) 47 | find_package(LTDL) 48 | find_package(PangoCairo) 49 | diff --git a/cmd/dot/CMakeLists.txt b/cmd/dot/CMakeLists.txt 50 | index 00a4a283bdcfd4ed2c8a88f6ebd466bb4da82a42..e8214ae13eb80b0f3ba571bf9efc1284e4adac1d 100644 51 | --- a/cmd/dot/CMakeLists.txt 52 | +++ b/cmd/dot/CMakeLists.txt 53 | @@ -10,16 +10,29 @@ include_directories( 54 | ${GRAPHVIZ_LIB_DIR}/pathplan 55 | ) 56 | 57 | -add_executable(dot 58 | - # Source files 59 | - dot.c 60 | - no_builtins.c 61 | -) 62 | - 63 | -target_link_libraries(dot 64 | - cgraph 65 | - gvc 66 | -) 67 | +if(BUILD_SHARED_LIBS) 68 | + add_executable(dot 69 | + # Source files 70 | + dot.c 71 | + no_builtins.c 72 | + ) 73 | + 74 | + target_link_libraries(dot 75 | + cgraph 76 | + gvc 77 | + ) 78 | +else(BUILD_SHARED_LIBS) 79 | + add_executable(dot 80 | + # Source files 81 | + dot.c 82 | + dot_builtins.c 83 | + ) 84 | + target_link_libraries(dot 85 | + gvplugin_core 86 | + gvplugin_dot_layout 87 | + gvplugin_neato_layout 88 | + ) 89 | +endif(BUILD_SHARED_LIBS) 90 | 91 | # Installation location of executables 92 | install( 93 | diff --git a/cmd/tools/CMakeLists.txt b/cmd/tools/CMakeLists.txt 94 | index 087bf15cf0d5d4bfbb2a4549cdddbea678976472..741619f6cf0c06f61b7490d14244515c02d1e0aa 100644 95 | --- a/cmd/tools/CMakeLists.txt 96 | +++ b/cmd/tools/CMakeLists.txt 97 | @@ -266,35 +266,38 @@ tool_defaults(gvgen) 98 | 99 | add_definitions(-DDEMAND_LOADING=0) 100 | 101 | -add_executable(gvpack 102 | - # Source files 103 | - gvpack.c 104 | -) 105 | +if(BUILD_SHARED_LIBS) 106 | + add_executable(gvpack 107 | + # Source files 108 | + gvpack.c 109 | + ) 110 | 111 | -target_include_directories(gvpack PRIVATE 112 | - ${GRAPHVIZ_LIB_DIR} 113 | - ${CMAKE_CURRENT_SOURCE_DIR} 114 | - ${CMAKE_CURRENT_BINARY_DIR} 115 | - ${GRAPHVIZ_LIB_DIR}/cdt 116 | - ${GRAPHVIZ_LIB_DIR}/cgraph 117 | - ${GRAPHVIZ_LIB_DIR}/common 118 | - ${GRAPHVIZ_LIB_DIR}/gvc 119 | - ${GRAPHVIZ_LIB_DIR}/pack 120 | - ${GRAPHVIZ_LIB_DIR}/pathplan 121 | - ${EXPAT_INCLUDE_DIRS} 122 | - ${Getopt_INCLUDE_DIRS} 123 | -) 124 | + target_include_directories(gvpack PRIVATE 125 | + ${GRAPHVIZ_LIB_DIR} 126 | + ${CMAKE_CURRENT_SOURCE_DIR} 127 | + ${CMAKE_CURRENT_BINARY_DIR} 128 | + ${GRAPHVIZ_LIB_DIR}/cdt 129 | + ${GRAPHVIZ_LIB_DIR}/cgraph 130 | + ${GRAPHVIZ_LIB_DIR}/common 131 | + ${GRAPHVIZ_LIB_DIR}/gvc 132 | + ${GRAPHVIZ_LIB_DIR}/pack 133 | + ${GRAPHVIZ_LIB_DIR}/pathplan 134 | + ${EXPAT_INCLUDE_DIRS} 135 | + ${Getopt_INCLUDE_DIRS} 136 | + ) 137 | 138 | -target_link_libraries(gvpack 139 | - cdt 140 | - cgraph 141 | - gvc 142 | - gvplugin_neato_layout 143 | - ingraphs 144 | -) 145 | + target_link_libraries(gvpack 146 | + cdt 147 | + cgraph 148 | + gvc 149 | + gvplugin_neato_layout 150 | + ingraphs 151 | + ) 152 | 153 | tool_defaults(gvpack) 154 | 155 | +endif(BUILD_SHARED_LIBS) 156 | + 157 | # =================================== gxl2gv =================================== 158 | if(EXPAT_FOUND) 159 | 160 | diff --git a/lib/cdt/CMakeLists.txt b/lib/cdt/CMakeLists.txt 161 | index 159f9864afb6b9b387d7d3dd11a7bfac9df0de29..070f470ea8a73a70bac672cb8baa1a1b83aad35d 100644 162 | --- a/lib/cdt/CMakeLists.txt 163 | +++ b/lib/cdt/CMakeLists.txt 164 | @@ -1,6 +1,8 @@ 165 | -add_definitions(-DEXPORT_CDT) 166 | +if(BUILD_SHARED_LIBS) 167 | + add_definitions(-DEXPORT_CDT) 168 | +endif() 169 | 170 | -add_library(cdt SHARED 171 | +add_library(cdt 172 | # Header files 173 | cdt.h 174 | dthdr.h 175 | diff --git a/lib/cdt/cdt.h b/lib/cdt/cdt.h 176 | index 7bafbc061c4212df7bf5ec2b253315088698bbed..78d5380e7f06c797f9592f2698f34c48d81a7a56 100644 177 | --- a/lib/cdt/cdt.h 178 | +++ b/lib/cdt/cdt.h 179 | @@ -19,7 +19,7 @@ extern "C" { 180 | # ifdef EXPORT_CDT 181 | # define CDT_API __declspec(dllexport) 182 | # else 183 | -# define CDT_API __declspec(dllimport) 184 | +# define CDT_API extern 185 | # endif 186 | #else 187 | # define CDT_API extern 188 | diff --git a/lib/cgraph/CMakeLists.txt b/lib/cgraph/CMakeLists.txt 189 | index 4d188459b8538154de5a380eaaafe7b749521d46..797f2ca019350df501357a556173037953510b39 100644 190 | --- a/lib/cgraph/CMakeLists.txt 191 | +++ b/lib/cgraph/CMakeLists.txt 192 | @@ -2,9 +2,13 @@ BISON_TARGET(Grammar grammar.y ${CMAKE_CURRENT_BINARY_DIR}/grammar.c) 193 | FLEX_TARGET(Scan scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.c) 194 | ADD_FLEX_BISON_DEPENDENCY(Scan Grammar) 195 | 196 | -add_definitions(-DEXPORT_CGRAPH -DEXPORT_AGXBUF -DEXPORT_CGHDR -DYY_NO_UNISTD_H) 197 | +if(BUILD_SHARED_LIBS) 198 | + add_definitions(-DEXPORT_CGRAPH -DEXPORT_AGXBUF -DEXPORT_CGHDR) 199 | +endif() 200 | 201 | -add_library(cgraph SHARED 202 | +add_definitions(-DYY_NO_UNISTD_H) 203 | + 204 | +add_library(cgraph 205 | # Header files 206 | agxbuf.h 207 | cghdr.h 208 | diff --git a/lib/cgraph/agxbuf.h b/lib/cgraph/agxbuf.h 209 | index eeb12235bee6d5350f950d42ecef38c5128d22cc..c0659ed4a92aca4ff805d63a8acd4e86f7f6e13d 100644 210 | --- a/lib/cgraph/agxbuf.h 211 | +++ b/lib/cgraph/agxbuf.h 212 | @@ -24,7 +24,7 @@ extern "C" { 213 | # ifdef EXPORT_AGXBUF 214 | # define AGXBUF_API __declspec(dllexport) 215 | # else 216 | -# define AGXBUF_API __declspec(dllimport) 217 | +# define AGXBUF_API extern 218 | # endif 219 | #else 220 | # define AGXBUF_API extern 221 | diff --git a/lib/cgraph/cghdr.h b/lib/cgraph/cghdr.h 222 | index 131efbadfd2a72daf9673b9e71b604cdabb79922..eb93a41b3ca675ede6445813ffd0b36a92b0b564 100644 223 | --- a/lib/cgraph/cghdr.h 224 | +++ b/lib/cgraph/cghdr.h 225 | @@ -19,7 +19,7 @@ 226 | # ifdef EXPORT_CGHDR 227 | # define CGHDR_API __declspec(dllexport) 228 | # else 229 | -# define CGHDR_API __declspec(dllimport) 230 | +# define CGHDR_API extern 231 | # endif 232 | #else 233 | # define CGHDR_API extern 234 | diff --git a/lib/cgraph/cgraph.h b/lib/cgraph/cgraph.h 235 | index 8ee2fc4498793d50aa25365b65098f486956b7cd..b9b4ea5097c9235850f0537faac422d44002bc62 100644 236 | --- a/lib/cgraph/cgraph.h 237 | +++ b/lib/cgraph/cgraph.h 238 | @@ -25,7 +25,7 @@ extern "C" { 239 | # ifdef EXPORT_CGRAPH 240 | # define CGRAPH_API __declspec(dllexport) 241 | # else 242 | -# define CGRAPH_API __declspec(dllimport) 243 | +# define CGRAPH_API extern 244 | # endif 245 | #else 246 | # define CGRAPH_API extern 247 | diff --git a/lib/common/CMakeLists.txt b/lib/common/CMakeLists.txt 248 | index 2620f1867b7d51b26b021da21728148262f0be24..ca67f7724f518a3b4c0309d870ed952afe536a6e 100644 249 | --- a/lib/common/CMakeLists.txt 250 | +++ b/lib/common/CMakeLists.txt 251 | @@ -1,6 +1,8 @@ 252 | BISON_TARGET(HTMLparse htmlparse.y ${CMAKE_CURRENT_BINARY_DIR}/htmlparse.c) 253 | 254 | -add_definitions(-DGVC_EXPORTS -D_BLD_gvc=1) 255 | +if(BUILD_SHARED_LIBS) 256 | + add_definitions(-DGVC_EXPORTS -D_BLD_gvc=1) 257 | +endif() 258 | 259 | # Generate colortbl.h from sources 260 | add_custom_command( 261 | diff --git a/lib/common/utils.h b/lib/common/utils.h 262 | index 4177461a2d21f769990ceb7a7a7ea262d68c656d..99c5491bb5162a171a0261c06c594a28597b021f 100644 263 | --- a/lib/common/utils.h 264 | +++ b/lib/common/utils.h 265 | @@ -21,7 +21,7 @@ extern "C" { 266 | 267 | /*visual studio*/ 268 | #ifdef _WIN32 269 | -#ifndef GVC_EXPORTS 270 | +#ifdef GVC_EXPORTS 271 | #define extern __declspec(dllimport) 272 | #endif 273 | #endif 274 | diff --git a/lib/gvc/CMakeLists.txt b/lib/gvc/CMakeLists.txt 275 | index 1db89a0ab87a3cfd3b5f68fb341a20f67fbce08e..3405e1d1a0250f8d7da4c7cc512eab1e68fdb18e 100644 276 | --- a/lib/gvc/CMakeLists.txt 277 | +++ b/lib/gvc/CMakeLists.txt 278 | @@ -1,6 +1,8 @@ 279 | -add_definitions(-D_BLD_gvc=1 -DGVC_EXPORTS -DGVLIBDIR="${LIBRARY_INSTALL_DIR}/graphviz") 280 | +if(BUILD_SHARED_LIBS) 281 | + add_definitions(-D_BLD_gvc=1 -DGVC_EXPORTS -DGVLIBDIR="${LIBRARY_INSTALL_DIR}/graphviz") 282 | +endif() 283 | 284 | -add_library(gvc SHARED 285 | +add_library(gvc 286 | # Header files 287 | gvc.h 288 | gvcext.h 289 | diff --git a/lib/gvc/gvc.h b/lib/gvc/gvc.h 290 | index 894683a2d35dc16a5dfd523984a991da31a76a0d..b0d93eb27b232dae0d3423e75b2512ed71458860 100644 291 | --- a/lib/gvc/gvc.h 292 | +++ b/lib/gvc/gvc.h 293 | @@ -29,13 +29,12 @@ extern "C" { 294 | 295 | /*visual studio*/ 296 | #ifdef _WIN32 297 | -#ifndef GVC_EXPORTS 298 | -#undef extern 299 | -#define extern __declspec(dllimport) 300 | -#endif 301 | +# ifdef GVC_EXPORTS 302 | +# define extern __declspec(dllimport) 303 | +# endif 304 | #endif 305 | /*end visual studio*/ 306 | - 307 | + 308 | #define LAYOUT_DONE(g) (agbindrec(g, "Agraphinfo_t", 0, TRUE) && GD_drawing(g)) 309 | 310 | /* misc */ 311 | diff --git a/lib/pathplan/CMakeLists.txt b/lib/pathplan/CMakeLists.txt 312 | index 552d6243b387821f6398e9d1294c03b05da786b8..5ef7bb7f01cc5757818f04223a575123b82d32b5 100644 313 | --- a/lib/pathplan/CMakeLists.txt 314 | +++ b/lib/pathplan/CMakeLists.txt 315 | @@ -1,6 +1,8 @@ 316 | -add_definitions(-D_BLD_pathplan -DPATHPLAN_EXPORTS) 317 | +if(BUILD_SHARED_LIBS) 318 | + add_definitions(-D_BLD_pathplan -DPATHPLAN_EXPORTS) 319 | +endif() 320 | 321 | -add_library(pathplan SHARED 322 | +add_library(pathplan 323 | # Header files 324 | pathgeom.h 325 | pathplan.h 326 | diff --git a/lib/pathplan/vis.h b/lib/pathplan/vis.h 327 | index 96022d3d41e9e9abd9b59dccd9f851b33b49822a..743d5126f5b0c557a76fb01a61bd1e244471cfc6 100644 328 | --- a/lib/pathplan/vis.h 329 | +++ b/lib/pathplan/vis.h 330 | @@ -46,10 +46,12 @@ extern "C" { 331 | /* this is computed from the above */ 332 | array2 vis; 333 | }; 334 | + 335 | +/*visual studio*/ 336 | #ifdef _WIN32 337 | -#ifndef PATHPLAN_EXPORTS 338 | -#define extern __declspec(dllimport) 339 | -#endif 340 | +# ifdef PATHPLAN_EXPORTS 341 | +# define extern __declspec(dllimport) 342 | +# endif 343 | #endif 344 | /*end visual studio*/ 345 | 346 | diff --git a/lib/xdot/CMakeLists.txt b/lib/xdot/CMakeLists.txt 347 | index afd07939fa97c40a6126ed36ce05e41fbc36edd0..b9ac70023246f3b7b7ea4532cffafc98a039d30c 100644 348 | --- a/lib/xdot/CMakeLists.txt 349 | +++ b/lib/xdot/CMakeLists.txt 350 | @@ -1,6 +1,8 @@ 351 | -add_definitions(-DEXPORT_XDOT) 352 | +if(BUILD_SHARED_LIBS) 353 | + add_definitions(-DEXPORT_XDOT) 354 | +endif() 355 | 356 | -add_library(xdot SHARED 357 | +add_library(xdot 358 | # Header files 359 | xdot.h 360 | 361 | diff --git a/lib/xdot/xdot.h b/lib/xdot/xdot.h 362 | index fc9392e44c8aee429a3378757fecd7807609db87..3669b3864b635c555fac0ec2ce61d474369610a2 100644 363 | --- a/lib/xdot/xdot.h 364 | +++ b/lib/xdot/xdot.h 365 | @@ -25,7 +25,7 @@ extern "C" { 366 | # ifdef EXPORT_XDOT 367 | # define XDOT_API __declspec(dllexport) 368 | # else 369 | -# define XDOT_API __declspec(dllimport) 370 | +# define XDOT_API 371 | # endif 372 | #else 373 | # define XDOT_API extern 374 | diff --git a/plugin/core/CMakeLists.txt b/plugin/core/CMakeLists.txt 375 | index 2f003e7791863b971e7bede8a124074095bf69de..324816ce8928bc2e40efbeff80770e28809432e6 100644 376 | --- a/plugin/core/CMakeLists.txt 377 | +++ b/plugin/core/CMakeLists.txt 378 | @@ -6,7 +6,7 @@ add_custom_command( 379 | ${CMAKE_CURRENT_SOURCE_DIR}/ps.txt > ${CMAKE_CURRENT_BINARY_DIR}/ps.h 380 | ) 381 | 382 | -add_library(gvplugin_core SHARED 383 | +add_library(gvplugin_core 384 | # Header files 385 | ps.h 386 | 387 | diff --git a/plugin/dot_layout/CMakeLists.txt b/plugin/dot_layout/CMakeLists.txt 388 | index 5f6886bdecdf050e2f50d69aa7931d318345960c..009e215fe3eee7d18237b89400646b4e4ac44a40 100644 389 | --- a/plugin/dot_layout/CMakeLists.txt 390 | +++ b/plugin/dot_layout/CMakeLists.txt 391 | @@ -1,4 +1,4 @@ 392 | -add_library(gvplugin_dot_layout SHARED 393 | +add_library(gvplugin_dot_layout 394 | # Source files 395 | gvplugin_dot_layout.c 396 | gvlayout_dot_layout.c 397 | diff --git a/plugin/gd/CMakeLists.txt b/plugin/gd/CMakeLists.txt 398 | index 0beeccd82d0f960f20204e87adf0b8ae9cde56ab..63b46827d4107b6c5657b9139367fa1f3a3681c2 100644 399 | --- a/plugin/gd/CMakeLists.txt 400 | +++ b/plugin/gd/CMakeLists.txt 401 | @@ -1,6 +1,6 @@ 402 | if (GD_FOUND) 403 | 404 | -add_library(gvplugin_gd SHARED 405 | +add_library(gvplugin_gd 406 | # Source files 407 | gvdevice_gd.c 408 | gvloadimage_gd.c 409 | diff --git a/plugin/gdiplus/CMakeLists.txt b/plugin/gdiplus/CMakeLists.txt 410 | index 58388d63b7a4ee2ccc488d5b3657f5cf2e213ed4..0851458dc2e3e1444e15c392b15b043b173d1209 100644 411 | --- a/plugin/gdiplus/CMakeLists.txt 412 | +++ b/plugin/gdiplus/CMakeLists.txt 413 | @@ -1,6 +1,6 @@ 414 | if (WIN32) 415 | 416 | -add_library(gvplugin_gdiplus SHARED 417 | +add_library(gvplugin_gdiplus 418 | # Header files 419 | FileStream.h 420 | gvplugin_gdiplus.h 421 | diff --git a/plugin/neato_layout/CMakeLists.txt b/plugin/neato_layout/CMakeLists.txt 422 | index 8e27c972174be956520ebaa7ee0dca07bcc9ec62..df3881b9659243a8f2a7435b16c48273336d8c96 100644 423 | --- a/plugin/neato_layout/CMakeLists.txt 424 | +++ b/plugin/neato_layout/CMakeLists.txt 425 | @@ -1,4 +1,4 @@ 426 | -add_library(gvplugin_neato_layout SHARED 427 | +add_library(gvplugin_neato_layout 428 | # Source files 429 | gvplugin_neato_layout.c 430 | gvlayout_neato_layout.c 431 | diff --git a/plugin/pango/CMakeLists.txt b/plugin/pango/CMakeLists.txt 432 | index e2a4a3845e7683389bbff652336c3cb121a8b1b4..afbea203c318afe1da3c44fe3f95fefc700b134f 100644 433 | --- a/plugin/pango/CMakeLists.txt 434 | +++ b/plugin/pango/CMakeLists.txt 435 | @@ -1,6 +1,6 @@ 436 | if(Cairo_FOUND AND PangoCairo_FOUND) 437 | 438 | -add_library(gvplugin_pango SHARED 439 | +add_library(gvplugin_pango 440 | # Header files 441 | gvgetfontlist.h 442 | gvplugin_pango.h 443 | -------------------------------------------------------------------------------- /tools/Compile.os: -------------------------------------------------------------------------------- 1 | #Использовать v8runner 2 | #Использовать logos 3 | 4 | Перем Лог; 5 | Перем УправлениеКонфигуратором; 6 | 7 | Функция ДатуКСтроке(Дат) 8 | Возврат Формат(Дат,"ДФ=yyyy.MM.dd.HH.mm.ss"); 9 | КонецФункции 10 | 11 | // Перемещаят найденные по маскам файлы с сохранением пути. 12 | // 13 | // Параметры: 14 | // КаталогКуда - Строка - Путь к каталогу в который переносятся файлы; 15 | // КаталогиОткуда - Массив - Пути к каталогам в которых осуществляется поиск файлов; 16 | // МассивМасок - Массив - Маски, по которым осуществляется поиск файлов. 17 | // 18 | // Взято из https://infostart.ru/public/537028/ 19 | Процедура ПереместитьФайлыВКаталог(КаталогКуда, КаталогиОткуда, МассивМасок) 20 | 21 | Для Каждого КаталогПоиска Из КаталогиОткуда Цикл 22 | 23 | КаталогПоискаОбъект = Новый Файл(КаталогПоиска); 24 | 25 | Если НЕ КаталогПоискаОбъект.Существует() Тогда 26 | Лог.Ошибка(НСтр("ru = 'Каталог не найден.'")); 27 | Продолжить; 28 | КонецЕсли; 29 | 30 | Для Каждого Маска Из МассивМасок Цикл 31 | 32 | МассивФайлов = НайтиФайлы(КаталогПоиска, Маска, Истина); 33 | 34 | Для Каждого НайденныйФайл Из МассивФайлов Цикл 35 | 36 | НовыйПуть = СтрЗаменить(НайденныйФайл.Путь, КаталогПоиска, КаталогКуда); 37 | НовоеИмя = НайденныйФайл.Имя; 38 | 39 | Если НЕ ОбеспечитьКаталог(НовыйПуть) Тогда 40 | Продолжить; 41 | КонецЕсли; 42 | 43 | Если НайденныйФайл.ЭтоКаталог() Тогда 44 | Продолжить; 45 | КонецЕсли; 46 | 47 | 48 | ИмяФайлаДляПеремещения = ОбъединитьПути(НовыйПуть, НовоеИмя); 49 | УдалитьФайлы(ИмяФайлаДляПеремещения); 50 | 51 | Попытка 52 | ПереместитьФайл(НайденныйФайл.ПолноеИмя,ИмяФайлаДляПеремещения); 53 | Исключение 54 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось переместить файл: 55 | |%1'"), ОписаниеОшибки())); 56 | Продолжить; 57 | КонецПопытки; 58 | 59 | ФайлНаДиске = Новый Файл(ОбъединитьПути(НовыйПуть, НовоеИмя)); 60 | Если НЕ ФайлНаДиске.Существует() Тогда 61 | Лог.Ошибка(НСтр("ru = 'Не удалось корректно переместить файл.'")); 62 | Продолжить; 63 | КонецЕсли; 64 | КонецЦикла; 65 | 66 | КонецЦикла; 67 | 68 | КонецЦикла; 69 | 70 | КонецПроцедуры 71 | 72 | // Проверяет наличия каталога и в случае его отсутствия создает новый. 73 | // 74 | // Параметры: 75 | // Каталог - Строка - Путь к каталогу, существование которого нужно проверить. 76 | // 77 | // Возвращаемое значение: 78 | // Булево - признак существования каталога. 79 | // 80 | // Взято из https://infostart.ru/public/537028/ 81 | Функция ОбеспечитьКаталог(Знач Каталог) 82 | 83 | Файл = Новый Файл(Каталог); 84 | Если Не Файл.Существует() Тогда 85 | Попытка 86 | СоздатьКаталог(Каталог); 87 | Исключение 88 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Не удалось создать каталог %1. 89 | |%2'"), Каталог, ИнформацияОбОшибке())); 90 | Возврат Ложь; 91 | КонецПопытки; 92 | ИначеЕсли Не Файл.ЭтоКаталог() Тогда 93 | Лог.Ошибка(СтрШаблон(НСтр("ru = 'Каталог %1 не является каталогом.'"), Каталог)); 94 | Возврат Ложь; 95 | КонецЕсли; 96 | 97 | Возврат Истина; 98 | 99 | КонецФункции 100 | 101 | Функция ПроверитьЧтоВсеФайлыИсходниковСоответствуютИхВерсиям(МассивВерсий,Знач ИмяКаталога) 102 | ПромКаталог = СтрЗаменить(ИмяКаталога,"/","\"); 103 | Если Прав(ПромКаталог,1) <> "\" Тогда 104 | ИмяКаталога = ИмяКаталога + ПолучитьРазделительПути(); 105 | КонецЕсли; 106 | 107 | //Сообщить("ИмяКаталога="+ИмяКаталога); 108 | 109 | МассивФайлов = Новый Массив; 110 | МассивДляПоиска = Новый Массив; 111 | Файлы = НайтиФайлы(ИмяКаталога,"*",Истина); 112 | Для Каждого Файл Из Файлы Цикл 113 | Если Файл.ЭтоКаталог() Тогда 114 | Продолжить; 115 | КонецЕсли; 116 | 117 | Если ЭтоСлужебныйФайл(Файл.Имя) Тогда 118 | Продолжить; 119 | КонецЕсли; 120 | 121 | МассивФайлов.Добавить(Файл); 122 | 123 | Стр = Сред(Файл.ПолноеИмя,СтрДлина(ИмяКаталога)); 124 | Стр = СтрЗаменить(Стр,"/","\"); 125 | 126 | //Сообщить("СтрокаДляПоиска="+Стр); 127 | МассивДляПоиска.Добавить(Стр); 128 | КонецЦикла; 129 | 130 | //Сообщить("МассивФайлов.Количество()="+МассивФайлов.Количество()); 131 | //Сообщить("МассивВерсий.Количество()="+МассивВерсий.Количество()); 132 | 133 | Если МассивФайлов.Количество() <> МассивВерсий.Количество() Тогда 134 | Лог.Информация("Изменилось количество файлов."); 135 | 136 | //значит в исходниках появился новый файл или исчез 137 | Возврат Ложь; 138 | КонецЕсли; 139 | 140 | 141 | Для Каждого СтрокаВерсии Из МассивВерсий Цикл 142 | Поз = Найти(СтрокаВерсии,"|"); 143 | Версия = Лев(СтрокаВерсии,Поз-1); 144 | ЧастьПути = Сред(СтрокаВерсии,Поз+1); 145 | 146 | ЧастьПути = СтрЗаменить(ЧастьПути,"/","\"); 147 | 148 | ИдФайла = МассивДляПоиска.Найти(ЧастьПути); 149 | 150 | Если ИдФайла = Неопределено Тогда 151 | Лог.Информация("Не найден файл версии: " + ЧастьПути); 152 | Возврат Ложь; 153 | КонецЕсли; 154 | 155 | Файл = МассивФайлов[ИдФайла]; 156 | ТекущаяВерсияСтрокой = ДатуКСтроке(Файл.ПолучитьВремяИзменения()); 157 | Если ТекущаяВерсияСтрокой <> Версия Тогда 158 | Лог.Информация("Изменилась версия у файла: " + ЧастьПути); 159 | Возврат Ложь; 160 | КонецЕсли; 161 | КонецЦикла; 162 | 163 | Возврат Истина; 164 | КонецФункции 165 | 166 | Процедура ЗагрузитьОбработкуИлиОтчетИзXML(ИмяФайла_filename,ИмяОбработкиИлиОтчета) 167 | Файл_filename = Новый Файл(ИмяФайла_filename); 168 | 169 | 170 | КаталогГдеЛежит_filename = Файл_filename.Путь; 171 | ИмяФайлаВерсии = Файл_filename.Путь + "fileversion"; 172 | 173 | Файл_ИмяКаталога_filename = Новый Файл(Файл_filename.Путь); 174 | ИмяКаталога_filename = Файл_ИмяКаталога_filename.Имя; 175 | 176 | ФайлКаталогГдеЛежит_filename = Новый Файл(КаталогГдеЛежит_filename); 177 | ИмяФайлаXML = ФайлКаталогГдеЛежит_filename.Имя + ".xml"; 178 | 179 | ИмяФайлаКорневойXml = ФайлКаталогГдеЛежит_filename.Путь + ИмяФайлаXML; 180 | ФайлКорневойXML = Новый Файл(ИмяФайлаКорневойXml); 181 | Если Не ФайлКорневойXML.Существует() Тогда 182 | ВызватьИсключение "Файл " + ИмяФайлаКорневойXml + " не существует."; 183 | КонецЕсли; 184 | 185 | ИмяФайлаОбработкиИлиОтчета = ФайлКорневойXML.Путь + ИмяОбработкиИлиОтчета; 186 | 187 | Если Прав(НРег(ИмяФайлаОбработкиИлиОтчета),4) = ".epf" Тогда 188 | ИмяФайлаВременныйОбработкаИлиОтчет = ПолучитьИмяВременногоФайла("epf"); 189 | Иначе 190 | ИмяФайлаВременныйОбработкаИлиОтчет = ПолучитьИмяВременногоФайла("erf"); 191 | КонецЕсли; 192 | 193 | 194 | ФайлОбработкаИлиОтчет = Новый Файл(ИмяФайлаОбработкиИлиОтчета); 195 | Если ФайлОбработкаИлиОтчет.Существует() Тогда 196 | //Проверим версию. Если она совпадает, то собирать файл не надо. 197 | ФайлВерсии = Новый Файл(ИмяФайлаВерсии); 198 | Если ФайлВерсии.Существует() Тогда 199 | Массив = Новый Массив; 200 | 201 | Текст = Новый ЧтениеТекста; 202 | Текст.Открыть(ИмяФайлаВерсии,"UTF-8"); 203 | 204 | Пока Истина Цикл 205 | Стр = Текст.ПрочитатьСтроку(); 206 | Если Стр = Неопределено Тогда 207 | Прервать; 208 | КонецЕсли; 209 | 210 | Массив.Добавить(Стр); 211 | КонецЦикла; 212 | Текст.Закрыть(); 213 | 214 | Если Массив.Количество() < 1 Тогда 215 | ВызватьИсключение "Н смог прочитать файл версии: " + ИмяФайлаВерсии; 216 | КонецЕсли; 217 | 218 | ВерсияСтрокой = Массив[0]; 219 | Поз = Найти(ВерсияСтрокой,"|"); 220 | ВерсияСтрокой = Лев(ВерсияСтрокой,Поз-1); 221 | 222 | ТекущаяВерсияСтрокой = ДатуКСтроке(ФайлОбработкаИлиОтчет.ПолучитьВремяИзменения()); 223 | Если НРег(ВерсияСтрокой) = НРег(ТекущаяВерсияСтрокой) Тогда 224 | Массив.Удалить(0); 225 | Если ПроверитьЧтоВсеФайлыИсходниковСоответствуютИхВерсиям(Массив,ФайлОбработкаИлиОтчет.Путь + ИмяКаталога_filename) Тогда 226 | Лог.Информация("" + ИмяОбработкиИлиОтчета + " УЖЕ собран."); 227 | Возврат; 228 | КонецЕсли; 229 | 230 | КонецЕсли; 231 | 232 | Если ТекущаяВерсияСтрокой > ВерсияСтрокой Тогда 233 | Лог.Ошибка("Файл <" + ИмяФайлаОбработкиИлиОтчета + "> имеет версию новее чем в исходниках. Удалите " + ФайлОбработкаИлиОтчет.Имя + ", если хотите пересобрать его."); 234 | Лог.Ошибка("Версия в исходниках: " + ВерсияСтрокой); 235 | Лог.Ошибка("Версия файла: " + ТекущаяВерсияСтрокой); 236 | ВызватьИсключение "Обработка прервана."; 237 | КонецЕсли; 238 | 239 | КонецЕсли; 240 | КонецЕсли; 241 | 242 | 243 | ПараметрыЗапуска = УправлениеКонфигуратором.ПолучитьПараметрыЗапуска(); 244 | ПараметрыЗапуска.Добавить("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяФайлаКорневойXml + """ """ + ИмяФайлаВременныйОбработкаИлиОтчет + """"); 245 | 246 | ИмяФайлаOut = ПолучитьИмяВременногоФайла("txt"); 247 | ПараметрыЗапуска.Добавить("/Out """ + ИмяФайлаOut + """"); 248 | 249 | 250 | 251 | Попытка 252 | УправлениеКонфигуратором.ВыполнитьКоманду(ПараметрыЗапуска); 253 | Исключение 254 | Лог.Ошибка(ОписаниеОшибки()); 255 | Лог.Ошибка(УправлениеКонфигуратором.ВыводКоманды()); 256 | ВызватьИсключение "Выгрузка обработок в xml прервана."; 257 | КонецПопытки; 258 | 259 | УдалитьФайлы(ИмяФайлаОбработкиИлиОтчета); 260 | ПереместитьФайл(ИмяФайлаВременныйОбработкаИлиОтчет,ИмяФайлаОбработкиИлиОтчета); 261 | 262 | ФайлОбработкаИлиОтчет = Новый Файл(ИмяФайлаОбработкиИлиОтчета); 263 | ВремяИзменения = ДатуКСтроке(ФайлОбработкаИлиОтчет.ПолучитьВремяИзменения()); 264 | 265 | 266 | //запишем версию файла 267 | ЗаписатьВерсиюОбработкиИлиОтчета(ФайлОбработкаИлиОтчет,ИмяКаталога_filename,ИмяОбработкиИлиОтчета); 268 | 269 | Лог.Информация("" + ИмяОбработкиИлиОтчета + " собран."); 270 | КонецПроцедуры 271 | 272 | Функция ЭтоСлужебныйФайл(ИмяФайла) 273 | Если Нрег(ИмяФайла) = "filename" Тогда 274 | Возврат Истина; 275 | ИначеЕсли Нрег(ИмяФайла) = "fileversion" Тогда 276 | Возврат Истина; 277 | КонецЕсли; 278 | 279 | Возврат Ложь; 280 | КонецФункции 281 | 282 | Функция ПолучитьВерсииФайловВКаталоге(Каталог) 283 | //Сообщить("КаталогПолучитьВерсииФайловВКаталоге="+Каталог); 284 | 285 | ТаблицаФайлов = Новый ТаблицаЗначений; 286 | ТаблицаФайлов.Колонки.Добавить("ПолноеИмя"); 287 | ТаблицаФайлов.Колонки.Добавить("ЧастьПути"); 288 | ТаблицаФайлов.Колонки.Добавить("ЭтоКаталог"); 289 | ТаблицаФайлов.Колонки.Добавить("ВремяИзменения"); 290 | 291 | Файлы = НайтиФайлы(Каталог,"*",Истина); 292 | Для Каждого Файл Из Файлы Цикл 293 | Если ЭтоСлужебныйФайл(Файл.Имя) Тогда 294 | Продолжить; 295 | КонецЕсли; 296 | 297 | 298 | СтрокаТаблицаФайлов = ТаблицаФайлов.Добавить(); 299 | СтрокаТаблицаФайлов.ПолноеИмя = Файл.ПолноеИмя; 300 | СтрокаТаблицаФайлов.ЭтоКаталог = Файл.ЭтоКаталог(); 301 | СтрокаТаблицаФайлов.ЧастьПути = Сред(Файл.ПолноеИмя,СтрДлина(Каталог)); 302 | 303 | //Сообщить("СтрокаТаблицаФайлов.ЧастьПути="+СтрокаТаблицаФайлов.ЧастьПути); 304 | 305 | Если СтрокаТаблицаФайлов.ЭтоКаталог Тогда 306 | Продолжить; 307 | КонецЕсли; 308 | 309 | СтрокаТаблицаФайлов.ВремяИзменения = ДатуКСтроке(Файл.ПолучитьВремяИзменения()); 310 | КонецЦикла; 311 | 312 | Возврат ТаблицаФайлов; 313 | КонецФункции 314 | 315 | Процедура ЗаписатьВерсиюОбработкиИлиОтчета(ФайлОбработкаИлиОтчет,ИмяКаталогаОбработки,ИмяОбработкиИлиОтчета) 316 | ИмяФайлаВерсии = ФайлОбработкаИлиОтчет.Путь + ПолучитьРазделительПути()+ ИмяКаталогаОбработки + ПолучитьРазделительПути() + "fileversion"; 317 | //Сообщить("ИмяФайлаВерсии="+ИмяФайлаВерсии); 318 | УдалитьФайлы(ИмяФайлаВерсии); 319 | ВремяИзменения = ДатуКСтроке(ФайлОбработкаИлиОтчет.ПолучитьВремяИзменения()); 320 | 321 | ВерсииФайлов = ПолучитьВерсииФайловВКаталоге(ФайлОбработкаИлиОтчет.Путь + ИмяКаталогаОбработки + ПолучитьРазделительПути()); 322 | 323 | ЗТ = Новый ЗаписьТекста(ИмяФайлаВерсии,"UTF-8",,Истина); 324 | ЗТ.ЗаписатьСтроку(ВремяИзменения + "|" + ИмяОбработкиИлиОтчета); 325 | 326 | Для Каждого СтрокаВерсииФайлов Из ВерсииФайлов Цикл 327 | Если СтрокаВерсииФайлов.ЭтоКаталог Тогда 328 | Продолжить; 329 | КонецЕсли; 330 | 331 | Стр = "" + СтрокаВерсииФайлов.ВремяИзменения + "|" + СтрокаВерсииФайлов.ЧастьПути; 332 | ЗТ.ЗаписатьСтроку(Стр); 333 | КонецЦикла; 334 | 335 | ЗТ.Закрыть(); 336 | КонецПроцедуры 337 | 338 | Процедура СобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(Путь) 339 | Файл = Новый Файл(Путь); 340 | Если НЕ Файл.Существует() Тогда 341 | ВызватьИсключение "Каталог <" + Путь + "> не существует."; 342 | КонецЕсли; 343 | 344 | Файлы = НайтиФайлы(Путь,"filename.*",Истина); 345 | 346 | КоличествоФайлов = Файлы.Количество(); 347 | 348 | НомерФайла = 0; 349 | Для Каждого Файл Из Файлы Цикл 350 | НомерФайла = НомерФайла + 1; 351 | 352 | Текст = Новый ЧтениеТекста; 353 | Текст.Открыть(Файл.ПолноеИмя,"UTF-8"); 354 | ИмяОбработкиИлиОтчета = ""; 355 | 356 | Пока Истина Цикл 357 | Стр = Текст.ПрочитатьСтроку(); 358 | Если Стр = Неопределено Тогда 359 | Прервать; 360 | КонецЕсли; 361 | 362 | ИмяОбработкиИлиОтчета = Стр; 363 | КонецЦикла; 364 | Текст.Закрыть(); 365 | 366 | Если ИмяОбработкиИлиОтчета = "" Тогда 367 | ВызватьИсключение "В файле " + Файл.ПолноеИмя + " не найдено имя собираемого файла."; 368 | КонецЕсли; 369 | 370 | Лог.Информация("Файл " + НомерФайла + " из " + КоличествоФайлов + ": " + ИмяОбработкиИлиОтчета); 371 | 372 | ЗагрузитьОбработкуИлиОтчетИзXML(Файл.ПолноеИмя,ИмяОбработкиИлиОтчета); 373 | КонецЦикла; 374 | 375 | КонецПроцедуры 376 | 377 | Функция ПереместитьФайлыДляРазборки(КаталогКудаОбъект, КаталогОткудаОбъект, Маска, МассивУдаляемыхВременныхФайлов) 378 | 379 | МассивПеремещения = НайтиФайлы(КаталогОткудаОбъект.ПолноеИмя, Маска, Истина); 380 | 381 | Для каждого ЭлементМассиваПеремещения из МассивПеремещения Цикл 382 | 383 | ПолноеИмяФайлаОткуда = ЭлементМассиваПеремещения.ПолноеИмя; 384 | КороткоеИмяФайлаОткуда = ЭлементМассиваПеремещения.Имя; 385 | ОтносительноеИмя = СтрЗаменить(ПолноеИмяФайлаОткуда, КаталогОткудаОбъект.ПолноеИмя, ""); 386 | ИмяНовогоКаталога = СтрЗаменить(КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя, КороткоеИмяФайлаОткуда, ""); 387 | 388 | Если НЕ ОбеспечитьКаталог(ИмяНовогоКаталога) Тогда 389 | Продолжить; 390 | КонецЕсли; 391 | 392 | КопироватьФайл(ПолноеИмяФайлаОткуда, КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя); 393 | МассивУдаляемыхВременныхФайлов.Добавить(КаталогОткудаОбъект.ПолноеИмя + ОтносительноеИмя); 394 | //Лог.Информация("Копируем " + ПолноеИмяФайлаОткуда + " в " + КаталогКудаОбъект.ПолноеИмя + ОтносительноеИмя); 395 | КонецЦикла; 396 | 397 | Возврат МассивУдаляемыхВременныхФайлов; 398 | 399 | КонецФункции 400 | 401 | Процедура УстановитьПутьКПлатформеИзПеременнойСреды(УправлениеКонфигуратором) 402 | 403 | // В Linux не видит путь к платформе, возможно из-за изменения пути установки 404 | // Пока будем передавать путь через переменную среды. 405 | // TODO: посмотреть и поправить библиотеки v8runner/v8find 406 | ПутьКПлатформе = ПолучитьПеременнуюСреды("Path1C"); 407 | Если НЕ ПустаяСтрока(ПутьКПлатформе) Тогда 408 | УправлениеКонфигуратором.ПутьКПлатформе1С(ПутьКПлатформе); 409 | КонецЕсли; 410 | 411 | КонецПроцедуры 412 | 413 | Лог = Логирование.ПолучитьЛог("vb.compile.log"); 414 | Лог.УстановитьУровень(УровниЛога.Отладка); 415 | 416 | Если АргументыКоманднойСтроки.Количество() = 0 Тогда 417 | Лог.Ошибка("Не переданы параметры!"); 418 | ИначеЕсли АргументыКоманднойСтроки.Количество() > 2 Тогда 419 | Лог.Ошибка("Скрипт принимает не больше двух параметров!"); 420 | 421 | Иначе 422 | УправлениеКонфигуратором = Новый УправлениеКонфигуратором(); 423 | УстановитьПутьКПлатформеИзПеременнойСреды(УправлениеКонфигуратором); 424 | КаталогБазы = ПолучитьИмяВременногоФайла(); 425 | УправлениеКонфигуратором.СоздатьФайловуюБазу(КаталогБазы); 426 | УправлениеКонфигуратором.УстановитьКонтекст("/F""" + КаталогБазы + """","",""); 427 | 428 | Если АргументыКоманднойСтроки.Количество() = 2 Тогда 429 | 430 | МассивУдаляемыхВременныхФайлов = Новый Массив; 431 | КаталогКудаОбъект = Новый Файл(АргументыКоманднойСтроки[1]); 432 | КаталогОткудаОбъект = Новый Файл(АргументыКоманднойСтроки[0]); 433 | СобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(КаталогОткудаОбъект.ПолноеИмя); 434 | МассивУдаляемыхВременныхФайлов = ПереместитьФайлыДляРазборки(КаталогКудаОбъект,КаталогОткудаОбъект, "*.epf", МассивУдаляемыхВременныхФайлов); 435 | МассивУдаляемыхВременныхФайлов = ПереместитьФайлыДляРазборки(КаталогКудаОбъект,КаталогОткудаОбъект, "*.erf", МассивУдаляемыхВременныхФайлов); 436 | 437 | Для каждого ВременныйФайл из МассивУдаляемыхВременныхФайлов Цикл 438 | УдалитьФайлы(ВременныйФайл); 439 | КонецЦикла; 440 | 441 | Иначе 442 | СобратьОбработкуИлиОтчетВКаталогеИПодКаталогах(АргументыКоманднойСтроки[0]); 443 | КонецЕсли; 444 | 445 | КонецЕсли; 446 | 447 | Сообщить("Обработка завершена."); 448 | 449 | 450 | 451 | -------------------------------------------------------------------------------- /src/AddInNative.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include "../version.h" 4 | #define STRINGIZE2(s) #s 5 | #define STRINGIZE(s) STRINGIZE2(s) 6 | 7 | #ifdef _WINDOWS 8 | #pragma warning (disable : 4267) 9 | #pragma warning (disable : 4302) 10 | #pragma warning (disable : 4311) 11 | #else 12 | #include 13 | #include 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "AddInNative.h" 27 | 28 | #ifdef _WINDOWS 29 | 30 | HMODULE hModule = NULL; 31 | 32 | BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID lpReserved) 33 | { 34 | switch (ul_reason_for_call) 35 | { 36 | case DLL_PROCESS_ATTACH: 37 | ::DisableThreadLibraryCalls(module); 38 | ::hModule = module; 39 | break; 40 | case DLL_THREAD_ATTACH: 41 | case DLL_THREAD_DETACH: 42 | case DLL_PROCESS_DETACH: 43 | break; 44 | } 45 | return TRUE; 46 | } 47 | #endif 48 | 49 | const WCHAR_T* GetClassNames() 50 | { 51 | static const std::u16string names(AddInNative::getComponentNames()); 52 | return (const WCHAR_T*)names.c_str(); 53 | } 54 | 55 | long GetClassObject(const WCHAR_T* wsName, IComponentBase** pInterface) 56 | { 57 | if (*pInterface) return 0; 58 | auto cls_name = std::u16string(reinterpret_cast(wsName)); 59 | return long(*pInterface = AddInNative::CreateObject(cls_name)); 60 | } 61 | 62 | long DestroyObject(IComponentBase** pInterface) 63 | { 64 | if (!*pInterface) return -1; 65 | delete* pInterface; 66 | *pInterface = nullptr; 67 | return 0; 68 | } 69 | 70 | std::string WC2MB(const std::wstring& wstr) 71 | { 72 | std::wstring_convert> converter; 73 | return converter.to_bytes(wstr); 74 | } 75 | 76 | std::wstring MB2WC(const std::string& str) 77 | { 78 | std::wstring_convert> converter; 79 | return converter.from_bytes(str); 80 | } 81 | 82 | std::map AddInNative::components; 83 | 84 | AddInNative::AddInNative(void) : result(nullptr, this) { 85 | AddProperty(u"Version", u"Версия", [&](VH var) { var = this->version(); }); 86 | } 87 | 88 | std::string AddInNative::version() 89 | { 90 | return STRINGIZE(VERSION_FULL); 91 | } 92 | 93 | bool AddInNative::Init(void* pConnection) 94 | { 95 | m_iConnect = static_cast(pConnection); 96 | if (m_iConnect) m_iConnect->SetEventBufferDepth(100); 97 | return m_iConnect != nullptr; 98 | } 99 | 100 | bool AddInNative::setMemManager(void* memory) 101 | { 102 | return m_iMemory = static_cast(memory); 103 | } 104 | 105 | long AddInNative::GetInfo() 106 | { 107 | return 2000; 108 | } 109 | 110 | void AddInNative::Done() 111 | { 112 | } 113 | 114 | bool AddInNative::RegisterExtensionAs(WCHAR_T** wsLanguageExt) 115 | { 116 | return *wsLanguageExt = W(name.c_str()); 117 | } 118 | 119 | long AddInNative::GetNProps() 120 | { 121 | return properties.size(); 122 | } 123 | 124 | long AddInNative::FindProp(const WCHAR_T* wsPropName) 125 | { 126 | std::u16string name((char16_t*)wsPropName); 127 | for (auto it = properties.begin(); it != properties.end(); ++it) { 128 | for (auto n = it->names.begin(); n != it->names.end(); ++n) { 129 | if (n->compare(name) == 0) return long(it - properties.begin()); 130 | } 131 | } 132 | name = upper(name); 133 | for (auto it = properties.begin(); it != properties.end(); ++it) { 134 | for (auto n = it->names.begin(); n != it->names.end(); ++n) { 135 | if (upper(*n).compare(name) == 0) return long(it - properties.begin()); 136 | } 137 | } 138 | return -1; 139 | } 140 | 141 | const WCHAR_T* AddInNative::GetPropName(long lPropNum, long lPropAlias) 142 | { 143 | try { 144 | auto it = std::next(properties.begin(), lPropNum); 145 | if (it == properties.end()) return nullptr; 146 | auto nm = std::next(it->names.begin(), lPropAlias); 147 | if (nm == it->names.end()) return nullptr; 148 | return W(nm->c_str()); 149 | } 150 | catch (...) { 151 | return nullptr; 152 | } 153 | } 154 | 155 | bool AddInNative::GetPropVal(const long lPropNum, tVariant* pvarPropVal) 156 | { 157 | auto it = std::next(properties.begin(), lPropNum); 158 | if (it == properties.end()) return false; 159 | if (!it->getter) return false; 160 | try { 161 | it->getter(VA(pvarPropVal, &(*it))); 162 | return true; 163 | } 164 | catch (const std::u16string& msg) { 165 | AddError(msg); 166 | return false; 167 | } 168 | catch (...) { 169 | return false; 170 | } 171 | } 172 | 173 | bool AddInNative::SetPropVal(const long lPropNum, tVariant* pvarPropVal) 174 | { 175 | auto it = std::next(properties.begin(), lPropNum); 176 | if (it == properties.end()) return false; 177 | if (!it->setter) return false; 178 | try { 179 | it->setter(VA(pvarPropVal, &(*it))); 180 | return true; 181 | } 182 | catch (const std::u16string& msg) { 183 | AddError(msg); 184 | return false; 185 | } 186 | catch (...) { 187 | return false; 188 | } 189 | } 190 | 191 | bool AddInNative::IsPropReadable(const long lPropNum) 192 | { 193 | auto it = std::next(properties.begin(), lPropNum); 194 | if (it == properties.end()) return false; 195 | return (bool)it->getter; 196 | } 197 | 198 | bool AddInNative::IsPropWritable(const long lPropNum) 199 | { 200 | auto it = std::next(properties.begin(), lPropNum); 201 | if (it == properties.end()) return false; 202 | return (bool)it->setter; 203 | } 204 | 205 | long AddInNative::GetNMethods() 206 | { 207 | return methods.size(); 208 | } 209 | 210 | long AddInNative::FindMethod(const WCHAR_T* wsMethodName) 211 | { 212 | std::u16string name((char16_t*)wsMethodName); 213 | for (auto it = methods.begin(); it != methods.end(); ++it) { 214 | for (auto n = it->names.begin(); n != it->names.end(); ++n) { 215 | if (n->compare(name) == 0) return long(it - methods.begin()); 216 | } 217 | } 218 | name = upper(name); 219 | for (auto it = methods.begin(); it != methods.end(); ++it) { 220 | for (auto n = it->names.begin(); n != it->names.end(); ++n) { 221 | if (upper(*n).compare(name) == 0) return long(it - methods.begin()); 222 | } 223 | } 224 | return -1; 225 | } 226 | 227 | const WCHAR_T* AddInNative::GetMethodName(const long lMethodNum, const long lMethodAlias) 228 | { 229 | try { 230 | auto it = std::next(methods.begin(), lMethodNum); 231 | if (it == methods.end()) return nullptr; 232 | auto nm = std::next(it->names.begin(), lMethodAlias); 233 | if (nm == it->names.end()) return nullptr; 234 | return W(nm->c_str()); 235 | } 236 | catch (...) { 237 | return nullptr; 238 | } 239 | } 240 | 241 | long AddInNative::GetNParams(const long lMethodNum) 242 | { 243 | auto it = std::next(methods.begin(), lMethodNum); 244 | if (it == methods.end()) return 0; 245 | if (std::get_if(&it->handler)) return 0; 246 | if (std::get_if(&it->handler)) return 1; 247 | if (std::get_if(&it->handler)) return 2; 248 | if (std::get_if(&it->handler)) return 3; 249 | if (std::get_if(&it->handler)) return 4; 250 | if (std::get_if(&it->handler)) return 5; 251 | if (std::get_if(&it->handler)) return 6; 252 | if (std::get_if(&it->handler)) return 7; 253 | return 0; 254 | } 255 | 256 | bool AddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant* pvarParamDefValue) 257 | { 258 | try { 259 | VA(pvarParamDefValue).clear(); 260 | auto it = std::next(methods.begin(), lMethodNum); 261 | if (it == methods.end()) return true; 262 | auto p = it->defs.find(lParamNum); 263 | if (p == it->defs.end()) return true; 264 | auto var = &p->second.variant; 265 | if (auto value = std::get_if(var)) { 266 | VA(pvarParamDefValue) = *value; 267 | return true; 268 | } 269 | if (auto value = std::get_if(var)) { 270 | VA(pvarParamDefValue) = *value; 271 | return true; 272 | } 273 | if (auto value = std::get_if(var)) { 274 | VA(pvarParamDefValue) = *value; 275 | return true; 276 | } 277 | if (auto value = std::get_if(var)) { 278 | VA(pvarParamDefValue) = *value; 279 | return true; 280 | } 281 | return true; 282 | } 283 | catch (const std::u16string& msg) { 284 | AddError(msg); 285 | return false; 286 | } 287 | catch (...) { 288 | return false; 289 | } 290 | } 291 | 292 | bool AddInNative::HasRetVal(const long lMethodNum) 293 | { 294 | try { 295 | auto it = std::next(methods.begin(), lMethodNum); 296 | if (it == methods.end()) return false; 297 | return it->hasRetVal; 298 | } 299 | catch (...) { 300 | return false; 301 | } 302 | } 303 | 304 | bool AddInNative::CallMethod(MethFunction* func, tVariant* p, Meth* m, const long lSizeArray) 305 | { 306 | if (auto handler = std::get_if(func)) { 307 | (*handler)(); 308 | return true; 309 | } 310 | if (auto handler = std::get_if(func)) { 311 | if (lSizeArray < 1) throw std::bad_function_call(); 312 | (*handler)(VA(p, m, 0)); 313 | return true; 314 | } 315 | if (auto handler = std::get_if(func)) { 316 | if (lSizeArray < 2) throw std::bad_function_call(); 317 | (*handler)(VA(p, m, 0), VA(p, m, 1)); 318 | return true; 319 | } 320 | if (auto handler = std::get_if(func)) { 321 | if (lSizeArray < 3) throw std::bad_function_call(); 322 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2)); 323 | return true; 324 | } 325 | if (auto handler = std::get_if(func)) { 326 | if (lSizeArray < 4) throw std::bad_function_call(); 327 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3)); 328 | return true; 329 | } 330 | if (auto handler = std::get_if(func)) { 331 | if (lSizeArray < 5) throw std::bad_function_call(); 332 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4)); 333 | return true; 334 | } 335 | if (auto handler = std::get_if(func)) { 336 | if (lSizeArray < 6) throw std::bad_function_call(); 337 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4), VA(p, m, 5)); 338 | return true; 339 | } 340 | if (auto handler = std::get_if(func)) { 341 | if (lSizeArray < 7) throw std::bad_function_call(); 342 | (*handler)(VA(p, m, 0), VA(p, m, 1), VA(p, m, 2), VA(p, m, 3), VA(p, m, 4), VA(p, m, 5), VA(p, m, 6)); 343 | return true; 344 | } 345 | return false; 346 | } 347 | 348 | bool AddInNative::CallAsProc(const long lMethodNum, tVariant* paParams, const long lSizeArray) 349 | { 350 | auto it = std::next(methods.begin(), lMethodNum); 351 | if (it == methods.end()) return false; 352 | try { 353 | result << VA(nullptr); 354 | return CallMethod(&it->handler, paParams, &(*it), lSizeArray); 355 | } 356 | catch (const std::u16string& msg) { 357 | AddError(msg); 358 | return false; 359 | } 360 | catch (...) { 361 | return false; 362 | } 363 | } 364 | 365 | bool AddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) 366 | { 367 | auto it = std::next(methods.begin(), lMethodNum); 368 | if (it == methods.end()) return false; 369 | try { 370 | result << VA(pvarRetValue); 371 | bool ok = CallMethod(&it->handler, paParams, &(*it), lSizeArray); 372 | result << VA(nullptr); 373 | return ok; 374 | } 375 | catch (const std::u16string& msg) { 376 | AddError(msg); 377 | return false; 378 | } 379 | catch (...) { 380 | result << VA(nullptr); 381 | return false; 382 | } 383 | } 384 | 385 | void AddInNative::SetLocale(const WCHAR_T* locale) 386 | { 387 | try { 388 | std::string loc = WCHAR2MB(locale); 389 | this->alias = loc == "rus"; 390 | std::locale::global(std::locale{ loc.c_str() }); 391 | } 392 | catch (std::runtime_error&) { 393 | std::locale::global(std::locale{ "" }); 394 | } 395 | } 396 | 397 | std::u16string AddInNative::getComponentNames() { 398 | const char16_t* const delim = u"|"; 399 | std::vector names; 400 | for (auto it = components.begin(); it != components.end(); ++it) names.push_back(it->first); 401 | std::basic_ostringstream, std::allocator> imploded; 402 | std::copy(names.begin(), names.end(), std::ostream_iterator>(imploded, delim)); 403 | std::u16string result = imploded.str(); 404 | result.pop_back(); 405 | return result; 406 | } 407 | 408 | std::u16string AddInNative::AddComponent(const std::u16string& name, CompFunction creator) 409 | { 410 | components.insert({ name, creator }); 411 | return name; 412 | } 413 | 414 | AddInNative* AddInNative::CreateObject(const std::u16string& name) { 415 | auto it = components.find(name); 416 | if (it == components.end()) return nullptr; 417 | AddInNative* object = it->second(); 418 | object->name = name; 419 | return object; 420 | } 421 | 422 | void AddInNative::AddProperty(const std::u16string& nameEn, const std::u16string& nameRu, const PropFunction& getter, const PropFunction& setter) 423 | { 424 | properties.push_back({ { nameEn, nameRu }, getter, setter }); 425 | } 426 | 427 | void AddInNative::AddProcedure(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction& handler, const MethDefaults& defs) 428 | { 429 | methods.push_back({ { nameEn, nameRu }, handler, defs, false }); 430 | } 431 | 432 | void AddInNative::AddFunction(const std::u16string& nameEn, const std::u16string& nameRu, const MethFunction& handler, const MethDefaults& defs) 433 | { 434 | methods.push_back({ { nameEn, nameRu }, handler, defs, true }); 435 | } 436 | 437 | bool ADDIN_API AddInNative::AllocMemory(void** pMemory, unsigned long ulCountByte) const 438 | { 439 | return m_iMemory ? m_iMemory->AllocMemory(pMemory, ulCountByte) : false; 440 | } 441 | 442 | void ADDIN_API AddInNative::FreeMemory(void** pMemory) const 443 | { 444 | if (m_iMemory) m_iMemory->FreeMemory(pMemory); 445 | } 446 | 447 | std::string AddInNative::WCHAR2MB(std::basic_string_view src) 448 | { 449 | #ifdef _WINDOWS 450 | static std::wstring_convert> cvt_utf8_utf16; 451 | return cvt_utf8_utf16.to_bytes(src.data(), src.data() + src.size()); 452 | #else 453 | static std::wstring_convert, char16_t> cvt_utf8_utf16; 454 | return cvt_utf8_utf16.to_bytes(reinterpret_cast(src.data()), 455 | reinterpret_cast(src.data() + src.size())); 456 | #endif//_WINDOWS 457 | } 458 | 459 | std::wstring AddInNative::WCHAR2WC(std::basic_string_view src) { 460 | #ifdef _WINDOWS 461 | return std::wstring(src); 462 | #else 463 | std::wstring_convert> conv; 464 | return conv.from_bytes(reinterpret_cast(src.data()), 465 | reinterpret_cast(src.data() + src.size())); 466 | #endif//_WINDOWS 467 | } 468 | 469 | std::u16string AddInNative::MB2WCHAR(std::string_view src) { 470 | #ifdef _WINDOWS 471 | static std::wstring_convert> cvt_utf8_utf16; 472 | std::wstring tmp = cvt_utf8_utf16.from_bytes(src.data(), src.data() + src.size()); 473 | return std::u16string(reinterpret_cast(tmp.data()), tmp.size()); 474 | #else 475 | static std::wstring_convert, char16_t> cvt_utf8_utf16; 476 | return cvt_utf8_utf16.from_bytes(src.data(), src.data() + src.size()); 477 | #endif//_WINDOWS 478 | } 479 | 480 | std::u16string AddInNative::upper(std::u16string& str) 481 | { 482 | std::transform(str.begin(), str.end(), str.begin(), std::towupper); 483 | return str; 484 | } 485 | 486 | std::wstring AddInNative::upper(std::wstring& str) 487 | { 488 | std::transform(str.begin(), str.end(), str.begin(), std::towupper); 489 | return str; 490 | } 491 | 492 | TYPEVAR AddInNative::VarinantHelper::type() 493 | { 494 | if (pvar == nullptr) throw std::bad_variant_access(); 495 | return pvar->vt; 496 | } 497 | 498 | uint32_t AddInNative::VarinantHelper::size() 499 | { 500 | if (pvar == nullptr) throw std::bad_variant_access(); 501 | if (pvar->vt != VTYPE_BLOB) throw error(VTYPE_BLOB); 502 | return pvar->strLen; 503 | } 504 | 505 | char* AddInNative::VarinantHelper::data() 506 | { 507 | if (pvar == nullptr) throw std::bad_variant_access(); 508 | if (pvar->vt != VTYPE_BLOB) throw error(VTYPE_BLOB); 509 | return pvar->pstrVal; 510 | } 511 | 512 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::string& str) 513 | { 514 | return operator=(AddInNative::MB2WCHAR(str)); 515 | } 516 | 517 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::wstring& str) 518 | { 519 | if (sizeof(wchar_t) == 2) { 520 | return operator=(std::u16string(reinterpret_cast(str.data()), str.size())); 521 | } 522 | else { 523 | return operator=(WC2MB(str)); 524 | } 525 | } 526 | 527 | void AddInNative::VarinantHelper::clear() 528 | { 529 | if (pvar == nullptr) throw std::bad_variant_access(); 530 | switch (TV_VT(pvar)) { 531 | case VTYPE_BLOB: 532 | case VTYPE_PWSTR: 533 | addin->FreeMemory(reinterpret_cast(&TV_WSTR(pvar))); 534 | break; 535 | } 536 | tVarInit(pvar); 537 | } 538 | 539 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(int64_t value) 540 | { 541 | clear(); 542 | if (INT32_MIN <= value && value <= INT32_MAX) { 543 | TV_VT(pvar) = VTYPE_I4; 544 | TV_I4(pvar) = (int32_t)value; 545 | } 546 | else { 547 | TV_VT(pvar) = VTYPE_R8; 548 | TV_R8(pvar) = (double)value; 549 | } 550 | return *this; 551 | } 552 | 553 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(double value) 554 | { 555 | clear(); 556 | TV_VT(pvar) = VTYPE_R8; 557 | TV_R8(pvar) = value; 558 | return *this; 559 | } 560 | 561 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(bool value) 562 | { 563 | clear(); 564 | TV_VT(pvar) = VTYPE_BOOL; 565 | TV_BOOL(pvar) = value; 566 | return *this; 567 | } 568 | 569 | AddInNative::VarinantHelper& AddInNative::VarinantHelper::operator=(const std::u16string& str) 570 | { 571 | clear(); 572 | TV_VT(pvar) = VTYPE_PWSTR; 573 | pvar->pwstrVal = nullptr; 574 | size_t size = (str.size() + 1) * sizeof(char16_t); 575 | if (!addin->AllocMemory(reinterpret_cast(&pvar->pwstrVal), size)) throw std::bad_alloc(); 576 | memcpy(pvar->pwstrVal, str.c_str(), size); 577 | pvar->wstrLen = str.size(); 578 | while (pvar->wstrLen && pvar->pwstrVal[pvar->wstrLen - 1] == 0) pvar->wstrLen--; 579 | return *this; 580 | } 581 | 582 | bool AddInNative::AddError(const std::u16string& descr, long scode) 583 | { 584 | std::u16string info = u"AddIn." + name; 585 | return m_iConnect && m_iConnect->AddError(ADDIN_E_IMPORTANT, (WCHAR_T*)info.c_str(), (WCHAR_T*)descr.c_str(), scode); 586 | } 587 | 588 | static std::u16string typeinfo(TYPEVAR vt, bool alias) 589 | { 590 | switch (vt) { 591 | case VTYPE_EMPTY: 592 | return alias ? u"Неопределено" : u"Undefined"; 593 | case VTYPE_I2: 594 | case VTYPE_I4: 595 | case VTYPE_ERROR: 596 | case VTYPE_UI1: 597 | return alias ? u"Целое число" : u"Integer"; 598 | case VTYPE_BOOL: 599 | return alias ? u"Булево" : u"Boolean"; 600 | case VTYPE_R4: 601 | case VTYPE_R8: 602 | return alias ? u"Число" : u"Float"; 603 | case VTYPE_DATE: 604 | case VTYPE_TM: 605 | return alias ? u"Дата" : u"Date"; 606 | case VTYPE_PSTR: 607 | case VTYPE_PWSTR: 608 | return alias ? u"Строка" : u"String"; 609 | case VTYPE_BLOB: 610 | return alias ? u"Двоичные данные" : u"Binary"; 611 | default: 612 | return alias ? u"Неопределено" : u"Undefined"; 613 | } 614 | } 615 | 616 | std::exception AddInNative::VarinantHelper::error(TYPEVAR vt) const 617 | { 618 | std::basic_stringstream, std::allocator> ss; 619 | if (addin && addin->alias) { 620 | ss << u"Ошибка получения значения"; 621 | if (prop) ss << u" при обращении к свойству <" << prop->names[1] << ">"; 622 | if (meth) ss << u" при вызове метода <" << meth->names[1] << ">"; 623 | if (number >= 0) ss << u" параметр <" << number + 1 << ">"; 624 | ss << u" ожидается <" + typeinfo(vt, true) << u">"; 625 | if (pvar) ss << u" фактически <" + typeinfo(pvar->vt, true) << u">"; 626 | } 627 | else { 628 | ss << u"Error getting value"; 629 | if (prop) ss << u" of property <" << prop->names[0] << ">"; 630 | if (meth) ss << u" when calling method <" << meth->names[0] << ">"; 631 | if (number >= 0) ss << u" parameter <" << number + 1 << ">"; 632 | ss << u" expected <" + typeinfo(vt, false) << u">"; 633 | if (pvar) ss << u" actual value <" + typeinfo(pvar->vt, false) << u">"; 634 | } 635 | if (addin) addin->AddError(ss.str()); 636 | return std::bad_typeid(); 637 | } 638 | 639 | AddInNative::VarinantHelper::operator std::string() const 640 | { 641 | std::u16string str(*this); 642 | return WCHAR2MB((WCHAR_T*)str.c_str()); 643 | } 644 | 645 | AddInNative::VarinantHelper::operator std::wstring() const 646 | { 647 | std::u16string str(*this); 648 | return WCHAR2WC((WCHAR_T*)str.c_str()); 649 | } 650 | 651 | AddInNative::VarinantHelper::operator std::u16string() const 652 | { 653 | if (pvar == nullptr) throw std::bad_variant_access(); 654 | if (pvar->vt != VTYPE_PWSTR) throw error(VTYPE_PWSTR); 655 | return reinterpret_cast(pvar->pwstrVal); 656 | } 657 | 658 | AddInNative::VarinantHelper::operator int64_t() const 659 | { 660 | if (pvar == nullptr) throw std::bad_variant_access(); 661 | switch (TV_VT(pvar)) { 662 | case VTYPE_I2: 663 | case VTYPE_I4: 664 | case VTYPE_UI1: 665 | case VTYPE_ERROR: 666 | return (int64_t)pvar->lVal; 667 | case VTYPE_R4: 668 | case VTYPE_R8: 669 | return (int64_t)pvar->dblVal; 670 | default: 671 | throw error(VTYPE_I4); 672 | } 673 | } 674 | 675 | AddInNative::VarinantHelper::operator int() const 676 | { 677 | if (pvar == nullptr) throw std::bad_variant_access(); 678 | switch (TV_VT(pvar)) { 679 | case VTYPE_I2: 680 | case VTYPE_I4: 681 | case VTYPE_UI1: 682 | case VTYPE_ERROR: 683 | return (int)pvar->lVal; 684 | case VTYPE_R4: 685 | case VTYPE_R8: 686 | return (int)pvar->dblVal; 687 | default: 688 | throw error(VTYPE_I4); 689 | } 690 | } 691 | 692 | AddInNative::VarinantHelper::operator double() const 693 | { 694 | if (pvar == nullptr) throw std::bad_variant_access(); 695 | switch (TV_VT(pvar)) { 696 | case VTYPE_I2: 697 | case VTYPE_I4: 698 | case VTYPE_UI1: 699 | case VTYPE_ERROR: 700 | return (double)pvar->lVal; 701 | case VTYPE_R4: 702 | case VTYPE_R8: 703 | return (double)pvar->dblVal; 704 | default: 705 | throw error(VTYPE_R4); 706 | } 707 | } 708 | 709 | AddInNative::VarinantHelper::operator bool() const 710 | { 711 | if (pvar == nullptr) throw std::bad_variant_access(); 712 | switch (TV_VT(pvar)) { 713 | case VTYPE_BOOL: 714 | return TV_BOOL(pvar); 715 | case VTYPE_I2: 716 | case VTYPE_I4: 717 | case VTYPE_UI1: 718 | case VTYPE_ERROR: 719 | return (bool)pvar->lVal; 720 | default: 721 | throw error(VTYPE_BOOL); 722 | } 723 | } 724 | 725 | void AddInNative::VarinantHelper::AllocMemory(unsigned long size) 726 | { 727 | clear(); 728 | if (!addin->AllocMemory((void**)&pvar->pstrVal, size)) throw std::bad_alloc(); 729 | TV_VT(pvar) = VTYPE_BLOB; 730 | pvar->strLen = size; 731 | } 732 | 733 | WCHAR_T* AddInNative::W(const char16_t* str) const 734 | { 735 | WCHAR_T* res = NULL; 736 | size_t length = std::char_traits::length(str) + 1; 737 | unsigned long size = length * sizeof(WCHAR_T); 738 | if (!AllocMemory((void**)&res, size)) throw std::bad_alloc(); 739 | memcpy(res, str, size); 740 | return res; 741 | } 742 | 743 | --------------------------------------------------------------------------------