Форум » GUI » Как передать данные из одной программы в другую ? » Ответить

Как передать данные из одной программы в другую ?

Andrey: Всем привет... Есть ли механизм передачи данных между программами ? Допустим прога на МиниГуи запустила терминалку. Как узнать что терминалка нормально запустилась ?

Ответов - 59, стр: 1 2 3 All

PSP: Механизм mutex-ов

Andrey: А пример можно для Харбора как это будет работать ? А то по описанию трудно понять как это делать... Когда с этим работаешь, то понятно... а когда не знаешь как использовать, то труба !

Andrey: Нашел на Дельфи: Дело в том, что можно в памяти создавать временные файлы. При перезагрузке они теряются, а так существуют. Кстати, этот метод можно использовать и для обмена информацией между вашими приложениями. Пример с использованием FileMapping: program Project1; uses Windows, // Обязательно Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} const MemFileSize = 1024; MemFileName = 'one_inst_demo_memfile'; var MemHnd : HWND; begin // Попытаемся создать файл в памяти MemHnd := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READWRITE, 0, MemFileSize, MemFileName); // Если файл не существовал запускаем приложение if GetLastError<>ERROR_ALREADY_EXISTS then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; CloseHandle(MemHnd); end. А как бы сделать похожее на МиниГуи ?


vvv: А если просто создавать временный файл на диске?

Andrey: vvv пишет: А если просто создавать временный файл на диске? Ну это будет слишком просто и непонятно.... Прога на МиниГуи (вывесила заставку ЗАПУСКАЮ....), далее запустила терминалку на хХарборе, терминалка на хХарборе создала временный файл "все'Ok". Далее прога на МиниГуи у себя отметила что прога на хХарборе запустилась нормально, убрала заставку ЗАПУСКА (как сделать пока не представляю)... Потом нужно рассматривать варианты, если программа не запустилась по каким то причинам... кто будет убирать заставку и когда ? И т.д.

santy: Есть интересный пример : http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx

Andrey: santy пишет: Есть интересный пример Спасибо. Только в С я не силен. Как бы на Харборе сделать ?

SergKis: Andrey пишет: Прога на МиниГуи (вывесила заставку ЗАПУСКАЮ....), далее запустила терминалку на хХарборе, терминалка на хХарборе создала временный файл "все'Ok". Далее прога на МиниГуи у себя отметила что прога на хХарборе запустилась нормально, убрала заставку ЗАПУСКА (как сделать пока не представляю)... Потом нужно рассматривать варианты, если программа не запустилась по каким то причинам... кто будет убирать заставку и когда ? И т.д. Вот примерный ответ (не C и hb) на AutoIt3: [pre2] ; Запуск AutoIt3.exe <ScriptName.au3> ; В AutoIt3 есть возможность собирать из скрипта Exe, включая в него файлы, ; как при инсталяции. ; http://autoit-script.ru/ #NoTrayIcon $jpg = ".\images\darkside.jpg" ; Создать всплывающее окно с изображением. по умолчанию в центре экрана ; SplashImageOn("title", "file" [, width] [, height] [, x pos] [, y pos] [, opt]) ; file - Полный путь к файлу с изображением (BMP, GIF или JPG). SplashImageOn("Splash Screen", $jpg, 150, 150) ; Инициализировать набор пользовательских реквизитов для выполнения ; Run и RunWait операций. Только для 2000/XP и позже. ; If RunAsSet("Administrator", @Computername, "adminpassword") Then ; Run("MyProg.exe MyParam", "WorkingDir") ; снять набор пользовательских реквизитов ; RunAsSet() ; EndIf Run("MyProg.exe MyParam", "WorkingDir") ; Прервать выполнение скрипта до момента появления указанного окна. ; WinWait ( "title", ["text"], [timeout] ) ; или ; Прервать выполнение скрипта до момента активизации указанного окна. ; timeout в секундах ; WinWaitActive ( "title", ["text"], [timeout] ) If WinWaitActive( "MyProgramTitle", "", 30 ) Then MsgBox(1, "Info", "MyProgram started", 10) ; timeout 10 сек. Else MsgBox(1, "Info", "Failed started", 10) ; timeout 10 сек. ; Принудительно закрыть окно. ; WinKill ( "title", ["text"] ) ; или ; Остановить выполнение указанного процесса. ; ProcessClose ( "process" [, flag] ) ; Названия процессов могут быть, например, "notepad.exe", "winword.exe". EndIf ; Закрыть окна, открытые с помощью SplashTextOn или SplashImageOn. SplashOff() [/pre2]

vvv: Андрей, а какой командой запускаешь терминалку?

Andrey: vvv пишет: Андрей, а какой командой запускаешь терминалку? ShellExecute(, 'open',cPathExe+cRunExe, cParam, "" , SW_SHOWNORMAL)

Andrey: Возвращаюсь опять к этому вопросу. Уже много времени прошло. В прошлом году для обмена между МиниГуи и терминалкой сделал (с помощью форумчан) пример: MiniGUI\SAMPLES\BASIC\COMM_2 Вроде отлично работал, пока пути без русских букв. Реализовал передачу данных всё таки через базу по таймеру. Сейчас хочу переделать. Нужно передавать данные между двумя программами (своими) на одном компе. Можно ли использовать стандартный SendMessage() ? Основная программа (сервер) на МиниГуи, клиент терминалка. В клиенте правятся записи базы, после редактирования SendMessage() и эти номера записей принимает сервер. Какова вероятность потери при передачи с SendMessage() ? И ещё при взаимодействии с другими программами (допустим на С#) сколько можно передать данных ? Т.е. какой максимальный размер данных при передачи через SendMessage() ?

SergKis: Andrey пишет Сейчас хочу переделать. С терминалкой, не очень будет, с wvt можно через WM_COPYDATA Проще сделать через переменную(е) Enviroment (вроде до 4К), т.е. hb_SetEnv(..., ...) hb_GetEnv(...)

Andrey: SergKis пишет: С терминалкой, не очень будет, с wvt можно через WM_COPYDATA У меня терминалка с wvt. Тест с C# идёт, c терминалкой нет. P.S. Нашел вот тут нужную тему: Передача сообщений между приложениями/процессами при помощи сообщения WM_COPYDATA http://www.frolov-lib.ru/books/bsp/v27/ch2_2.htm Минигуи сделал, работает. А терминалку нет. Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() ? Саму функцию взял из МиниГуи - [pre2]#pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #ifndef __XHARBOUR__ #define ISBYREF( n ) HB_ISBYREF( n ) #endif HB_FUNC( SENDCOPYDATAMSG ) { HWND hwnd; COPYDATASTRUCT cds; hwnd = (HWND) hb_parnl( 1 ); cds.dwData = 0xCE98; cds.lpData = (char *) hb_parc( 2 ); cds.cbData = strlen( (char*) cds.lpData ); SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM) &cds ); } #pragma ENDDUMP [/pre2]

SergKis: Andrey пишет Как в терминалке прикрутить передачу 1. Надо залезть в исходники, добавить обработку WM_COPYDATA, прочитать получ. данные, сохранив в буф. и послать какой то KeyBoadrd 2. Иметь процедуру, которая сможет получить данные из буф. ( HB_FUNC ) 3. Сделать SET KEY на KeyBoard процедуры из 2., которая примет полученные данные как то так

Петр: Andrey пишет: Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() ? SergKis пишет: 1. Надо залезть в исходники Или я не вижу всех сообщений, или вы издеваетесь друг над другом..

SergKis: Петр И в чем протеворечие ? Andrey про МиниГуишный вариант, я про wvt-ый (принять по WM_COPYDATA). Возможно у Вас есть решение, но это уже др. история\предложение.

Петр: SergKis пишет: И в чем протеворечие ? Нет противоречий, но.. Andrey пишет: Как в терминалке прикрутить передачу - функцию SendCopyDataMsg() похоже на тонкий троллинг публики. А с вашей стороны рекомендации по организации прийома с использованием какого-то KeyBoadrd, наводят меня на мысль, что я что-то пропустил или не понял. Процесс организации прийома описан правильно, ну чуть усложнили.. Но последний вопрос был про передачу! А рекомендации на эту тему Андрею я давал. Что-то вроде используйте то, что знаете и умеете. Стандартов нет - варианты есть, тем более если все размещено локально. И еще, если Андрей написал сервер, то обычно сервер работает по какому-то протоколу - пускай его и использует для взаимодействия. Я уже не говорю, что "времени прошло много" и с терминалки можно было спрыгнуть. Но это лень, мне знакомо это святое чувство

Andrey: Петр пишет: Я уже не говорю, что "времени прошло много" и с терминалки можно было спрыгнуть. Но это лень, мне знакомо это святое чувство Ага. С удовольствием бы спрыгнул. Третий год АКТИВНО переделываю проект. Бровсом только год занимаюсь. Без поддержки с форума не смог бы столько сделать. БОЛЬШОЕ ВАМ ВСЕМ СПАСИБО, кто помогал мне ! Конец работы уже виден, но столько ещё делать.... А юзера новую прогу и не жалуют. Перевести на новую программу одна морока. Как привыкли работать, так и всё. Юзера не любят осваивать новое. Не знаю что с ними делать... Разобрался я с Передачей сообщений между приложениями. В качестве обучающего примера выслал Григорию для включения в библиотеку. Передача строки идёт на ура ! И даже ехе-ник в 700Мб передаю и получаю !!! Всё глотает. Пробовал через C# передать строку в 50Мб - проходит, т.е. Минигуи такую строку тоже принимает. Но сборщик МУСОРА в С# хуже чем в Харборе (это не моё мнение). Теперь можно реализовать по событию контроль за изменением записей в базе между двумя программами и обходиться без таймера.

SergKis: Петр пишет похоже на тонкий троллинг публики Это не троллинг, что в данный момент Андрею надо, то он и говорит прямо, честно и откровенно. Правда, потом оказывается, надо еще воз и тележку и не маленькую ..., потому я сразу про wvt прием и говорил. Процесс организации прийома описан правильно, ну чуть усложнили.. В чем ? Сейчас это уже не использую (в hb 2.0 было), но интересно, если проще можно.

Петр: SergKis пишет: В чем ? Сейчас это уже не использую (в hb 2.0 было), но интересно, если проще можно. По пунктам 1. Надо залезть в исходники, добавить обработку WM_COPYDATA, прочитать получ. данные, сохранив в буф. и послать какой то KeyBoadrd Не обязательно. Нужно заменить стандартный обработчик окна. Это можно делать и что назывется "на лету". KeyBoard зачем трогать? 2. Иметь процедуру, которая сможет получить данные из буф. ( HB_FUNC ) Все зависит от пункта №1. Все действие можно перевести и на PRG уровень. 3. Сделать SET KEY на KeyBoard процедуры из 2., которая примет полученные данные как то так Опять же вы использовали существующий механизм, а без этого можно обойтись. На PRG уровне вы создаете публичную переменную (масив строк, хаш) и по событию WM_COPYDATA ваш обработчик добавляет в переменную элементы. Вам остается контролировать состояние переменной (используя таймер, потоки, возможности hb_idle * - то, что у вас лучше всего получается) и вовремя удалять отработанные данные. В качестве переменной может быть экземпляр какого-то класса с методами и свойствами. Я надеюсь, что Андрей организовал хоть какую-то проверку целосности данных. Если бы речь о 2-х MiniGUI программах, то там вообще "рай": мультипоточность (в разумных пределах, MiniGUI не thread safe), сериализация/десериализация переменных простых типов, выбор методов проверки контрольных сум. Я надеюсь, что пример Андрея будет именно таким

SergKis: Петр пишет Нужно заменить стандартный обработчик окна. Это можно делать и что назывется "на лету" Не видел такую возможность в hb 3.2. Это как можно сделать ? С idle и прочим все понятно (если можно на уровне prg подсунуть свой обработчик для WM_COYDATA)

Петр: SergKis пишет: Не видел такую возможность в hb 3.2. Это как можно сделать ? С idle и прочим все понятно (если можно на уровне prg подсунуть свой обработчик для WM_COYDATA) Я не писал, что это возможность hb 3.2. Я писал, что есть такая возможность (средствами winapi, например, SetWindowLongPtr). SergKis пишет: если можно на уровне prg подсунуть свой обработчик для WM_COYDATA Ну эта возможность не на пустом месте возникла. Когда-то мне надоело по "бескрайним просторам" стандартного обработчика MiniGUI ездить и появилась SET EVENTS FUNCTION TO MYEVENTS Сейчас я бы делал уже как-то так SET GLOBAL LISTENER TO MYEVENTS SET LISTENER TO Form_1_Listener() OF Form_1 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY

SergKis: Петр пишет Я не писал, что это возможность hb 3.2. Я писал, что есть такая возможность (средствами winapi, например, SetWindowLongPtr Жаль, что в hb нет "нормального" подкл. своего обработчика, а winapi установит новый, я понимаю все из старого надо повторять. Или можно старый вызывать тоже, хотя не важно, пока не потребутся и ... Спасибо за разъяснения Ну эта возможность не на пустом месте возникла. Когда-то мне надоело по "бескрайним просторам" стандартного обработчика MiniGUI ездить и появилась SET EVENTS FUNCTION TO MYEVENTS В Events(...) давно была фишка своего обработчика [pre2] #ifdef _USERINIT_ FOR EACH cProc IN _HMG_aCustomEventProcedure r := &cProc ( hWnd , nMsg , wParam , lParam ) IF ValType ( r ) <> 'U' RETURN r ENDIF NEXT #endif [/pre2] не так цивилизованно, как сейчас, но ...

Петр: SergKis пишет: В Events(...) давно была фишка своего обработчика Это немного другое. 2008/02/01: Build 48 (HMG 1.4 Extended Edition) Published. .. * Updated: Synchronized an Extended HMG with an Official HMG 2.0.010: - New: HMG User Components Support. I've created a standard interface to allow HMG users to create its own components (ie: new controls) without need to modify HMG library itself. HMG User Components Reference: - InstallEventHandler ( <cEventHandlerFunctionName> ) 2007/02/15: Build 31 (HMG 1.3 Extended) Published. * New: SET EVENTS FUNCTION TO <funcname> command. Contributed by Petr Chornyj <myorg63@mail.ru> (see demo in folder \samples\Advanced\RunCmd) Сама функция Events и есть обработчик. Если ваш собственный не отработал сообщение то может вызвать Events, иначе рискуете получить глюки, как Андрей. Но есть нюансы. Harbour мультиплатформенный и это нужно помнить. К тому же он open source, и то, что интересно вам или мне, может быть не интересно другому

SergKis: Петр пишет Это немного другое Возможно, но использовать это как свой с вызовом, если надо Events(), можно было. Это не так красиво как сейчас, но исп. можно было где то. То что неправильно использовать можно, так это уже др. песня. Но я не пользовал, привычнее лазить по "бескрайним просторам" ... хотя восторга от этого не имею. Harbour мультиплатформенный и это нужно помнить. К тому же он open source, и то, что интересно вам или мне, может быть не интересно другому Как правило (я про себя) заканчивается своей версией либы.

Andrey: Петр пишет: Я надеюсь, что Андрей организовал хоть какую-то проверку целосности данных. Нет. Не знаю как.... Вот пример, посмотри - https://cloud.mail.ru/public/7gRW/zW5JDS68H Я думаю, что Передача сообщений между приложениями/процессами будет многим интересна. Тем более, что кода мало.

SergKis: Петр пишет Сейчас я бы делал уже как-то так SET GLOBAL LISTENER TO MYEVENTS SET LISTENER TO Form_1_Listener() OF Form_1 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY Может в таком виде "ширее" будет[pre2] SET GLOBAL LISTENER ADD LISTENER TO Form_1 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY ACTION {|hW,nM,wP,lP| MY1(hW,nM,wP,lP) } ADD LISTENER TO Form_5 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY ACTION {|hW,nM,wP,lP| MY2(hW,nM,wP,lP) } ADD LISTENER TO Form_7 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY ACTION {|hW,nM,wP,lP| MY3(hW,nM,wP,lP) } ... [/pre2] EVENTS могут быть разными. И эта штука может не пересекаться с SET EVENTS FUNCTION TO MYEVENTS т.е. может присутсвовать и то и то

Петр: Andrey пишет: Тем более, что кода мало. Кода мало - ошибок много.

Петр: SergKis пишет: SET GLOBAL LISTENER в моем понимании эта команда отключает глобальный обработчик ADD LISTENER TO Form_1 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY ACTION {|hW,nM,wP,lP| MY1(hW,nM,wP,lP) } - эта команда создает обработчик для окна Form_1, в случае если приходят события WM_CREATE, WM_COPYDATA, WM_DESTROY их обработка передается блоку в существующей модели HMG это реализуется примерно вот так [pre2]SET EVENTS FUNCTION TO my_EventsHandler FUNCTION my_EventsHandler ( hWnd, nMsg, wParam, lParam ) LOCAL nResult IF hWnd == GetFormHandle( "Form_1" ) IF nMsg == WM_CREATE .OR. nMsg == WM_COPYDATA .OR. nMsg == WM_DESTROY nResult := Eval( {|hW,nM,wP,lP| MY1(hW,nM,wP,lP), hWnd, nMsg, wParam, lParam ) IF nResult != 0 RETURN nResult ELSE RETURN Events( hWnd, nMsg, wParam, lParam ) ENDIF ENDIF ENDIF RETURN Events( hWnd, nMsg, wParam, lParam )[/pre2] Я правильно понял? Андрей, обратите внимание на мою реализацию и на обработку событий в вашем примере, кое-что там совешенно лишнее.

SergKis: Петр пишет в моем понимании эта команда отключает глобальный обработчик Тут мы немного разошлись в понимании, я считал, что даем команду "будем исп. глобальный список обработчиков", т.е. создаем массив\hash для списков. ADD ... добавляет в список окна , обозначенные события и свой обработчик этих событий. Причем самих окон еще может не быть. т.е., к примеру (чисто условно) [pre2] a_Listener := hb_Hash() hb_HSet(a_Listener, "Form_1", {{WM_CREATE, WM_COPYDATA, WM_DESTROY}, bAction}) hb_HSet(a_Listener, "Form_5", {{WM_CREATE, WM_COPYDATA, WM_DESTROY}, bAction}) ... в обработчике примерно так cForm := _HMG_aFormNames[ ascan(_HMG_aFormHandles, hWnd) ] aEvnt := hb_HGetDef(a_Listener, cForm, {}) If empty(aEvnt) RETURN Events( hWnd, nMsg, wParam, lParam ) EndIf a := aEvnt[1] If ( i := ascan(a, {|msg| msg == nMsg }) ) > 0 If hb_IsBlock(aEvnt[2]) nResult := Eval(aEvnt[2], hWnd, nMsg, wParam, lParam) IF nResult != 0 RETURN nResult ENDIF EndIf EndIf RETURN Events( hWnd, nMsg, wParam, lParam ) [/pre2]

Петр: Понятно, значит у вас "ужее" Если у нас, будет вот так hb_HSet(a_Listener, "Form_1", {{WM_CREATE, WM_COPYDATA, WM_DESTROY}, bAction}) hb_HSet(a_Listener, "Form_1", {{WM_PAINT}, bAction}) hb_HSet(a_Listener, "Form_1", {{WM_CREATE}, bAction}) что нужно будет выполнять и что возвращать (а возвращать придется ). К сведению, в существующей реализации (не знаю кто-то пользуется или нет - примеров нет ) легко можно делать такие вещи как, например, OnBeforeInit, OnAfterInit (что-то подобное было в FoxPro: событие перед событием - само событие - событие после события :) ).

SergKis: Петр пишет Если у нас, будет вот так hb_HSet(a_Listener, "Form_1", {{WM_CREATE, WM_COPYDATA, WM_DESTROY}, bAction}) hb_HSet(a_Listener, "Form_1", {{WM_PAINT}, bAction}) hb_HSet(a_Listener, "Form_1", {{WM_CREATE}, bAction}) Будет последний в hash hb_HSet(a_Listener, "Form_1", {{WM_CREATE}, bAction}) Потому и писал hash, чтобы один обработчик на форму, а вернет aEvnt := hb_HGetDef(a_Listener, "Form_1", {}) или {{WM_CREATE}, bAction}, если найдет, или {}, если нет К сведению, в существующей реализации (не знаю кто-то пользуется или нет - примеров нет ) легко можно делать такие вещи как, например, OnBeforeInit, OnAfterInit (что-то подобное было в FoxPro: событие перед событием - само событие - событие после события :) ) НО ПРИМЕРОВ НЕТ ! ГДЕ СМОТРЕТЬ ?

Петр: SergKis пишет: НО ПРИМЕРОВ НЕТ ! ГДЕ СМОТРЕТЬ ? Вопрос не ко мне. Хотя примеров в MiniGUI много, что иногда раздражает, не сразу и понятно, что автор хотел показать, много дубляжей ради одной какой-то функции в середине примера, в том же HMG off. лучшая структуированость примеров. SergKis пишет: Будет последний в hash hb_HSet(a_Listener, "Form_1", {{WM_CREATE}, bAction}) Понятно, например в nodejs, если я не ошибаюсь там, идет поочередный вызов всех обработчиков. Где-то, забыл где , обработчик в случае дублирования не устанавливается. Нужна установка с доп. параметром: типа так и так, все понимаю, все равно хочу Остался один вопрос - кому это нужно, реализация несложная (если не формировать внутреннюю очередь событий конечно).

SergKis: Петр пишет Остался один вопрос - кому это нужно, реализация несложная Мы начали Сейчас я бы делал уже как-то так SET GLOBAL LISTENER TO MYEVENTS SET LISTENER TO Form_1_Listener() OF Form_1 EVENTS WM_CREATE, WM_COPYDATA, WM_DESTROY т.е. с централизованных команд в hmg, подискутировали на эту тему и пришли к выводу, что SET EVENTS FUNCTION TO MYEVENTS достаточно для всех хотелок

Andrey: Петр пишет: Андрей, обратите внимание на мою реализацию и на обработку событий в вашем примере, кое-что там совешенно лишнее. Не, для меня это пока слишком сложно, да и другим новичкам тоже. Хотя я уже года 3 как активно перевожу программу. Именно перевожу, разбираться как это работает очень сложно. Как всегда недостаток времени. Петр пишет: Я надеюсь, что Андрей организовал хоть какую-то проверку целосности данных. Как это сделать ? К вам большая просьба (я думаю и другие новички присоединятся) подправить правильно, то что я наваял ! Заранее спасибо за помощь ! Пример потом отправьте Григорию для включения в библиотеку. Пусть все пользуются.

Петр: Andrey пишет: Не, для меня это пока слишком сложно Это проще паренной репы - если вы обработали сообщение в пользовательсом обработчике - верните значение отличное от 0 (например - 1), если нет, но подозреваете, что это сообщение нужно все таки отработать - вызовите стандартный HMG обработчик Events (припоминаете, что без этого у вас Labels перестали правильно отображаться?). У вас же обработка фактически состоялась и вы просто теряете время вызывая опять Events (Events о WM_COPYDATA ничего не знает). Andrey пишет: К вам большая просьба (я думаю и другие новички присоединятся) подправить правильно, то что я наваял ! Да не вопрос. ссылка на архив Проверка, конечно элементарная, но есть. Если Григорий захочет - пусть пример публикует, в принципе он же ваш. Только не нужно его COMM - называть (у меня, почему-то ассоциация с COM портом, хотя понимаю, что это communication), лучше IPC (Inter-process communication).

Петр: SergKis пишет: SET EVENTS FUNCTION TO MYEVENTS достаточно для всех хотелок Может быть, "но не все умеют их готовить"

SergKis: Петр пишет "но не все умеют их готовить" Добавка команд в hmg, вряд ли научит "готовить", а код в hmg (не много) но добавиться.

Петр: SergKis пишет: а код в hmg (не много) но добавиться. Это хорошо или плохо?

SergKis: Петр пишет Это хорошо или плохо? Это (как всегда) с какой стороны смотреть ? Все относительно. Григорий постоянно оптимизирует либу, борется с лишними включениями. Замусорить легко, вычищать сложно. По нашей теме, на сегодня, новые команды\код, скорее излишества, как завтра будет ... посмотрим. Но это мое мнение.

Andrey: Петр пишет: Только не нужно его COMM - называть (у меня, почему-то ассоциация с COM портом, хотя понимаю, что это communication), лучше IPC (Inter-process communication). Да так Григорий назвал, не я. Спасибо !

Петр: SergKis пишет: Григорий постоянно оптимизирует либу, борется с лишними включениями. Замусорить легко, вычищать сложно. Ок. Я знаю позицию Григория. Лишнее или не лишнее - вопрос дискуссий.

Andrey: Вопрос дилетанта по окнам: SET EVENTS FUNCTION TO MYEVENTS можно назначать любому окну в программе ? И соответсвенно WM_COPYDATA будет обрабатываться в этом окне ? А то не хочу (неудобно) делать приёмку MAIN окном.

Петр: Andrey пишет: SET EVENTS FUNCTION TO MYEVENTS можно назначать любому окну в программе ? Нет Каждое окно в MiniGUI создается с оконной процедурой WndProc. При запуске WndProc проверяет глобальную переменную sEVENTSFUNC. Если эта переменная содержит имя Harbour функции, WndProc запускает ее на исполнение с параметрами HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam; если нет - выполняется обработчик по умолчанию - функция Events. Если Events или ваша функция-обработчик в качестве результата вернут 0, WndProc вызовет обработчик по умолчанию для Windows -DefWindowProc (что бы программа не зависла - выполнялись какие-то елементарные стандартные действия.) Поэтому думайте, что возвращать. Команда SET EVENTS FUNCTION TO MYEVENTS как раз помещает имя функции MYEVENTS в глобальную переменную и больше ничего.

Петр: Andrey пишет: А то не хочу (неудобно) делать приёмку MAIN окном. Это что прикол такой?

Andrey: Петр пишет: Это что прикол такой? Да не прикол. Хочу в другом окне WINDOWTYPE STANDARD принимать/обрабатывать WM_COPYDATA из терминалки. Из-за этого и спрашиваю, возможно ли обрабатывать событие из терминалки по этому окну ? Если нельзя, то нельзя. Будет тогда обрабатывать MAIN окно.

Петр: Andrey пишет: Хочу в другом окне WINDOWTYPE STANDARD принимать/обрабатывать WM_COPYDATA из терминалки. WM_COPYDATA передает данные от одного приложения к другому, тип окон при этом значения не имеет. В догонку: при этом принимающее окно не обязательно дожно быть видимым (Hide). Вы можете обрабатывать эти сообщения в MYEVENTS, но тем не менее SET EVENTS FUNCTION TO MYEVENTS делает то, что делает.

Andrey: Петр пишет: WM_COPYDATA передает данные от одного приложения к другому Чуток не понятно.... hWnd := FindWindow( cAppTitleServer ) Мы же передаём не приложению, а по хендлу окна // Transfer data to window "Server" SendMessageData( hwnd, cVal, nID ) т.е. я могу отправлять сообщение не приложению, а по хендлу любому окну приложения. Правильно или нет ?

SergKis: Andrey пишет Хочу в другом окне Так делай, обработчик в твоих руках, команды\ф-ии минигуи ты знаешь. Так, к примеру If _IsWindowDefined('Form_10') Form_10.Buf.Cargo := <данные wm_copydata> Postmessage(Form_10.Handle, WM_KEYDOWN, VK_F20, 0) EnfIf на окне у тебя @ 0,0 LABEL Buf ... This.Buf.Cargo := '' _DefineHotKey ( ThisWindow.Name, 0 , VK_F20 , {|| MyCopyData()} ) и Func MyCopyData() If ! empty(This.Buf.Cargo) ... прием This.Buf.Cargo := '' EndIf Return Nil или что то др. придумай

Петр: Еще раз уточните про неудобно обрабатывать в главном окне. Мне этот момент не понятен. Andrey пишет: т.е. я могу отправлять сообщение не приложению, а по хендлу любому окну приложения. Правильно или нет ? Вы отправляете сообщение окну другого приложения, любому окну другого приложения, которое захочет с вами общаться. Использовать WM_COPYDATA для передачи данных между окнами одного сообщения потерпит неудачу, система сочтет такое поведение странным и просто ничего не будет посылать. hWnd := FindWindow( cAppTitleServer ) - вместо cAppTitleServer - можете ставить, что угодно, лишь бы нашли.

Andrey: Петр пишет: Еще раз уточните про неудобно обрабатывать в главном окне. Мне этот момент не понятен. У меня отдельное окно для отображения кол-ва отправленных записей на сервер ЛетоДБ по таймеру и это же окно занимается отправкой записей на сервер. Зачем мне делать обработку события в MAIN окне, если логичней делать это в окне отправки. SergKis пишет: Так делай, обработчик в твоих руках, команды\ф-ии минигуи ты знаешь. Понял. Спасибо ! Спасибо всем за разъяснения.

Andrey: Ещё вопрос возник. А зачем нужен 3-параметр при передачи ? // Transfer data to window "Server" SendMessageData( hwnd, cVal, nID ) Я так понял что для проверки получения: IF nDataID == APP_ID // it's our data? А какие варианты кроме 777 можно использовать ? #define APP_ID 777

Петр: Вы, что пытаетесь у всех распросить, что вы там в примере написали? Andrey пишет: Я так понял что для проверки получения: Для идентификации принятых данных: если у вас на компе нет больше установленных программ или вы тщательно отследили их поведение: можете игнорировать (как вы и делали сначала). Кроме 777 - любое число от 0 до 4294967295.

Петр: Andrey пишет: Зачем мне делать обработку события в MAIN окне, если логичней делать это в окне отправки. Еще раз - обработку события вы делаете в функции обработчике, не зависимо от того, как вы представляете работу minigui. Из функции обработчика вам доступно управление видом всех окон вашей программы. Так, что поменять какой-нибудь label вы можете сразу во всех окнах. Главное. что бы вы не перехватывали ненужных вам событий. И если ID не 777 ( или любое другое число от 0 до 4294967295) не забирайте чужих данных, наоборот если это ваши данные возвратите 1, Windows поймет, что доставка состоялась. Кстати, надеюсь вы заметили, что клиент и сервер должны знать ID друг друга. И еще не факт, что чужими данными ваша программа не подавиться, неправильно их интерпретировав и обработав.

Andrey: Спасибо за разъяснения. Порой мои вопросы бывают и тупыми, но хочется понять как и что работает.

Andrey: Можно ли программе запущенной на сервере передать данные с клиентской программы напрямую ? Т.е. без всяких файлов и т.д. - как уже сделали вместе в предыдущем случае !

PSP: Andrey пишет: Можно ли программе запущенной на сервере передать данные с клиентской программы напрямую ? Т.е. без всяких файлов и т.д. - как уже сделали вместе в предыдущем случае ! Они на разных компьютерах?

Dima: Andrey HbNetIO пробовал ? PS А вообще не совсем понятна задача...

Andrey: Dima пишет: А вообще не совсем понятна задача... Входящие и Исходящие документы. Задача информер на клиенте, показывает по таймеру кол-во просроченных/не выполненных/выполненных документов (записей) или при запросе список этих записей. На сервере стоит задача сервер (просчитывает по оператору его записи), при запросе клиентом предает ему общее кол-во или список записей для этого оператора. P.S. Нашёл - MiniGUI\SAMPLES\Advanced\NETIO_2. То что надо !



полная версия страницы