|
forms + c-client
|
|||
---|---|---|---|
#18+
Привет Всем. Решаю следующую задачу. Есть С-клиент, который умеет принимать тестовые сообщения. Как бы его можно объединить с приложением forms, чтобы сообщения с этого клиента пересылать в приложение. Какие могут быть варианты? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2016, 16:59 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Client-Server, Web-Forms какая версия? 1. Например Windows Messages 2. Java Bean, JNI ... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2016, 20:21 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Leonid KudryavtsevClient-Server, Web-Forms какая версия? 1. Например Windows Messages 2. Java Bean, JNI Forms 6i Яву пока не хотелось бы, т.к. получается слишком сложно: формс+ява+с Вроде бы у формсов есть С API? Таким образом можно было в нее встроить с-клиент, и она имела бы доступ ко всем переменным приложения на формсах. Кто-нибудь пробовал C API? Нужен хотя бы простейший пример, как его скомпилировать и подключить в приложение формс. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.05.2016, 22:26 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Итак, Oracle forms OPEN API. Взял руководство Using the Oracle® Forms Application Programming Interface (API). Взял из него первый пример: #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <d2fctx.h> /* Forms API context */ #include <d2ffmd.h> /* Form module header file */ int main(int argc, char *argv[]) { d2fctxa ctx_attr; d2fctx *ctx; d2ffmd *form; text *form_name; /* Check arguments */ if (argc != 2) { fprintf(stderr, "USAGE: %s <filename>\n", argv[0]); exit(1); } /* Create Forms API context */ ctx_attr.mask_d2fctxa = (ub4)0; if (d2fctxcr_Create(&ctx, &ctx_attr) != D2FS_SUCCESS) { fprintf(stderr, "Error creating Forms API context\n"); exit(1); } /* Load the form module into memory */ if (d2ffmdld_Load(ctx, &form, argv[1], FALSE) != D2FS_SUCCESS) { fprintf(stderr, "Failed to load form module: %s\n", argv[1]); exit(1); } /* Get the name of the form module */ if (d2ffmdg_name(ctx, form, &form_name) != D2FS_SUCCESS) { fprintf(stderr, "Error getting the name of the form module\n"); } else { /* Print the name of the form, then free it */ printf("The name of the form is %s\n", form_name); free(form_name); } /* Destroy the in-memory form */ if (d2ffmdde_Destroy(ctx, form) != D2FS_SUCCESS) { fprintf(stderr, "Error destroying form module\n"); } /* Close the API and destroy context */ d2fctxde_Destroy(ctx); return 0; } Создал проект в VS2015, добавил в проект хедеры из oracle forms 6i, добавил ему в ресурсы файлик ifd2f60.lib, в корень проекта добавил на всякий случай ifd2f60.dll. Проект собрался без ошибок. Получился exe-шник. Что дальше делать с exe-шником? Как из него получить fmb например? Пробую просто запустить, пишет USAGE ****.exe <filename> Пробую подсунуть ему пустой файл, тоже не нравится *****.exe test.fmb Failed to load form module: test.fmb ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 09:52 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
2 microbash Не в ту степь. Насколько я помню, этот API предназначен для другой цели, а именно - обеспечить доступ к функциональности Forms Builder для обработки всяческих исходников (типа, можно клепать на C эдакие модули скриптовой обработки по своим потребностям). ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 10:27 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
microbashForms 6i Клиент-сервер? 1. Читать ORA_FFI пакет, простейшие примеры можно найти на данном сайте. 2, Таким образом можно было в нее встроить с-клиент, и она имела бы доступ ко всем переменным приложения на формсах. 2.1. К глобальным переменным (GLOBAL) и полям на форме можно получить доступ через USER_EXIT (или ORA_FFI) + PRO/C правильной версии. Для 6i это вроде PRO*C 8.0.5 - 8.0.6. В свое время использовал PRO*C 8.0.3 - тоже работало. PRO*C 8.1.5 или старше - не подойдет. Так же, SQL команды выполняемые через PRO*C работают в той же сессии, что и Forms. Т.ч. можно без проблем работать с БД из C-кода. 2.2. Но, скорее всего, это тебе не нужно. Проще сделать ф-ции получения данных из C-модуля и вызывать их. Нафиг переусложнять C-ную часть? ))) 3. Я твой вопрос понял немного по другому, что тебе нужно выполнять какой-то callback из потока (thread) C программы в поток (thread) Forms. В этом случае, самое простое: создать item на форме (например кнопку) и, когда нужно, посылать ей сообщения Windows (SendMessage, PostMessage например WM_CLICK). HWND получается банально, через GET_ITEM_PROPERTY Если нужно что-то простейшее отрисовывать на форме, то можно создать User Item, получить его HWND, создать child-окно внутри этого HWND и рисовать там. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 10:40 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
4. Forms умеет принимать event от ActiveX контрола. Т.ч. если C-код сделать в виде ActiveX, то тоже должно работать. Но я так не делал, т.к. усложняется deploy приложения. У нас система была тиражируемая и все, что усложняло deploy или support, отправлялось в топку ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 10:48 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
-=APS=-2 microbash Не в ту степь. Насколько я помню, этот API предназначен для другой цели, а именно - обеспечить доступ к функциональности Forms Builder для обработки всяческих исходников (типа, можно клепать на C эдакие модули скриптовой обработки по своим потребностям). Т.е. при генерировании fmb из С-файла генератор уберет весь "лишний" для него код? И всех моих дополнений в конечном как бы fmb уже не будет? Если так, то действительно, тут мимо кассы. Все таки мне было бы интересно тут довести до конца мои тесты. Мало ли понадобится на будущее. Так что жду подсказок что дальше делать с exe-шником. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 12:09 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Так что жду подсказок что дальше делать с exe-шником. А что нужно-то ? Exe'шник вещь хорошая: 1. можно на флешку записатоь 2. можно на CD диск записать 3. можно открыть в FAR'е в hex виде, сделать скриншот, распечатать на принтере, украсить квартиру вместо обоев. можно скомбинировать 2 + 3 и украсить квартиру в техно стиле ))) microbash... Пробую подсунуть ему пустой файл, тоже не нравится *****.exe test.fmb Failed to load form module: test.fmb "Failed to load form module" обозначает, что он не смог загрузить .fmb файл. Или имя файла с ошибкой, или форма битая или каких-то PLL не находит. Возможно просто имя формы нужно без .fmb. Давно работал, уже не помню. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 12:18 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
-> Клиент-сервер? Установлены компоненты 6i oracle forms и reports, обе без серверных компонент. Это? -> 1. Читать ORA_FFI пакет, простейшие примеры можно найти на данном сайте. Да, уже есть и тут подвижки: по примерам собрал простую DLL , из формсов получается вызвать из DLL функцию __declspec(dllexport), в функции __declspec(dllexport) у меня запускается тред с клиентом. Причем тут работать можно двояко: 1) без присоединения к треду. Тут как раз возникает вопрос: как вернуть данные из треда в формсы?? status = pthread_create(&thread_loop, NULL, thread_proc, (void *)pPrimaryDat); //status = pthread_join(thread_loop, (void**)&status_addr); 2) с присоединением к треду. Тут данные возвращаются в формсы, но сами они висят в ступоре, что не есть гуд. status = pthread_create(&thread_loop, NULL, thread_proc, (void *)pPrimaryDat); status = pthread_join(thread_loop, (void**)&status_addr); -> 2.1. К глобальным переменным (GLOBAL) и полям на форме можно получить доступ через USER_EXIT (или ORA_FFI) + PRO/C Любопытно было бы пощупать все эти варианты. -> 2.2. Но, скорее всего, это тебе не нужно. Проще сделать ф-ции получения данных из C-модуля и вызывать их. Нафиг переусложнять C-ную часть? ))) А вызывать по таймеру? Тогда не будет пуша данных в сторону клиента. -> 3. Я твой вопрос понял немного по другому, что тебе нужно выполнять какой-то callback из потока (thread) C программы в поток (thread) Forms. У меня С-клиент получает из сети текстовое сообщение в буфер char []. Вот это сообщение мне нужно отобразить в приложении формсов (например в консоле окна). -> В этом случае, самое простое: создать item на форме (например кнопку) и, когда нужно, посылать ей сообщения Windows (SendMessage, PostMessage например WM_CLICK). HWND получается банально, через GET_ITEM_PROPERTY Если нужно что-то простейшее отрисовывать на форме, то можно создать User Item, получить его HWND, создать child-окно внутри этого HWND и рисовать там. Спасибо, попробую. ) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 12:58 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
-> 2.2. Но, скорее всего, это тебе не нужно. Проще сделать ф-ции получения данных из C-модуля и вызывать их. Нафиг переусложнять C-ную часть? ))) А вызывать по таймеру? Тогда не будет пуша данных в сторону клиента. IMHO Самое простое и наимение глукавое. В C приходящие сообщения записывать в очередь, в Forms'ах в триггере по таймеру их вычитывать. Просто и работоспособно. Легко отлаживать. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 14:53 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsevпропущено... А вызывать по таймеру? Тогда не будет пуша данных в сторону клиента. IMHO Самое простое и наимение глукавое. В C приходящие сообщения записывать в очередь, в Forms'ах в триггере по таймеру их вычитывать. Просто и работоспособно. Легко отлаживать. Мне проще тогда уж их сразу из базы по таймеру выкачивать. Теряется режим реального времени. Итак делаю как выше советовали: 1.Есть кнопка :control.BT 2.На кпопке есть триггер WHEN_BUTTON_PRESSED вида: declare ... ret integer; CurrItem integer; begin CurrItem := get_item_property(':control.BT', WINDOW_HANDLE) ; ret:= Fn_Split2 (tmpvar,CurrItem,0,0); ... end; 3. FUNCTION Fn_Split2 (p_text IN OUT VARCHAR2, p_wid IN BINARY_INTEGER, p_att IN BINARY_INTEGER, p_start IN BINARY_INTEGER) RETURN NUMBER IS l_fn ORA_FFI.FuncHandleType; -- FUNCTION dll_split2(pFh IN ORA_FFI.funcHandleType, str IN OUT VARCHAR2, wid IN BINARY_INTEGER, bld IN BINARY_INTEGER, strt IN BINARY_INTEGER) RETURN pls_integer; -- PRAGMA interface( c, dll_split2, 11265); BEGIN IF p_text IS NULL THEN Return NULL; END IF; -- l_fn := Fn_Load_Function2('splitstr2'); -- ORA_FFI.register_parameter(l_fn,ORA_FFI.C_CHAR_PTR ); ORA_FFI.register_parameter(l_fn,ORA_FFI.C_INT ); ORA_FFI.register_parameter(l_fn,ORA_FFI.C_INT ); ORA_FFI.register_parameter(l_fn,ORA_FFI.C_INT ); ORA_FFI.register_return(l_fn,ORA_FFI.C_INT ); -- Return dll_split2(l_fn,p_text,p_wid,p_att,p_start); END Fn_Split2; 4. FUNCTION Fn_Load_Function2 (p_func_name IN VARCHAR2) RETURN ORA_FFI.FuncHandleType IS l_lib ORA_FFI.LibHandleType; l_func ORA_FFI.FuncHandleType; BEGIN BEGIN l_lib := ORA_FFI.Find_Library('simple2.dll'); EXCEPTION WHEN OTHERS THEN l_lib := ORA_FFI.Load_Library('.\','simple2.dll'); END; -- l_func := ORA_FFI.Register_Function(l_lib,p_func_name,ORA_FFI.C_STD); -- Return l_func; EXCEPTION WHEN OTHERS THEN FOR c IN 1..Tool_Err.NErrors LOOP Message(Tool_Err.Message); Tool_Err.Pop; END LOOP; END Fn_Load_Function2; 5. DLL ... include <windows.h> __declspec(dllexport) int splitstr2(char *str, int len, int bold, int start) { ... SendMessage((HWND)len, WM_SETTEXT, 0, (LPARAM)L"EEEEE"); ... } По нажатию кнопки на формсах, пытаюсь поменять на ней текст. Ан нет :( ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 16:09 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
microbashПо нажатию кнопки на формсах, пытаюсь поменять на ней текст. Ан нет :( Ну кнопка и не обязана уметь свой текст менять. Text Item на WM_SETTEXT / EM_REPLACESEL точно работает AFAIK. В любом случае, Forms'ов под рукой нет, я такое лет 10-15 назад делал ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 16:35 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Косяк похоже с определением указателя: CurrItem := get_item_property(':control.BT', WINDOW_HANDLE) ; Использую spy tool в VS2015 для просмотра всех окон в ОС и их указателей. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 20:12 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
microbashКосяк похоже с определением указателя: CurrItem := get_item_property(':control.BT', WINDOW_HANDLE) ; Использую spy tool в VS2015 для просмотра всех окон в ОС и их указателей. У меня в свое время работало. И в User Item'е свои окна создавал и в Text Item'е навигацией курсора управлял. Проблем на однострочных блоках не было (с многострочными блоками, разумеется, могут быть проблемы) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 20:17 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Сделал пока так (определение хендлера в самой DLL по названию объекта): HWND WindowHandle = FindWindow(NULL, L"Oracle Forms Runtime"); SendMessage(WindowHandle, WM_SETTEXT, 0, (LPARAM)L"DATAFROMDLL"); Работает! ) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.05.2016, 21:33 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
Leonid KudryavtsevmicrobashКосяк похоже с определением указателя: CurrItem := get_item_property(':control.BT', WINDOW_HANDLE) ; Использую spy tool в VS2015 для просмотра всех окон в ОС и их указателей. У меня в свое время работало. И в User Item'е свои окна создавал и в Text Item'е навигацией курсора управлял. Так вы работали с хендлами только внутри самих формсов? Или снаружи тоже по ним же работали? На каком то буржуйском форуме прочитал замечание, что хендлы объектов формсов не соответствуют хендлам ОС. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2016, 14:52 |
|
forms + c-client
|
|||
---|---|---|---|
#18+
microbashТак вы работали с хендлами только внутри самих формсов? Или снаружи тоже по ним же работали? На каком то буржуйском форуме прочитал замечание, что хендлы объектов формсов не соответствуют хендлам ОС. Фраза "изнутри/снаруже" мне не очень понятна. Скажем так: на C. SendMessage, PostMessage нормально работали. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2016, 16:38 |
|
|
start [/forum/topic.php?fid=51&msg=39236923&tid=1878010]: |
0ms |
get settings: |
12ms |
get forum list: |
5ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
69ms |
get topic data: |
2ms |
get forum data: |
0ms |
get page messages: |
316ms |
get tp. blocked users: |
0ms |
others: | 354ms |
total: | 760ms |
0 / 0 |