Перейти к публикации

Вопрос по Ug/open


Рекомендованные сообщения

Вопрос , как из одного UG/Styler диалога вызвать другой UG/Styler диалог.

Ткните в документацию или поделитесь куском кода.

А то что то :wallbash:

Ссылка на сообщение
Поделиться на других сайтах


Вопрос , как из одного UG/Styler диалога вызвать другой UG/Styler диалог.

Ткните в документацию или поделитесь куском кода.

А то что то  :wallbash:

<{POST_SNAPBACK}>

Да элементарно

Есть функция UF_STYLER_create_dialog

Только нужно иметь в виду что в массиве структур родительского диалога

UF_STYLER_callback_info_t

{IMPELLER_ACTION_OPEN  , UF_STYLER_ACTIVATE_CB     , 1, IMPELLER_action_open_cb},
------------------------------

При вызове некоторых других функций типа UF_STYLER_create_dialog которые приводят к созданию дочернего окна также нужна 1

-----------------------------

int IMPELLER_action_open_cb ( int dialog_id,

             void * client_data,

             UF_STYLER_item_value_type_p_t callback_data)

{ int irc, response;

  static char filename[UF_CFI_MAX_PATH_NAME_SIZE + UF_CFI_MAX_FILE_NAME_SIZE ]="";

  static char defname[UF_CFI_MAX_PATH_NAME_SIZE + UF_CFI_MAX_FILE_NAME_SIZE]="";

  static char prompt_string[133]="Select input filename";

  static char title_string[133]="Open file";

  static char filter_string[UF_CFI_MAX_PATH_NAME_SIZE + 1]="*.xml";



  if(UF_initialize() != 0) return (UF_UI_CB_CONTINUE_DIALOG);

  try

  {

  impeller_profile_dialog dialog(dialog_id);



  strcpy(defname, filename);

  irc=UF_UI_create_filebox(prompt_string, title_string,

                           filter_string, defname, filename, &response);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



    switch(response)

    {

    case UF_UI_CANCEL:

       {

       strcpy(filename, ""); strcpy(filter_string, "*.xml");

       break;

       }

    case UF_UI_OK:

       {

       dialog.dictinary_impeller[dialog.solid_tag]->read_xml(filename);

       dialog.update_dialog();

       break;

       }

    default:  throw base_err(THIS_FILE, __LINE__, "unknown case");

    }





  }

  catch(base_err& e) { e.trace(THIS_FILE, __LINE__);  ug_err(e).message(); }

  catch(...)         { base_err e(THIS_FILE, __LINE__, "System error"); ug_err(e).message(); }

    UF_terminate ();

    return (UF_UI_CB_CONTINUE_DIALOG);

}

третий параметр должен быть установлен в 1 в том элементе

диалога из которого будет вызван дочерний диалог

Иначе ничего не получится!!!!!

Изменено пользователем nut888
Ссылка на сообщение
Поделиться на других сайтах

Спасибо. Все вроде бы понятно и мне обязательно пригодится, но сейчас мне хотелось бы другого: вызывать из одного UG/styler диалога второй, уже откомпилированный и слинкованный и который уже в dll формате (как вызвать GRIP вроде бы понятно)

И макрокоманды тоже хотелось бы научиться запускать программно, но и эту ф-ю никак не могу найти в документации.

Продолжающий надеяться на помощь tAlex

Ссылка на сообщение
Поделиться на других сайтах

Спасибо. Все вроде бы понятно и мне обязательно пригодится, но сейчас мне хотелось бы другого: вызывать из одного UG/styler диалога второй, уже откомпилированный и слинкованный и который уже в dll формате (как вызвать GRIP вроде бы понятно)

И макрокоманды тоже хотелось бы научиться запускать программно, но и эту ф-ю никак не могу найти в документации.

Продолжающий надеяться на помощь tAlex

<{POST_SNAPBACK}>

Я думаю стандартными функциями ug не вызвать другую dll

Если Вы программируете на Windows можно попробовать

посмотреть в msdn функции LoadLibrary, CreateProcess итд

Но остается проблема передачи информации между процессами

обработка и перехват ошибочных ситуаций

Я такие вещи не писал

Запуск макросов программно нереализован

Вообще посмотрите функции из раздела UF_UI_...

Там собраны фунции для осуществляющее взаимодействие программы

и юзера

Ссылка на сообщение
Поделиться на других сайтах

Я думаю стандартными функциями ug не вызвать другую dll

Если Вы программируете на Windows можно попробовать

посмотреть в msdn функции LoadLibrary, CreateProcess итд

Но остается проблема передачи информации между процессами

обработка и перехват ошибочных ситуаций

Я такие вещи не писал

<{POST_SNAPBACK}>

А не делает ли что то подобное(вызов Internal UG/open) функция UF_load_library()?

Но я такие вещи тоже не писал :(

Изменено пользователем tALEX
Ссылка на сообщение
Поделиться на других сайтах

А не делает ли что то подобное(вызов Internal UG/open) функция UF_load_library()?

Но я такие вещи тоже не писал :(

<{POST_SNAPBACK}>

Я думаю ей можно попробовать воспользоваться

примеры там есть

Может ее и проще будет использовать

К сожалению не нашел в описании создает ли она отдельный процесс

и дожидается ли родительский процесс окончания работы дочернего

Предполагаю что в UF_load_library так и есть иначе должны были бы быть

еще функции а этот случай как правило наиболее используемый

На виндах все это было бы написано сложнее

Ссылка на сообщение
Поделиться на других сайтах

2 tALEX

Вот приблизительный код, который умеет делать playback для макроса

и загружает необходимую экспортную ф-цию через UF_load_library(...).

Правда ф-ция программного запуска макроса отдает управление сразу и мне не удалось добиться того, чтобы корректно дождаться окончания его выполнения.

Поэтому, если раскомментарить uc1601(...)- то выполнение макроса прервется.

Макрос, который надо запустить должен сидеть в d:\test.macro

Соответственно передача параметров в экспортную ф-цию указатель на которую возвращается после вызова UF_load_library возможна при правильном приведении этого указателя.

Regardzzz ...

#include <iostream>

#include <string>

#include <sstream>



#include <uf.h>

#include <uf_ui.h>



#include <ug_session.hxx>

#include <ug_exception.hxx>

#include <ug_info_window.hxx>



////////////////////////////////////////////////

void printError ( const UgException & erc ) {

    try {

        UgSession sess(true);

        std::stringstream buff;

        buff << "+++ Error: " << erc.askErrorText() << std::endl;

        UgInfoWindow::open();

        UgInfoWindow::write ( buff.str() );

    }

    catch (...) { std::cout << "+++ Error in error handler" << std::endl; }

}



////////////////////////////////////////////////

void printError ( const char * erc ) {

    try {

        UgSession sess(true);

        std::stringstream buff;

        buff << "+++ Error: " << erc << std::endl;

        UgInfoWindow::open();

        UgInfoWindow::write ( buff.str() );

    }

    catch (...) { std::cout << "+++ Error in error handler" << std::endl; }

}





//////////////////////////////////////////////////////////////////////

std::string preparePath () {

    try {

        UgSession sess(true);

        char * path = NULL;

        UgException::throwOnFailure ( UF_translate_variable ("UGII_ROOT_DIR", & path ) );

        return path;

    }

    catch (const UgException & erc) { printError ( erc ); }

    catch (... ) { printError ( "Unhandled exception" );  }

    return "";

}



//////////////////////////////////////////////////////////////////////

extern DllExport void ufusr( char *parm, int *returnCode, int rlen ) {

    try {

        UgSession sess(true);



        ///// function name and path to library

        std::string functionName = "MACRO_playback_from_usertool";

        std::string libraryPath  = preparePath() + "libugui.dll";

        std::string macroPath    = "d:\\test.macro";



        //// pointer to library function

        void  ( __cdecl * func_ptr) ( const char * ) = NULL;



        //// find our function in library

        UgException::throwOnFailure ( 

            UF_load_library ( 

                const_cast < char * >  ( libraryPath.c_str () ) , 

                const_cast < char * >  ( functionName.c_str() ) , 

                reinterpret_cast < UF_load_f_p_t * >  (& func_ptr ) ) );



        //// check if load was successfull and we have valid pointer

        if ( !func_ptr ) { printError ("Invalid function"); return; }



        //// execute this func with d:\\test.macro

        func_ptr( macroPath.c_str() );



        //// display message box on successfull playback 

        //uc1601 ( "Playback finished", 1 );

    }

    catch (const UgException & erc) { printError ( erc ); }

    catch (... ) { printError ( "Unhandled exception" );  }

}
Ссылка на сообщение
Поделиться на других сайтах

Жаль, что все примеры в C++. А функциональность UG/Open_простоC и UG/OpenC++ одинаковая?

А то ведь не хотелось все переделывать в ++ стиле.

С уважением и надеждой на другие примеры tALEX.

зы

Хотя для тех, кто понимает, информации наверно вполне достаточно

Ссылка на сообщение
Поделиться на других сайтах

Я просто привык к С++, SEH , STL и т.д. - с их использованием гораздо быстрее и проще писать код.

В принципе то же самое можно написать и без использования UgOpen++, C++ и STL:

UgSession sess (true) -> UF_initialize() / UF_terminate ()

reinterpret_cast/const_cast -> приведение в стиле C.

UgException::throwOnFailure (...) -> int irc = func(); if (irc) { char error[133]; UF_get_fail_message ( irc, error); }

и т.д.

Regardzzz ...

Ссылка на сообщение
Поделиться на других сайтах

Поверхностное изучение примера любезно предоставленного niki показало, что в $UGII_ROOT лежит много длл в которых сокрыто множество полезных вещей.

И теперь 1 вопрос.

Описаны ли функции находящиеся в этих dll или в примере продемонстрирована недокументированная возможность ?

И второй вопрос

На попытку загрузки dll

и выполнением соотв функции

выразившуюся в таком коде

 if(!UF_load_library ("lib.dll", "ufusr",&ufusr_ptr )){

                                 Show_data("ok_load");

 	 ufusr_ptr(NULL,&ret,NULL);

 	 sprintf(str,"ret = %d",ret);

 	 Show_data(str);

            

  } else {

 	 Show_data("error_load");

  }
UG в окне статуса обьявляет,что

"Меню не может отображаться после повторного вызова меню создающее переключатель"

Т.е. вызов диалога в диалоге неудачен

То есть 2 вопрос остался прежним.

Как вызвать в одном диалоге второй диалог, когда второй диалог dll библиотека.

tALEX

Ссылка на сообщение
Поделиться на других сайтах

Поверхностное изучение примера любезно предоставленного niki показало, что в $UGII_ROOT лежит много длл в которых сокрыто множество полезных вещей.

И теперь 1 вопрос.

Описаны ли функции находящиеся в этих dll или в примере продемонстрирована недокументированная возможность ?

И второй вопрос

На попытку загрузки dll

и выполнением соотв функции

выразившуюся в таком коде

 if(!UF_load_library ("lib.dll", "ufusr",&ufusr_ptr )){

                                 Show_data("ok_load");

  	ufusr_ptr(NULL,&ret,NULL);

  	sprintf(str,"ret = %d",ret);

  	Show_data(str);

            

  } else {

  	Show_data("error_load");

  }
UG в окне статуса обьявляет,что

"Меню не может отображаться после повторного вызова меню создающее переключатель"

Т.е. вызов диалога в диалоге неудачен

То есть 2 вопрос остался прежним.

Как вызвать в одном диалоге второй диалог, когда второй диалог dll библиотека.

tALEX

<{POST_SNAPBACK}>

Попробуй распаралелить процесс

Niki ведь Тебе написал что UF_load_library перекрывает родителя

Ссылка на сообщение
Поделиться на других сайтах

2 tALEX

По вопросу намба ван - Это недокументированные (для не разработчиков UG) ф-ции. Их имена и то что они делают получено в результате ковыряния в SoftIce, OllyDbg, dumpbin.

По вопросу намба ту - Я написал небольшой пример (для NX2 + VisualStudio 7.0). Для того чтобы он корректно заработал надо :

0. Создать папку, например d:\\test

1. В ней создать папку application

2. В файл <там где установлен NX2>\UGII\menus\custom_dirs.dat дописать строчку d:\test Это надо для того чтобы UG смогда найти диалоговые файлы.

3. Открыть проект в VisualStudio 7.0

4. В файле first_dialog_template.cpp найти #define PATH_TO_SECOND_DLL и поменять на полный путь типа d:\\test\\application\\second_dialog.dll - т.к. UF_load_library требует полный путь к dll.

5. Скомпилировать/слинковать проект.

6. В папке output_data должны быть 4 файла - 2 dll-ки и 2 dlg-шки. - Их надо скопировать в папку d:\test\application

7. Запустить NX2 , File->Execute-> UgOpen -> выбрать d:\test\application\first_dialog.dll.

Regardzzz ...

dialog_examples.rar

Ссылка на сообщение
Поделиться на других сайтах

to niki

Ворос по вопросу намбе ван

Что бы ковыряться отладчиками в кодах надо

а) быть фанатом этого дела

б) что бы деньги платили

в) понимать невозможность написания нормального проекта под UG/Open без знания недокументированных возможностей

г) а+б+с

д) что то еще

Но это скорее не вопрос, а размышления по поводу того, в какое болото меня несет :)

А за исходники спасибо

Очень я люблю читать исходники.

Даже больше, чем документацию.

Интересно, будут ли в исходниках недокументированные возможности :)

tALEX

Ссылка на сообщение
Поделиться на других сайтах

Писать "нормальные проекты без недокументированных возможностей" не

составляет никаких проблем, просто иногда (очень редко) появляется

проблема, решить которую можно только поковырявшись отладчиком. ( например можно заставить UG отрисовывать линию сечения (iso128) на виде без осевых линий ).

Хороший UG-овый программист должен помимо знания языка

программирования должен уметь правильно работать в самой UG, знать её так

сказать движок( что за что цепляется, связи и т.д. ). По началу кодописание

под UG может казаться очень сложным, но на самом деле там ничего

сверхестественного нет.

Кстати если из GRIP-a есть возможность запустить macro ( где то такая инфа

проскакивала ) , то лучше использовать эту возможность, чем писать

потенциально опасный код ( с использованием внутренних ф-ций), который

может когда нибудь проглючить.

PS Пример то собрался/запустился ?

Regardzzz ...

Ссылка на сообщение
Поделиться на других сайтах

И теперь хочется подвести некоторые итоги

1) Вызвать один диалог из другого можно

а) функцией UF_STYLER_create_dialog(как отмечал nut888 )

б) через загрузку dll(пример любезно предоставлен niki)

2) И, что бы диалог действительно вызвался

как отметил nut888

Только нужно иметь в виду что в массиве структур родительского диалога

UF_STYLER_callback_info_t

{IMPELLER_ACTION_OPEN  , UF_STYLER_ACTIVATE_CB     , 1, IMPELLER_action_open_cb},

При вызове некоторых других функций типа UF_STYLER_create_dialog которые приводят к созданию дочернего окна также нужна 1

В документации тоже написано, что

is_dialog_launching_cb

int is_dialog_launching_cb

Informs the UIStyler that this callback will construct a dialog.

В общем, если при нажатии на кнопку надо диалог, поставь 1 в третей позиции в том месте структуры, где описана эта кнопка.

Всем спасибо

tALEX

Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете опубликовать сообщение сейчас, а зарегистрироваться позже. Если у вас есть аккаунт, войдите в него для написания от своего имени.
Примечание: вашему сообщению потребуется утверждение модератора, прежде чем оно станет доступным.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.




×
×
  • Создать...