Русский
English
Главная
RastrWin
Программа
Последние изменения
Часто задаваемые вопросы
Аннотация
Лицензирование и защита от копирования
Права Windows для пользователя RastrWin
Курсы
Компонентная архитектура
Интерфейс
Инструкция по установке
Документация, видео, презентации
Свидетельство о регистрации
RastrKZ
RastrMDP
RastrOS
ZamerSeti
Архив
Bars-Lincor
Расчетная модель
Система моделирования
Последние изменения
Программа
Инструкция пользователя
Инсталляция
RUStab
Загрузка
Последние изменения
Поддержка
Поддержка
Форум
Техподдержка
Персональная
Макро студия
Макро студия
Автоматизация
Работа с SQL
Оценка параметров ЛЭП и ТР
Эффективность размыкания сети
Анализ напряжений в Excel
Автоматизация с "AutoIt"
Создание графа сети из режима
Передача графики в SVG
Вариантные расчеты
Импортозамещение
О нас
О компании
Фотогалерея
Пользователи
Отчеты об использовании своего имущества
Реквизиты
Поддержка
Форум
Техподдержка
Персональная
Авторизация
Запомнить меня на этом компьютере
Забыли свой пароль?
Регистрация
Поиск по сайту
Подписка
Новости Bars- Lincor
Новости RastrWin
Общие новости
Новости RUStab
Изменение параметров
Hits
66852366
8469
Hosts
3525226
1366
Visitors
53088564
8275
65
Главная
/
Поддержка
/
Форумы
/
Макро
Форум «Макро»
Версия для печати
Список форумов
Новые темы
Список тем
Поиск по форумам
Помощь
Войти
Регистрация
Тема: «
Связь RastrWin и C#
» в форуме:
Макро
Просмотров: 13120
Артем Бабаев
Заглянувший
Всего сообщений:
3
Дата регистрации:
14.07.2018
Создано:
14.07.2018 20:43:19
Приветствую товарищи, хочу обратиться к вам с небольшой проблемой. Возникла необходимость создания отдельного приложения на C# в visual studio, непосредственно связанного с функционалом Rastr. Следуя справке, добавил ссылку на astra.dll и создал объект Rastr. Но если в разделе "Макро" самого растра, после выполнения написанного кода, непосредственно окна, которые должны были измениться - меняются (например, добавили несколько строчек в макросе), то здесь нет. Вопрос в том, как, используя C#, можно связаться с открытым в данный момент окном Растра. Прошерстил русскоязычные форумы, ничего подобного не нашел
P.S. в программировании новичок, мог не увидеть чего-то очевидного
Профиль
Наверх
Александр Александров
Администратор
Всего сообщений:
657
Дата регистрации:
31.05.2008
Создано:
15.07.2018 00:10:20
Здравствуйте, Артем Бабаев!
Попробуйте сформулировать задачу.
Профиль
Наверх
Артем Бабаев
Заглянувший
Всего сообщений:
3
Дата регистрации:
14.07.2018
Создано:
15.07.2018 10:12:23
Задача:
Иметь динамический обмен данных между растром и программой на C#, как это реализовано в собственном макро разделе растра. Вопрос:
Как, используя C#, связаться с открытой в данный момент рабочей областью растра?
Профиль
Наверх
Александр Александров
Администратор
Всего сообщений:
657
Дата регистрации:
31.05.2008
Создано:
15.07.2018 12:44:55
Боюсь что связь с внешним процессом это не та задача с которой стоит начинать изучение программирования. Штатных средств в Растре для этого нет, а имеющиеся в системе являются хаками, либо отладочными интерфейсами.
Вам было бы намного проще создать комобъект Растра и загружать в него данные . Создаётся он аналогично всем прочим комобъектам.
Профиль
Наверх
Артем Бабаев
Заглянувший
Всего сообщений:
3
Дата регистрации:
14.07.2018
Создано:
15.07.2018 14:51:15
Спасибо
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
16.07.2018 16:36:04
В зависимости от задачи, достаточно просто можно вынести расчёты в параллельный поток на javascript в браузере, но как сказано выше в Растре нет средств синхронизации параллельных потоков, так что пользоваться такой возможностью нужно осторожно.
Кстати, мне так и не рассказали, как можно подписаться на сообщения от объекта Растр (похоже, что эта возможность толком не работает), так что обновляться приходиться по таймеру, а не по событию.
Профиль
Наверх
Евгений Машалов
Администратор
Всего сообщений:
1042
Дата регистрации:
23.04.2007
Создано:
16.07.2018 17:55:47
Какие параллельные потоки ? Какие средства синхронизации Вам нужны от Rastr ? Он же не MULTIPLEUSE, как с ним вообще можно синхронизироваться, если он STA ?. Создавайте сколько нужно потоков cо своими Rastr и синхронизируйте их.
Как это толком не работает подписка на сообщения от Rastr, когда в оболочке Вы видите данные только благодаря ее работе ? И кто и в рамках чего Вам должен был рассказать про подписку на IRastrEvents, которая делается совершенно стандартно в любительских средах типа VBA и C# ?
Мысль топик-стартера не совсем понял. Надо управлять экземпляром оболочки RastrWin3 из C# ? Если да - это не предусмотрено. Для автоматизации есть встроенный VBscript. Если надо просто выполнять расчеты и работу с БД Rastr - создавайте экземпляр расчетного блока и делайте что захотите. Можно даже сделать собственный UI.
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
16.07.2018 18:29:19
Берём за основу Ваш же пример макроса с графическим интерфейсом в котором ссылка на объект Rastr передаётся из rba макроса в javascript код в браузере, но меняем код rba макроса так, чтобы он завершался не ожидая закрытия окна браузера. Таким образом мы получаем код который может выполнятся параллельно с кодом Rastr не блокируя его ui.
Если бы была возможность для кода javascript обновлять контролируемые величины по сообщениям от rastr'а было бы вообще замечательно, а так приходится обновляться по таймеру, но на мой топик так и остался с одиноким сообщением
http://www.rastrwin.ru/su
pport/forum/...9&TID=1021
Профиль
Наверх
Евгений Машалов
Администратор
Всего сообщений:
1042
Дата регистрации:
23.04.2007
Создано:
16.07.2018 18:50:52
Вы про эти что ли сообщения ? Которые правильно называются события ?
Код
Set spRastr = WScript.CreateObject("Ast
ra.Rastr.1", "Rastr_")
DocPath = CreateObject("Wscript.She
ll").SpecialFolders("Mydo
cuments") & "RastrWin3\"
spRastr.Load 1, DocPath & "test-rastrcx195.rg2", DocPath & "shablonрежим.rg2"
spRastr.Tables("node").Co
ls("name").Z(0) = "Новый узел"
spRastr.rgm ("p")
Function Rastr_OnChangeData(Hint,T
able,Column,Row)
Message = "Hint " & Hint & " Table " & Table & " Column " & Column & " Row " & Row
if Hint = 3 Then Message = Message & " New Value = " & spRastr.Tables(Table).Col
s(Column).ZS(Row)
WScript.Echo Message
End Function
Function Rastr_OnLog(Code, Level, StageId, TableName, TableIndex, Description, FormName)
WScript.Echo Description
End Function
Тут как бы форум - площадка для обмена информацией. Кто хочет тот отвечает. Если Вы хотите непременно получить ответ - обращайтесь в техподдержку. Если услуга оплачена - с Вами будут работать до получения результата или до тупика.
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
16.07.2018 19:32:30
Да. Вообще в классической теории ООП все обмены между объектами с помощью "сообщений", но в данном случае данный вид "сообщений" -- "события". Тут я, пожалуй, Вас запутал.
по примеру:
Код
Set spRastr = WScript.CreateObject("Ast
?ra.Rastr.1", "Rastr_")
...
Function Rastr_OnChangeData(Hint,T
?able,Column,Row)
...
End Function
этот способ понятен, но так как я использую объект Rastr созданный окружением rbs в RastrWin3, то:
- я не знаю, какой префикс надо использовать для создания обработчиков событий и был ли он вообще объявлен при создании объекта;
- я пока не разобрался (в том числе в силу первого буллита) как привязать обработчик событий из внешнего кода.
Профиль
Наверх
Евгений Машалов
Администратор
Всего сообщений:
1042
Дата регистрации:
23.04.2007
Создано:
16.07.2018 20:45:49
Интересно, когда мы ссылаемся на понятие "классическая теория ООП", мы имеем в виду какую-то определенную публикацию, семейство публикаций ? Или классика это то, что написано в википедии ? Я просто в теории ООП не силен. Как то больше все в практике.
Если Вам понятен приведенный способ, зачем же Вы сетовали на то что вопрос в соседней теме остался без ответа ? Вроде бы там хотелось примера OnChangeData на vbs/rbs. Ну вот он. И еще там что-то про таймер было, который вроде как не нужен если это было понятно.
В RastrWin3 скрипт машина не инициализирует объект Rastr как источник событий. Это же не нужно. Скрипт выполняется синхронно, никаких потоков нет.
В примере как раз и есть внешний код - cscript/vbscript, если понятие "внешний код" меня опять не запутывает.
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
17.07.2018 11:39:51
Ну, думаю, уместно считать классикой описание ООП данное создателями языка Smalltalk. Ту же терминологию часто применяют при ОО проектировании без привязки к языку, например, в UML.
Цитата
В RastrWin3 скрипт машина не инициализирует объект Rastr как источник событий. Это же не нужно. Скрипт выполняется синхронно, никаких потоков нет.
Спасибо за ответ. В принципе я так и понял. Однако, как создать параллельный процесс из кода rbs макроса в Растре я писал двумя постами выше.
Отсюда и вытекает проблема синхронизации, так как у меня получается не заблокирован интерфейс Растра (того экземпляра в котором был запущен rbs макрос породивший параллельный процесс) и я не могу получать в параллельном процессе сообщения (по событию "OnChangeData") от объекта Rastr (того, который инициализировала скрипт машина Растра и который был передан в параллельный процесс), то мне приходиться обновляться либо по кнопке либо по таймеру.
Надеюсь мне удалось достаточно понятно объяснить.
Профиль
Наверх
Михаил Реутов
Постоянный посетитель
Всего сообщений:
224
Дата регистрации:
21.11.2007
Создано:
17.07.2018 13:08:00
Олег Бельцов, может это Вам поможет
http://forum.script-codin
g.com/viewtopic.php?id=55
73
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
17.07.2018 13:33:43
Михаил Реутов,
это скорее не мне а топик стартеру.
Профиль
Наверх
Евгений Машалов
Администратор
Всего сообщений:
1042
Дата регистрации:
23.04.2007
Создано:
17.07.2018 14:03:19
Со скрипт-машиной RastrWin3 проблема не в том, что она не подключает события, а в том что объект Rastr предназначен для работы в STA - Single Threading Apartment. Это означает, что объект доступен только внутри порождающего потока и не может взаимодействовать с другими потоками напрямую. Если передать объект из порождающего потока в другой поток, то должна выполняться процедура под названием Marshalling. Суть процедуры в том, чтобы в принимающем объект потоке был создан клон его интерфейса с учетом технических ограничений и особенностей. В порождающем потоке создается stub, в принимающем (еще можно называть его клиентским) - proxy. С этим proxy принимающий поток и работает, думая что ему передали указатель на объект. На самом деле пара proxy-stub организует обмен данными с выполнением ряда условий. В частности, они синхронизируют вызовы из порождающего и принимающего потоков, или вообще передают вызовы в виде сообщений RPC (мы же можем создать объект вообще на удаленном сервере).
Так вот для STA не принято передавать указатель из порождающего потока в другой. Не то чтобы нельзя - синхронизирующие proxy-stub создаются и работают через механизм сообщений windows. Но это очень медленно. Поэтому мы раньше использовали Marshalling напрямую с внешней синхронизацией, а теперь стараемся потоки упрятать в расчетный блок. Длительные расчеты типа динамики и оптимизации так и работают внутри не блокируя клиента.
Технически я могу сделать на С++ подключение к событиям объекта, переданного из другого потока. Это делается точно также как я бы подключался к ним в родном потоке. Но как это сделать в vbs , в котором - заметьте - эту работу выполяет внешний компонент WScript - я не знаю. Как работает WScript понятно, он по сути и сделан в виде CreateObjectEx в RastrWin3. Он потрошит библиотеку типов, создает Connection Points и делает на них Advise. А что делать с vbs с указателем от внешнего потока чтобы добраться до событий - не понятно. Может и есть какой способ.
Видал реального человека, который, говорят - писал на SmallTalk. Да не что-нибудь - ОИК. Но теперь уже конечно на дельфи, как и все любители легкой жизни и высоких частот CPU.
А вот все кто любил UML даже и до дельфи не дотянули. Так и проектируют базы данных, которые потом все равно делают на SQL. UML - не наш путь.
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
17.07.2018 15:28:12
Спасибо за развёрнутый ответ.
Проблемы и ограничения в принципе понятны, но в ряде случаев будут не критичны. Например, сбор и анализ текущих значений и изменения для некоего набора величин (в общем-то сейчас для этого используется динобмен с Excel).
Можете привести пример C++ кода, хотя бы эскизно?
SmallTalk и Delphi немного устарели. Те, кто пишут под ограниченные аппаратные ресурсы, до сих пор пользуются C/asm, но стоимость такого кода, как я понимаю, непомерно высока.
Для основной массы ПО вполне целесообразна разработка на любом современном высокоуровневом языке упрощающем собственно процесс разработки, а на низкоуровневых языках оптимизировать только критичные участки кода.
UML -- инструмент ОО проектирования, и возможностей в нём раз в три больше чем в SQL. Все паттерны ООП, в любой литературе, описывают через UML. То, что конкретный человек не освоил инструмент, это скорее характеристика человека, а не инструмента.
Профиль
Наверх
Евгений Машалов
Администратор
Всего сообщений:
1042
Дата регистрации:
23.04.2007
Создано:
17.07.2018 15:51:59
Ну asm-то это тысячные процента. Разных чипов выходит 50 штук в год, для каждого писать реализацию народ сойдет с ума. Вполне достаточно C. Тем более что уделать на asm современный компилятор с/с++, который знает про фетчи, это надо постараться.
Про высокоуровневые языки - верно. До той поры, пока не приходится сделать то что ни не умеют или умеют плохо или нет либы нужной, которую можно подключить только платформозависимо. С партнерами-дельфистами мы наелись всякого. А с производительностью за счет промежуточного кода или неплохого компилятора у них и так все отлично.
Про UML я пренебрежительно высказываюсь не потому что я про него плохо знаю. Приходилось делать умный вид архитектора ПО. И кстати про паттерны тоже, что разработки что командные. Возможностей у картинок со стрелочками и человечками конечно на порядок больше чем у реального ПО и реальной среды разработки. Просто люди, которые упарываются в UML и паттерны в итоге оказываются не компетентны ни в предметной области ни в реализации. И так и сидят в придуманной ими самими же роли "постановщиков задачи" для программистов и перемещаются раз в год между третьесортными позициями в конторах с громкими именами. Как по мне - UML и паттерны это шашечки. А ехать - это люди с конкретным скиллом в предметной области и портфолио. Если коллектив не большой и не надо устраивать презентации про то как у нас тут все инновационно - люди с UML просто не нужны. А вот люди которые умеют правильно пользоваться, скажем, TBB, или умеют считать матрицу Якоби УУН без тригонометрии - очень нужны.
Короче хорошее настроение пописать назидалово у меня закончилось. Было ввиду завершения ЕГЭ. Но на этом все. Код на С++ - легко. Это небольшой, но главный фрагмент подключалки событий из RastrWin3
Код
HRESULT CEventHandler::CreateObje
ct(BSTR bstrProgID, BSTR bstrEvtPrefix, IDispatch **ppDisp)
{
CLSID clsid;
HRESULT hr = E_FAIL;
if(FAILED(hr = CLSIDFromProgID(bstrProgI
D,&clsid)))
{
ATLTRACE("\nCEventHan
dler::Failed to CLSIDFromProgID");
return hr;
}
// some trys on create instance
hr = CoCreateInstance(clsid,NU
LL,CLSCTX_ALL,IID_IDispat
ch,(void**)ppDisp);
if(FAILED(hr))
{
hr = CoCreateInstance(clsid,NU
LL,CLSCTX_LOCAL_SERVER,II
D_IDispatch,(void**)ppDis
p);
}
// when failed to create object, leave with HRESULT given
if(FAILED(hr))
{
*ppDisp = NULL;
return hr;
}
// when object is created and no prefix specified, leave with no event connection
_bstr_t bsPrefix = bstrEvtPrefix;
if(!bsPrefix.length())
return hr;
IID iid;
CComPtr<ITypeInfo> spSourceTypeInfo;
// try to find source interface iid and its type info
if(FAILED(GetSourceTypeIn
foByProvideClassInfo(*ppD
isp,iid, &spSourceTypeInfo))) // by IProvideClassInfo
if(FAILED(GetSourceTypeIn
foByRegistry(clsid,iid,&s
pSourceTypeInfo))) // by Registry scan
return E_FAIL;
// got source interface iid and its type info
// connect to object
CComPtr<IConnectionPointC
ontainer> spCont;
CComPtr<IConnectionPoint>
spPoint;
CComObject<CEventSink> *spSink = NULL;
if(FAILED(hr = (*ppDisp)->QueryInterface
(IID_IConnectionPointCont
ainer,(void**)&spCont)))
return hr;
if(FAILED(hr = spCont->FindConnectionPoi
nt(iid,&spPoint)))
return hr;
if(FAILED(hr = CComObject<CEventSink>::C
reateInstance(&spSink)))
return hr;
if(FAILED(hr = spSink->Setup(iid,bstrEvt
Prefix,m_spActiveScript,s
pPoint,spSourceTypeInfo,*
ppDisp)))
return hr;
if(FAILED(hr = spSink->Advise()))
return hr;
m_Events.push_back(spSink
);
hr = S_OK;
return hr;
}
Профиль
Наверх
Олег Бельцов
Посетитель
Всего сообщений:
34
Дата регистрации:
14.05.2012
Создано:
17.07.2018 16:19:56
Спасибо.
Профиль
Наверх
Читают тему
гостей:
1
, пользователей:
0
, из них скрытых:
0
Список форумов
Новые темы
Список тем
Поиск по форумам
Помощь
Войти
Регистрация
Программный комплекс «RastrWin»
© «RastrWin», 1988-2019