Форум » GUI » APPEVENT в MiniGUI » Ответить

APPEVENT в MiniGUI

Петр: Предлагаю к включению в MiniGUI "нового" механизма обработки сообщений APPEVENT APPEVENT использует для работы сообщения из диапазона WM_APP..0xBFFF (WM_APP) Пример, м.б. не самый удачный [more][quote][pre2] /* * Harbour MiniGUI Accelerators Demo * (c) 2017 P.Ch. */ #include "minigui.ch" #include "i_appevents.ch" ////////////////////////////////////////////////////////////////////////////// #define WM_APP 0x8000 #define ev_Fire1 (WM_APP + 1) #define ev_Fire2 (WM_APP + 2) #define ev_Fire3 (WM_APP + 3) #define ev_FireOnce (WM_APP + 10) ////////////////////////////////////////////////////////////////////////////// FUNCTION Main() LOCAL lResult LOCAL bEvent1 := {|h,m| HB_SYMBOL_UNUSED(h), MsgInfo('ID:'+hb_NtoS(m), 'Event fired:[1]')} LOCAL bEvent2 := {|h,m| HB_SYMBOL_UNUSED(h), MsgInfo('ID:'+hb_NtoS(m), 'Event fired:[2]')} LOCAL bEvent3 := {|h,m| HB_SYMBOL_UNUSED(h), MsgInfo('ID:'+hb_NtoS(m), 'Event fired:[3]')} LOCAL bEvent4 := {|h,m| HB_SYMBOL_UNUSED(h), MsgInfo('ID:'+hb_NtoS(m), 'Event fired:[4]')} LOCAL bEvent0 := {|h,m| HB_SYMBOL_UNUSED(h), MsgInfo('ID:'+hb_NtoS(m), 'Event fired:[0]')} DEFINE WINDOW WinMain ; CLIENTAREA 600, 400 ; TITLE 'AppEvents Demo' ; MAIN ON APPEVENT ev_Fire1 ACTION bEvent1 OF ThisWindow.Handle ON APPEVENT ev_Fire2 ACTION bEvent2 OF ThisWindow.Handle ON APPEVENT ev_Fire3 ACTION bEvent3 OF ThisWindow.Handle UPDATE APPEVENT ev_Fire3 OF ThisWindow.Handle NOACTIVE UPDATE APPEVENT ev_Fire3 ACTION bEvent4 OF ThisWindow.Handle ON APPEVENT ev_FireOnce ACTION bEvent0 OF ThisWindow.Handle ONCE // REMOVE APPEVENT ALL OF ThisWindow.Handle ONCE DEFINE BUTTONEX FireButton1 ROW 290 COL 50 CAPTION "Fire 1" ACTION EMIT ev_Fire1 OF WinMain.Handle WIDTH 140 HEIGHT 40 END BUTTONEX DEFINE BUTTONEX FireButton2 ROW 340 COL 50 CAPTION "Fire 2" ACTION EMIT ev_Fire2 OF WinMain.Handle WIDTH 140 HEIGHT 40 END BUTTONEX DEFINE BUTTONEX FireButton3 ROW 290 COL 200 CAPTION "Fire 3" ACTION EMIT ev_Fire3 OF WinMain.Handle WIDTH 140 HEIGHT 40 END BUTTONEX DEFINE BUTTONEX FireButton4 ROW 340 COL 200 CAPTION "Fire Once" ACTION EMIT ev_FireOnce OF WinMain.Handle WIDTH 140 HEIGHT 40 END BUTTONEX END WINDOW WinMain.Center WinMain.Activate RETURN 0 [/pre2][/quote][/more] Работа над реализацией механизма APPEVENT в основном закончена Удачи в тестировании. Если кто-то сочтет APPEVENT небесполезной игрушкой - просите Григория о включении в состав MiniGUI, если нет, то нет

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

Петр: Для работы APPEVENT нужно внести изменения в исходники библиотеки ( в основном c_windowc.c) Архив с примером и библиотекой версии 17.05. с внесенными изменениями можно скачать отсюда В прилагаемую библиотеку внесены и другие изменения: В MDI окнах переименованы свойства PROP_CFILE => HMG_CFILE PROP_FORMNAME => HMG_FORMNAME PROP_MODIFIED => HMG_MODIFIED Все свойства окна (в т.ч. MDI) с именами начинающимися с "HMG_" при удалении окна удаляются автоматически. Вернул обратно PROP_CFILE PROP_FORMNAME PROP_MODIFIED

Andrey: Петр пишет: Предлагаю к включению в MiniGUI "нового" механизма обработки сообщений APPEVENT Для чего нужно это ? Чуток подробней объясните....

SergKis: Петр 1. Как сделать вариант как в примере http://my-files.ru/mauqt9 на hmg2.07 Работа кнопок правых 1,2,3 и кнопки в середине тоолбар с # Выборка по примеру [pre2] line 50 DEFINE WINDOW &cWnd AT 0,0 WIDTH 650+60 HEIGHT 500 ; TITLE 'MiniGUI. Window\TsBrowse:UserKeys Demo' ; ICON 'hmg_ico' ; MAIN NOMAXIMIZE NOSIZE ; ON INIT NIL ; ON RELEASE dbCloseAll() ; ON MOUSECLICK ClickProcedure() line 86 oWnd:UserKeys('FRM_0' , {| | PostMessage( oWnd:Handle, WM_LBUTTONDOWN, 0, 0 ), DoEvents() }) oWnd:UserKeys('FRM_1' , {|o | MsgBox( ( This.Name )+" | "+o:Cargo:Get(1)+( This.FRM_1.Cargo ), oWnd:Name ) }) oWnd:UserKeys('FRM_2' , {|o | MsgBox( ( This.Name )+" | "+o:Cargo:Get(2)+( This.FRM_2.Cargo ), oWnd:Name ) }) oWnd:UserKeys('FRM_3' , {|o | MsgBox( ( This.Name )+" | "+o:Cargo:Get(3)+( This.FRM_3.Cargo ), oWnd:Name ) }) line 191 DEFINE TOOLBAR ToolBar_3 BUTTONSIZE 16,16 FLAT BUTTON FRM_0 ; PICTURE 'page_nr' ; ACTION oWnd:UserKeys( This.Name ) ; TOOLTIP 'Create form'+space(9)+'<1>, <2>, <3>' END TOOLBAR line 355 nY += 20 nX := This.oBrw1.Width+20 @ nY, nX BUTTONEX FRM_1 PICTURE 'n1' CAPTION "" ; ACTION ( oWnd:UserKeys( This.Name ), oBrw1:SetFocus() ) ; WIDTH 50 HEIGHT 50 ; TOOLTIP 'Create form'+space(9)+'<1>' ; NOXPSTYLE NOTABSTOP This.FRM_1.Cargo := ' Form <1> created !' nY += This.FRM_1.Height + 20 @ nY, nX BUTTONEX FRM_2 PICTURE 'n2' CAPTION "" ; ACTION ( oWnd:UserKeys( This.Name ), oBrw1:SetFocus() ) ; WIDTH 50 HEIGHT 50 ; TOOLTIP 'Create form'+space(9)+'<2>' ; NOXPSTYLE NOTABSTOP This.FRM_2.Cargo := ' Form <2> created !' nY += This.FRM_2.Height + 20 @ nY, nX BUTTONEX FRM_3 PICTURE 'n3' CAPTION "" ; ACTION ( oWnd:UserKeys( This.Name ), oBrw1:SetFocus() ) ; WIDTH 50 HEIGHT 50 ; TOOLTIP 'Create form'+space(9)+'<3>' ; NOXPSTYLE NOTABSTOP This.FRM_3.Cargo := ' Form <3> created !' line 711 STATIC FUNC ClickProcedure() Local nRow := _HMG_MouseRow Local nCol := _HMG_MouseCol Local cWnd := _HMG_ThisFormName Local aNam := {'FRM_1', 'FRM_2', 'FRM_3'} // button control name Local i, h If nRow == 0 .and. nCol == 0 For i := 1 To len(aNam) h := GetControlHandle(aNam[ i ], cWnd) SendMessage( h, WM_LBUTTONDOWN, 0, 0 ) // press button SendMessage( h, WM_LBUTTONUP , 0, 0 ) // unpress button InkeyGui(100) Next EndIf RETURN Nil [/pre2] Как такое проделать с APPEVENT 2. Кроме SendMessage, наверно нужно и PostMessage 3. О Set\GetProp пожелание 1. Включить во внутрь сериализацию\десереализацию, т.е положили массив\хеш\блок получили назад, как было 2. Events WM_DESTROY сделать на базе EnumProps автоматическое удаление уст. SetProp на окне и с mdi тоже.

SergKis: PS. 3. Надо спрятать на окне, наверное #define WM_APP 0x8000 #define EV_FIRE (WM_APP + 1) вроде это свойство окна, т.е. при создании окна куда то положить. К примеру, есть 99 видов начислений\удержаний и надо создать на окне расчета For i := 1 To len(aVop) APPEVENT ( WM_APP + i ) ACTION aAction[ i ] OF ThisWindow.Handle // лучше просто i, без WM_APP Next 4. Возможно надо передать какие то параметры постоянные, может так APPEVENT ( WM_APP + i ) ACTION aAction[ i ] OF ThisWindow.Handle PARAM aParam[ i ] 5. На окно (другое) с градусником (и др. данными процесса расчета), также ставим APPEVENT ... (окно знает, как правильно отображать). 6. В цикле расчета, начинаем с какого то кода\Id nKey := nIdStart If nKey > 0 nKey := SendMessage(ThisWindow.Handle, nKey, 0, 0) PostMessage(Grad.Handle, WM_APP+1, 0, 0) // для градусника EndIf ... Если я правильно понял с APPEVENT

Петр: SergKis пишет: 1. Как сделать вариант как в примере Не сразу уловил, в чем проблема. В рабочем варианте будет возможность добавления множественных событий ON для одного окна, а также добавлена поддержка ONCE (однократно исполняемое событие) SergKis пишет: Кроме SendMessage, наверно нужно и PostMessage Нужно, как и SendMessageTimeout, я думаю упаковать все EmitAppEvent с соотв. параметрами. SergKis пишет: 1. Включить во внутрь сериализацию\десереализацию, т.е положили массив\хеш\блок получили назад, как было В Harbour не поддерживается сериализация блоков кода. Все остальное в руках программиста. Не хотелось бы ограничивать никого своими предпочтениями, иными словами пока я склоняюсь к тому, что каждый, используя пример, может написать свои пользовательские функции, так как это ему нужно. И еще - некоторые манипуляции лучше проделывать на PRG, т.е. более высоком уровне. SergKis пишет: 2. Events WM_DESTROY сделать на базе EnumProps автоматическое удаление уст. SetProp на окне и с mdi тоже. Я так понял идет речь о PRG функции Events? Вы можете использовать EnumPropsEx, предварительно заменив #if 0 на #if 1 (или т.п.) и перекомпилировав библиотеку bCodeBlock := {|hWnd,cPropName,hHandle| HB_SYMBOL_UNUSED( hHandle ), RemoveProp( hWnd, cPropName ) } nRetVal := EnumPropsEx( nHandle, bCodeBlock )

SergKis: Петр пишет Вы можете использовать EnumPropsEx Я имею ввиду тех, кто ставит SetProp и забывает убрать их, разве не будет происходить утечка памяти ? В Harbour не поддерживается сериализация блоков кода. пусть будут array и hash, например в лето удобно параметр array передал на сервер, в функции получил и обратно так же. Это же на уровне _Set\GetWindowProp, записать их все равно нельзя. Почему сразу не сделать вариант, введя тип, к примеру <A>, <H> : STATIC aPropTypes := {'<A>', '<H>' } FUNC SetPropType(nNr, cType) и менять, если надо.

SergKis: PS Можно все типы ввести, которые могут проходить и проверять при GetProp

Петр: SergKis пишет: Я имею ввиду тех, кто ставит SetProp и забывает убрать их, разве не будет происходить утечка памяти ? Будет, в т.ч и у вас если забудете Поэтому в h_windowsMDI.prg лучше заменить _RemoveProperty( hWnd, "PROP_CFILE" ) _RemoveProperty( hWnd, "PROP_FORMNAME" ) _RemoveProperty( hWnd, "PROP_MODIFIED" ) на EnumPropsEx( hWnd, {|hWnd,cPropName,hHandle| HB_SYMBOL_UNUSED( hHandle ), RemoveProp( hWnd, cPropName ) } ) SergKis пишет: Почему сразу не сделать вариант Я в свое время, уже и не помню почему, не захотел Вы попробуйте.. UPD. Забыл про совместимость - эти функции написаны Andy Wos еще в 2005 году (а тогда и сериализация, вроде бы, еще не была написана). Я правил функции, а не писал их с нуля - это накладывает некоторые ограничения.

SergKis: Петр пишет Вы попробуйте.. Посмотрел уже, С код не проходит, сильно разный с hmg 2.07 Будет, в т.ч и у вас если забудете Потому и не использую, т.к. надо или списки городить того, что ставишь, или C коды адаптировать. Причем держать в голове ситуацию подвиса, о которой писал ранее. Потому спасибо, конечно, но пока Set\GetProp это мимо.

Петр: Andrey пишет: Для чего нужно это ? Чуток подробней объясните.... Andrey это трудно обьяснить. Наверное, просто так, в рамках добавления в MiniGUI элементов поддержки событийно-ориентированного программирования (см.) Наряду с включением поддержки акселераторов, должно облегчить нелегкую жизнь программиста MiniGUI Теперь ищите, куда это пристроить, (вот SergKis уже присматривается )

SergKis: Петр пишет Наряду с включением поддержки акселераторов, должно облегчить нелегкую жизнь программиста MiniGUI А я к своим "баранам", только не говорите, что есть set evens (нет его, религия у меня такая ). Причина в том, что этого set evens мало, т.к. в первую очередь не выделены места во внутренностях МиниГуи для блоков кода-исполнителей. Их надо засунуть в _HMG_aControlMiscData1 [k], а там разная длина массива, а где то =0. Т.е. Надо что бы везде был массив и устанавливать в последний элемент, забирать по ATail. Чем будет последний элемент, это технка (массив\hash\object) не столь важно. По содержимому (это блоки кода): a. 1. bGet - аналог bData из tsb колонки, для заполнения Value 2. bPut - для записи данных Value куда либо 3. bRefresh - перепоказ 4. bRestore - прочитать\уст. данные свойств контрола с вн. источников 5. bSave - сохранить данные свойств контрола на вн. источнике 6. bOther - ? возможно будет не нужен, но наличие его, в общей схеме, не помешает b. 1. Зарезервировать сообщения WM_USER+... для команд пункта a. 2. Добавить в Events() выполнение блоков кода по сообщениям с. 1. Добавить такое же (пункты a.) на окно (с теми же сообщениями WM_USER+...) Тогда работа с Post\SendMessage по сообщениям WM_USER+... будет простым d. Решение с клавишами должно укладываться в существ. схему SET HOTKEY ON - это default работа как сечас SET HOTKEY OFF - по акселератом SET KEY ... TO ACTION ... как сечас и для акселераторов SET GLOBAL ... для акселераторов не нужна, по мне (всегда заменит уст. на окно с массива\hash) может упустил что, но это главное.

SergKis: Петр пишет вот SergKis уже присматривается Просто хотел понять, правильно ли я понимаю APPEVENT. На сегодня мне вполне хватает для расчетов :UserKeys и сообщения на WM_HMG_NOTIFY_LBL[pre2] ElseIf nMsg == WM_HMG_NOTIFY_LBL // BAA IF ValType( _HMG_aControlMiscData1 [ i ] [4] )=='B' // это введенный bOther на Label _DoControlEventProcedure( _HMG_aControlMiscData1[ i ][4], i ) ELSE [/pre2] Делается фиктивный\ненужный Label для Cargo и выполнения блока по сообщению WM_USER+... -> WM_HMG_NOTIFY_LBL Сопля, конечно, но что делать "родного" механизма нет

Петр: SergKis пишет: А я к своим "баранам" Вы могли бы открыть новую тему. , только не говорите, что есть set evens (нет его, религия у меня такая ) Есть, это MiniGUI и стандартная функция Events - часть этого механизма. SergKis пишет: Причина в том, что этого set evens мало, т.к. в первую очередь не выделены места во внутренностях МиниГуи для блоков кода-исполнителей. Вся "прелесть" ситации в том, что эти "блоки кода - исполнители" часть прикладной программы и засовывать их внутрь библиотеки неправильно. Вы можете написать для своей программы какой-нибудь условный MyAppEvents(), установить его обработчиком с помощью set func events to. А в этом локальном обработчике уже делать, что-то типа [pre2] ElseIf nMsg == WM_HMG_NOTIFY_LBL // BAA IF ValType( _MY_aControlMiscData1 [ i ] [4] )=='B' // это введенный bOther на Label _DoControlEventProcedure( _MY_aControlMiscData1[ i ][4], i ) ELSE [/pre2] _MY_aControlMiscData1 (нужной вам структуры)вы можете инициализировать в 'условной' MyAppInit. Каждый инструмент предполагает его правильное использование и MiniGUI не исключение

Петр: SergKis пишет: Решение с клавишами должно укладываться в существ. схему SET HOTKEY ON - это default работа как сечас SET HOTKEY OFF - по акселератом hotkeys и accelerators - два разных механизма со своей сферой применения, что конечно не может помешать вам использовать их не по назначению

SergKis: Петр пишет Вы могли бы открыть новую тему А смысл, все равно останемся при своих. Вы - делай сам. Я - а как же религия МиниГуи, _HMG_... переменные наше все. Есть много возможностей, но нет (хотя бы) НИ ОДНОГО сообщения для управления через очередь этим всем, хотя это религия windows. Вся "прелесть" ситации в том, что эти "блоки кода - исполнители" часть прикладной программы и засовывать их внутрь библиотеки неправильно. В данном случае мы говорим только о внутренностях МиниГуи - ее контролах, событиях и окнах. До прикладнухи еще далеко.

SergKis: PS Если бы было, хотя бы одно сообщение, в МиниГуи WM_USER+... с bOther в _HMG_aFormMisc1[k] и _HMG_aControlMisc1[k] (зарезервировано место) - все вопросы бы отпали. Сейчас в МиниГуи задействованы несколько WM_USER+, мы задействовали несколько дополнительно, Где гарантия, что мы не пересечемся по ним в новых версиях ? Основное, что волнует, логическая организация _HMG_aFormMisc1[k] и _HMG_aControlMisc1[k] - это код прогр. Даже WM_USER+... не сильно беспокоит, это define. Но нет, так нет.

Петр: SergKis пишет: Вы могли бы открыть новую тему А смысл, все равно останемся при своих. Смысл в том, что не надо флудить: в этой теме обсуждался механизм использования сообщений из диапазона WM_APP, в случае успеха, этот механизм можна было бы расширить на WM_USER. Но нет, так нет. Вы - делай сам. Я - а как же религия МиниГуи, _HMG_... переменные наше все. В этом смысле я не религиозный человек. К тому же я не автор библиотеки, не мантейнер. Я такой же, время от времени, контрибутор, как и вы. Создайте, что нибудь годящее и направьте Григорию, пусть у него голова болит

SergKis: Петр пишет Смысл в том, что не надо флудить: в этой теме обсуждался механизм использования сообщений из диапазона WM_APP, в случае успеха, этот механизм можна было бы расширить на WM_USER. Что будет работать, не сомневаюсь, суть ясна, детали нет, но это потом прояснится. Флуда нет (WM_USER, APPEVENT суть одна, содержимое разное), все, что писал, связано с APPEVENT, хотя бы тем, что прописанные блоки кода, надо вызывать через процедуры _DoControlEventProcedure ( bBlock, i, cEventType, nParam ) если APPEVENT свяжется с контролом _DoWindowEventProcedure ( bBlock, i, cEventType ) для окна, связка уже есть

Петр: SergKis пишет: (WM_USER, APPEVENT суть одна, содержимое разное), все, что писал, связано с APPEVENT, хотя бы тем, что прописанные блоки кода, надо вызывать через процедуры _DoControlEventProcedure ( bBlock, i, cEventType, nParam ) если APPEVENT свяжется с контролом _DoWindowEventProcedure ( bBlock, i, cEventType ) для окна, связка уже есть Функционал реализован, возможно это не то и не так, как представляли его вы - не знаю. Пожалуйста тестируйте. Рад буду услышать ваше мнение. В споре рождается истина

SergKis: Петр пишет Функционал реализован, Я тут, бегом все, мельком глянул. Вопрос появился. #define MAX_EVENTS 64 т.е. если у меня 64 окна, я их спокойненько пронумеровал +1...+64 и чудненько имею по 1 APPEVENT у каждого. Если у меня 65 или 150-300, то я, немного потрахавшись, типа save\restore, save\restore,... в итоге получаю удовольствие ... Или я мимо, не попал на бегу ?

Петр: SergKis пишет: #define MAX_EVENTS 64 т.е. если у меня 64 окна, я их спокойненько пронумеровал +1...+64 и чудненько имею по 1 APPEVENT у каждого. Вы имеете 64 события ON (повторяющиеся) на одно окно или 4096 событий на 64 окна. при этом они должны лежать в диапазоне WM_APP..WM_APP + MAX_EVENTS Все сказанное справедливо по отношению и к событиям ONCE (однократные события). Для WINEVENT (там MAX_EVENTS тоже используется) вы имеете еще 64 события ON/ONCE на одно окно, при этом события лежат в диапазоне 0..WM_APP + MAX_EVENTS + практически неограниченное к-во событий вы можете обрабатывать в оконной функции (events func) Если кому-то этого буде мало - можно спокойно переопределить MAX_EVENTS и перекомпилировать библиотеку.

SergKis: Петр пишет Если кому-то этого буде мало В связи с MESSAGEONLY myWnd EVENTS myWndEvents TO hwnd и этого много, т.к. пока, применения, кроме присвоения номера окну (регистрация) для доступа к конфигурации и др. ресурсам программы не вижу. MESSAGEONLY myWnd EVENTS myWndEvents TO hwnd покрывает мои потребности, особенно, если Set\GetProp могут сохранять\возвращать ссылку на объект, hash. Если еще убрать во внутрь базу WM_USER, WM_APP (+ и - делать там), то и исп. проще, без доп. обвесов своими ф-ями. По MESSAGEONLY только один вопрос, как перевести в версию hmg 2.07, для совместимости.

Петр: SergKis пишет: По MESSAGEONLY только один вопрос, как перевести в версию hmg 2.07, для совместимости В чем уникальность этой версии, чтобы уделять ей какое-то внимание?



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