Форум » GUI » Новая версия Расширенного релиза библиотеки MiniGUI (часть VI ) (продолжение) » Ответить

Новая версия Расширенного релиза библиотеки MiniGUI (часть VI ) (продолжение)

gfilatov: Начало темы находится здесь, а теперь АНОНС * АНОНС * АНОНС * АНОНС * АНОНС Готовится к опубликованию новая сборка №48, которая выйдет в конце недели. Если у Вас есть интересные наработки для включения в новый релиз, то сейчас самое удобное время для их отправки мне Кратко, что нового: - исправление обнаруженных ошибок и неточностей кода; - новый класс HEADERIMAGE для Grid и Browse; - свойство Address в Hyperlink может теперь открывать папку или файл на диске; - добавлен NOTABSTOP класс для Browse; - поддержка пользовательских компонентов (заимствована из оффициального релиза); - расширения и исправления в библиотеках TsBrowse и PropGrid; - обновлены сборки Харбор и HMGS-IDE; - новые и обновленные старые примеры (как обычно ).

Ответов - 300, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

SergKis: gfilatov2002 Предложение [pre2] FUNCTION Events ( hWnd, nMsg, wParam, lParam ) ... **************************************************************************** CASE WM_TIMER **************************************************************************** i := AScan ( _HMG_aControlIds , wParam ) IF i > 0 #ifdef _NAMES_LIST_ x := _SetGetNamesList( "bWM_TIMER" ) IF HB_ISBLOCK( x ) IF !Empty( Eval( x, _HMG_aControlNames [ i ], GetParentFormName( i ), i ) ) EXIT // return 1 => everything is done ENDIF ENDIF #endif IF _HMG_aControlPicture [ i ] == .T. // Once ... **************************************************************************** CASE WM_COPYDATA **************************************************************************** #ifdef _NAMES_LIST_ x := _SetGetNamesList( "bWM_COPYDATA" ) IF HB_ISBLOCK( x ) Eval( x, hWnd, nMsg, wParam, lParam ) ENDIF #endif EXIT **************************************************************************** CASE WM_QUERYENDSESSION CASE WM_POWERBROADCAST **************************************************************************** i := 0 #ifdef _NAMES_LIST_ x := _SetGetNamesList( "bWM_PowerEndSession" ) IF HB_ISBLOCK( x ) i := Eval( x, hWnd, nMsg, wParam, lParam ) ENDIF #endif IF Empty( i ) __Quit() ENDIF EXIT **************************************************************************** CASE WM_CLOSE **************************************************************************** ... или WM_POWERBROADCAST отделить от WM_QUERYENDSESSION, т.е. ... **************************************************************************** CASE WM_QUERYENDSESSION **************************************************************************** __Quit() EXIT **************************************************************************** CASE WM_POWERBROADCAST **************************************************************************** #ifdef _NAMES_LIST_ x := _SetGetNamesList( "bWM_POWERBROADCAST" ) IF HB_ISBLOCK( x ) i := Eval( x, hWnd, nMsg, wParam, lParam ) ENDIF #endif EXIT ... [/pre2] PS Для разных таймеов можно делать один обработчик, назначив _SetGetNamesList( "bWM_TIMER", bBlock ) без исп. This среды, например для запуска выполнения в потоке DEFINE TIMER <name> INTERVAL <interval>

gfilatov2002: SergKis пишет: Предложение Это предложение мне очень нравится, но оно вносит в систему новые недокументированные глобальные статические переменные, знание имен которых будет требоваться от разработчика. Поэтому пока я отказался от этого дополнения в пользу универсального обработчика, который легко заменить на собственный менеджер событий по команде SET EVENTS FUNC TO <имя функции> Поскольку новая сборка уже собрана, буду рассматривать это предложение как задел на будущее...

SergKis: gfilatov2002 пишет буду рассматривать это предложение как задел на будущее... Вариант работы с сообщениями, как пример: [pre2] STATIC s_oWM_Names, s_oWM_Events MEMWAR p_oWM_Message ... PUBLIC p_oWM_Message ... s_oWM_Names := oHmgData() s_oWM_Names:Set( { ; {WM_MBUTTONDOWN , "WM_MBUTTONDOWN "}, ; {WM_RBUTTONDOWN , "WM_RBUTTONDOWN "}, ; {WM_LBUTTONDOWN , "WM_LBUTTONDOWN "}, ; {WM_MOUSEMOVE , "WM_MOUSEMOVE "}, ; {WM_MOVE , "WM_MOVE "}, ; {WM_HOTKEY , "WM_HOTKEY "}, ; {WM_KEYDOWN , "WM_KEYDOWN "}, ; {WM_KEYUP , "WM_KEYUP "}, ; {WM_MOUSEWHEEL , "WM_MOUSEWHEEL "}, ; {WM_INITMENUPOPUP , "WM_INITMENUPOPUP "}, ; {WM_UNINITMENUPOPUP, "WM_UNINITMENUPOPUP"}, ; {WM_SETFOCUS , "WM_SETFOCUS "}, ; {WM_HELP , "WM_HELP "}, ; {WM_HSCROLL , "WM_HSCROLL "}, ; {WM_VSCROLL , "WM_VSCROLL "}, ; {WM_TASKBAR , "WM_TASKBAR "}, ; {WM_WND_LAUNCH , "WM_WND_LAUNCH "}, ; {WM_CTL_LAUNCH , "WM_CTL_LAUNCH "}, ; {WM_NEXTDLGCTL , "WM_NEXTDLGCTL "}, ; {WM_DROPFILES , "WM_DROPFILES "}, ; {WM_CONTEXTMENU , "WM_CONTEXTMENU "}, ; {WM_SIZE , "WM_SIZE "}, ; {WM_COMMAND , "WM_COMMAND "}, ; {WM_NOTIFY , "WM_NOTIFY "}} ) s_oWM_Events := oHmgData() FOR EACH nMsg IN s_oWM_Message:Keys() s_oWM_Events:Set( nMsg, NIL ) // или блок кода для исполнения можно заносить на ключ nMsg, потом читать для выполнения NEXT p_oWM_Message := oHmgData() p_oWM_Message:oNames := s_oWM_Names p_oWM_Message:oEvents := s_oWM_Events ... добываем ... o := p_oWM_Message:oNames cMsg := "Event arrived - " + o:Get(nMsg, "?") ? HB_TSTOSTR( HB_DATETIME() ), cMsg, ProcNL() ... o := p_oWM_Message:oEvents IF HB_ISBLOCK( o:Get(nMsg, Nil) ) x := Eval( o:Get(nMsg), hWnd, nMsg, wParam, lParam ) IF !Empty( x ) RETURN 1 ENDIF ENDIF ... [/pre2] Можно подумать и убрать из prg в ресурсы языковые тексты. Например в формат ini, т.е. имеем в RESOURCE ini файлы, например, в utf8 с BOM en.ini ru.ini cs.ini ... в rc файле имеем EN RCDATA en.ini RU RCDATA ru.ini CS RCDATA cs.ini ... Пример Ini варианта для переменных _HMG_... как секции для языков EN и RU тут https://TransFiles.ru/icjjs


gfilatov2002: SergKis пишет: Вариант работы с сообщениями, как пример Спасибо!

gfilatov2002: Выложил последнюю сборку 23.09 с учетом последних исправлений Скачать Желаю всем форумчанам доброго здоровья! Мира вам, добра и процветания

Andrey: Собрал на новой версии свою большую систему. [pre2]: Harbour 3.2.0dev (r2307062207) : Borland C++ 5.8.2 (32-bit) : Harbour MiniGUI Extended Edition 23.09.0 (32-bit) ANSI [/pre2] Работает, у меня Win10 У заказчика в Николаеве тоже Win10, вылетает на ВСЕХ таблицах... Вот такая ошибка: [pre2]Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 67202 [2] = N 129 [3] = N 0 [4] = N 1695368 Called from EVENTS(0) Called from _CREATEWINDOWEX(0) Called from TSBROWSE:CREATE(0) Called from TSBROWSE:NEW(0) Called from _DEFINETBROWSE(0) Called from FORM_MYTABLE(324) in module: Source\Tbrw_table.prg Called from TBRWDOGOVOR(16) in module: Source\Tbrw_1Run.prg Called from (b)HB_MACROBLOCK(0)[/pre2] Почему так ? У меня в коде так:[pre2] SET EVENTS FUNCTION TO MyEventsHandler DEFINE WINDOW Form_Main ; .... // этот обработчик вызывается всегда вместо Events(...) FUNCTION MyEventsHandler( hHwnd, nMsg, wParam, lParam ) ... RETURN Events( hHwnd, nMsg, wParam, lParam) [/pre2]

Dima: Andrey У тебя с 2019 года глюки какие то с MyEventsHandler и Пётр писал тебе что нужно сделать.

Andrey: Dima пишет: У тебя с 2019 года глюки какие то с MyEventsHandler и Пётр писал тебе что нужно сделать. Что-то по форуму поискал и не нашёл это сообщение. Покажи пожалуйста его.

Dima: Тема http://clipper.borda.ru/?1-1-0-00000495-000-10001-0-1499871709 сообщение 1318

Andrey: Dima пишет: сообщение 1318 Петр пишет: Напишите корректный обработчик MYEVENTS, не перехватывайте ненужные события, перенаправьте их стандартному обработчику HMG (если, что Events() называется). Опять задание для телепатов. Дима - ошибка в другом: [pre2]Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 67202 [2] = N 129 [3] = N 0 [4] = N 1695368 Called from EVENTS(0) Called from _CREATEWINDOWEX(0) [/pre2] Обработчик нормальный !!! У меня работает, у заказчика НЕТ ! 3 раза перепроверил только что - Версия 23.07 работает, а 23.09 вылетает

SergKis: Andrey Когда то давно предлагал вариант, который у меня в версии от 2012 года, попробуй сейчас у себя Добавка в h_events.prg [pre2] STATIC s_bEvents *-----------------------------------------------------------------------------* FUNCTION Set_bEvents ( bBlock ) *-----------------------------------------------------------------------------* LOCAL b := s_bEvents IF HB_ISCHAR( bBlock ) IF "(" $ bBlock bBlock := "{|...| " + bBlock + " }" ELSE bBlock := "{|...| " + bBlock + "(...)" + " }" ENDIF bBlock := &( bBlock ) ENDIF s_bEvents := bBlock RETURN b *-----------------------------------------------------------------------------* FUNCTION Events ( hWnd, nMsg, wParam, lParam ) *-----------------------------------------------------------------------------* ... #endif IF HB_ISBLOCK( s_bEvents ) IF !Empty( Eval( s_bEvents, hWnd, nMsg, wParam, lParam ) ) RETURN 1 ENDIF ENDIF SWITCH nMsg **************************************************************************** CASE WM_MEASUREITEM **************************************************************************** ... В программе делаешь //SET EVENTS FUNC TO App_OnEvents // или MyEventsHandler Set_bEvents("App_OnEvents") // Set_bEvents("MyEventsHandler") ... FUNCTION App_OnEvents( hWnd, nMsg, wParam, lParam ) // или MyEventsHandler( hWnd, nMsg, wParam, lParam ) ... wParam := lParam // что бы компилятор не ругался, если не используются RETURN 0 // Events( hWnd, nMsg, wParam, lParam) // nMsg НЕ выполненно [/pre2]

Dima: Andrey пишет: 3 раза перепроверил только что - Версия 23.07 работает, а 23.09 вылетает Вероятно Григорий где то не тот код написал......... Так бывает..

Andrey: Проверил у другого заказчика. У него Win7 Core i3 4Gb ОЗУ Пару раз слетало за день вот примерно с такой ошибкой. [pre2]Time from start: 0 days 0 hours 2 mins 0 secs Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 262796 [2] = N 129 [3] = N 0 [4] = N 1240660 --------------------------------- Stack Trace --------------------------------- Called from EVENTS(0) Called from _CREATEWINDOWEX(0) Called from TSBROWSE:CREATE(0) Called from TSBROWSE:NEW(0) Called from _DEFINETBROWSE(0) Called from WINFORM3(48) in module: Source\mWinForm3.prg Called from START3WIN(57) in module: Source\mWin3Start.prg [/pre2]

Dima: Andrey а что если сделать не большой примерчик , ну там окно , меню и твой MyEventsHandler тоже будет падать ? ps такой пример могу затестить у себя , у меня win7

Andrey: Dima пишет: а что если сделать не большой примерчик , ну там окно , меню и твой MyEventsHandler тоже будет падать ? Не выйдет ! Короткие примеры работают ОЧЕНЬ четко, никогда не валятся. А вот когда ехе-ник большой (у меня 25 Мб) и юзер целый день сидит в программе, то начинаются чудеса. Вот на сервере терминалов прога вчера повисла и сутки висела, почему не знаю. Прога висит (выполняется, таймер каждые 5 минут в лог пишет), а на менюшках тыкать бесполезно. И юзер не может прогу снять, так как это сервер-терминалов, помогает только заход на сервер и снятие программы юзера на сервере. Т.е. в проге опять ОКНО ушло с фокуса и из-за этого прога ВИСИТ, хотя и работает. Уходит окно скорее всего из-за таймера, у меня в проге 3 таймера. Смотрю лог файл, там срабатывает таймер и всё, больше нет ничего, т.е. уход на таймер и окно проги потеряно. Как от этого избавиться - хз Самый длительный вариант избавления - выкинуть эту функцию по таймеру в отдельную программу, но это столько переписывать нужно..... работа на месяц...

Andrey: Прога на новом МиниГуи 23.09 на отличном сервере WinServer 2008 16Гб озу - СТАБИЛЬНО ПАДАЕТ раза два за день в одном и том же месте программы.... То работает, то падает... [pre2]Date: 29.08.2023 Time: 17:05:43 Time from start: 0 days 0 hours 20 mins 3 secs Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 5048360 [2] = N 129 [3] = N 0 [4] = N 1630660 Date: 29.08.2023 Time: 14:01:00 Time from start: 0 days 0 hours 17 mins 43 secs Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 7406422 [2] = N 129 [3] = N 0 [4] = N 1630660 Date: 30.08.2023 Time: 09:23:19 Time from start: 0 days 0 hours 20 mins 13 secs Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 1836998 [2] = N 129 [3] = N 0 [4] = N 1630660 Date: 31.08.2023 Time: 16:01:08 Time from start: 0 days 7 hours 11 mins 6 secs Error BASE/1001 Неизвестная функция: EVENTS Args: [1] = N 5703460 [2] = N 129 [3] = N 0 [4] = N 1630660 --------------------------------- Stack Trace --------------------------------- Called from EVENTS(0) Called from _CREATEWINDOWEX(0) Called from TSBROWSE:CREATE(0) Called from TSBROWSE:NEW(0) Called from _DEFINETBROWSE(0) Called from FORM_MYTABLE(324) in module: Source\Tbrw_table.prg Called from TBRWZAIVKA(116) in module: Source\Tbrw_1Run.prg Called from (b)HB_MACROBLOCK(0) [/pre2] Почему ?

Dima: Andrey А если закоментить строку и пересобрать , тоже упадет ? SET EVENTS FUNCTION TO MyEventsHandler

SergKis: Andrey пишет Самый длительный вариант избавления - выкинуть эту функцию по таймеру в отдельную программу, но это столько переписывать нужно..... работа на месяц... Не соглашусь, т.к. таймер это отдельный вход-запуск, значит можно его запуск повторить с др. места, т.е. запускаем твою же программу с параметрами. Делаем (все ф-ии в твоей проге как были доступны, так и остались): 1 новые параметры входа, данные для таймера сохранили в базе, файле ... 2 создаем событие, аналог запуска таймера, например :Event( 0, {|...| ... }) // запуск ф-ии, которая была по таймеру 3 Main window другое, по параметрам 1 на него попадаем 4 на ON INIT {|| DoEvents(), _wPost(0) } 5 в событии прочитали данные из базы, файла ..., отработали

Andrey: Dima пишет: А если закоментить строку и пересобрать , тоже упадет ? SET EVENTS FUNCTION TO MyEventsHandler Не могу - пропадёт отправка записей на сайт в PostgreSql, да и некоторые вызовы функций из терминалки пропадут. У меня SendMessageData активно используется. Юзер останется с частично рабочей программой.

Haz: Andrey пишет: из-за таймера, у меня в проге 3 таймера. Вместо таймера лучше использовать зацикленный поток и из него посылать событие окну , которое вызывает нужную процедуру Еще лучше - обрабатывать отдельным потоком, но при этом не забываем что рабочие области в потоках не видны постоянно нужно передавать через зеро спэйс или открывать свои в потоке ( можно с тем же алиасом ) Переделка быстрая, к примеру этот поток контролирует oBrw:bCahange и вызывает процедуру только когда пользователь оторвал палец от клавиатурных стрелок ( есть любители ездить вверх-вниз по бровсе без остановок , что вызывает бесконечное число ненужных вызовов bChenge ) [pre2] ... __objAddData (oBrw, 'tTs' ) __objAddData (oBrw, 'lChange' ) oBrw:tTs := HB_DateTime() oBrw:lChange := .f. oBrw:bChange := {|| oBrw:tTs := HB_DateTime(), oBrw:lChange := .t. } ... Func Change() local lMore := .t. local tTs := HB_DateTime() local nTick := 0.041667 / ( 3600 * 4 ) // кждую 1/4 секунды, 0,041667 это разница во времени в 1 час while lMore if oBrw:lChange if HB_DateTime() - oBrw:tTs > nTick oBrw:lChange := .f. _wpost(100, "Form_0") end end HB_ReleaseCPU() end return nil [/pre2]



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