На главную страницу
Русский English
 


Поддержка
Форум
Техподдержка
Закрытый разделПерсональная

Авторизация

Запомнить меня на этом компьютере
  Забыли свой пароль?
  Регистрация



Поиск по сайту


Подписка

Изменение параметров

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


Список форумов
Новые темы
Список тем
Поиск по форумам
Помощь
Войти
Регистрация







Программный комплекс «RasrWin»
Программный комплекс «RastrWin»
© «RastrWin», 1988-2019