Форум » GUI » Можно ли скомпилировать текст "DEFINE..." в RunTime? » Ответить

Можно ли скомпилировать текст "DEFINE..." в RunTime?

SADSTAR2: Можно ли скомпилировать текст "DEFINE..." в RunTime? Т.е. имеем текст определения визуального элемента в виде "DEFINE...". Нужно его выполнить как блок кода. Что-то мне подсказывает, что это не прокатит. Т.к. DEFINE реализован через xcommand и преобразуется во время прекомпиляции. И что делать в таком случае? Вызывать настоящую функцию _Define...(...)?

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

Петр: можно, Harbour, в отличии от xHb имеет в своем составе библиотеку compiler. См. исходники dot - хорошее наглядное пособие. Еще у нас есть pp.exe., xbscript.. Но, вот как Вы собрались использовать это, я так понял в визуальном редакторе, это уже вопрос. В любом случае все сводится к вызыву "настоящей функции _Define...(...)". Так, что лучше написать парсер (группу парсеров), для разбора (генерации) исходного текста DEFINE ... и преобразования к виду _Define. Причем правила по которому работает парсер должны быть формализованы и сохраняться во внешнем файле (xml, ini). Тогда без изменения основного текста программы, путем добавления нового парсера (правила для парсера) можно реализовать новую функциональность или расширять имеющуюся. Над чем-то подобным я сейчас работаю и первые результаты вполне обнадеживают .

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

Петр: Григорьев Владимир пишет: Компилятор ее не видет, а лишь работает с тем кодом, который получается в результате обработки препроцессором макрокоманды. Совершенно верно. Но также верно, что в Harbour/xHb работа с препроцессором улучшена и пользователь совершенно спокойно может использовать возможности препроцессора не только на этапе компиляции. но и в run-time. Вот небольшой пример использования библиотеки pp и функций для работы с препроцессором. Использован Harbour/консоль, но это неважно. ------------------------------- #xcommand TEXTSTREAM INTO <v> => #pragma __cstream|<v>+=%s PROCEDURE main() LOCAL cTextIn := "", cTextOut := "", cTextRule := "" LOCAL pp, button // получить строку мы можем в любой способ, в т.ч. прочитав из файла TEXTSTREAM INTO cTextRule #xcommand DEFINE BUTTON <name> [ WIDTH <w> ] [ HEIGHT <h> ] => _DefineButton( <"name">, <w>, <h> ) ENDTEXT TEXTSTREAM INTO cTextIn DEFINE BUTTON button HEIGHT 100 ENDTEXT // инициализируем препроцессор, обязательно, // можно без указания пути поиска и стандартного .ch файла pp := __PP_INIT( "C:\Harbour\Include", "C:\Harbour\Include\std.ch" ) // добавляем пути поиска, необязательно __PP_PATH( pp, "C:\MiniGUI\Include", .f. ) // добавляем правила обработки, желательно если хотим добиться результата :-) __PP_ADDRULE( pp, cTextRule ) // обрабатываем строку cTextOut := ALLTRIM( __PP_PROCESS( pp, cTextIn ) ) // сброс настроек препроцессора, необязательно __PP_RESET( pp ) __PP_FREE( pp ) ? ALLTRIM( cTextIn ) ? cTextOut ? &cTextOut RETURN FUNCTION _DefineButton() RETURN "defined" А вот какой результат мы получим на экране DEFINE BUTTON button HEIGHT 100 _DefineButton( "button", , 100) defined Еще рекомендую присмотреться к Harbour библиотеке compiler.lib да и другим расширениям Harbour/xHb которые позволяют решать большие задачи малой кровью.


Петр: Не удержусь и скажу, еще.. Так называемый altsyntax в MiniGUI вообще-то является основным, но реализован настолько .., что слов нет.

SADSTAR2: Петр пишет: Но, вот как Вы собрались использовать это, я так понял в визуальном редакторе, это уже вопрос. Вы удивительно проницательны !!! Была такая задумка - Form Desiner с некоторыми особенностями. 1.В связи с быстрым развитием MiniGUI чтобы не перекомпилировать FormDesiner каждый раз иметь описания всех визуальных элементов во внешних файлах 2.Внутри FormDesiner не пользоваться никакими внутренними системными структурами MiniGUI типа _HMG_Control... а только своими пользовательскими структурами. По весне даже начал кое-что делать в этом направлении. Потом лето наступило и все такое. Сейчас появилась возможность продолжить. И стали выявляться некоторые принципиальные системные проблемы. Но если вы занимаетесь чем-то подобным, может мне не стоит напрягаться в этом вопросе, т.к. из меня системный программист невысокого уровня и мои результаты будут заведомо хуже ваших?

gfilatov: Петр пишет: правила по которому работает парсер должны быть формализованы и сохраняться во внешнем файле (xml, ini) Существует интересная библиотека MidleX с открытым кодом по адресу http://www.rouvali.com/index.php?id=19, которая реализует определение форм в файлах xml-формата. К сожалению, она работает только под xHarbour 0.99.50 ... oForm:=RequestForm("myForm") oForm:Show() ... XML file: ... <form id="myForm" class="TEditForm" appearence="center" x="1" y="1" width="550" height="150" title="Asiakas"> <datasource id="default" source="dbf:asiakas.dbf"/> <label y="40" x="10" caption="Asiakas" /> <textbox y="40" x="100" width="400" field="default/name" /> ... Петр если это Вас заинтересует, то адаптация кода этой библиотеки к xHarbour CVS (или хотя бы подсказка, в каком направлении делать модификацию) была бы весьма кстати для всех пользователей MiniGUI

gfilatov: Петр пишет: altsyntax в MiniGUI вообще-то является основным, но реализован настолько .., Жду Ваших ранее обещанных предложений по усовершенствованию кода...

Петр: Sadstar2, Я действительно работаю, над IDE для MINIGUI/HARBOUR, в т.ч. и частью этого проекта будет визуальный редактор. И также подтверждаю, что после окончания работ, или на том этапе, когда посчитаю проект вполне готовым для тестирования, он будет выложен в общедоступное место. Могу подтвердить ваши слова, что на определенном этапе сталкиваешся с определенными "принципиальными системными проблемами". Но это не проблемы HARBOUR, а проблемы MINIGUI, вернее особенности реализации. Спасибо Григорий, я посмотрю MidleX. Теперь о усовершенствовании кода библиотеки. Я думаю, к этому подходить нужно системно и взвешено. Вот из недавней переписки в группе MiniGUI. Добавление обработки события ON INTERACTIVECLOSE for MDICHILD windows nWindowHandle := ASCAN(_HMG_aFormNames, ThisWindow.Name) IF nWindowHandle > 0 _HMG_aFormInteractiveCloseProcedure[nWindowHandle] := ; { || SalidadeProceso("Navegador", cFormName) } ENDI вполне работоспособное решение. Но оно показывает все проблемы архитектуры MiniGUI. конечно можно все решить, запретить пользователям напрямую обращаться к внутренним структурам библиотеки, написать интерфейс для общения прикладных программ и библиотеки, ну например, что-то frmInstallOnEventProcedure( cFormName, OE_INTERACTIVECLOSE, { || SalidadeProceso("Navegador", cFormName) } ) но как быть с совместимостью ? Нас поймут правильно ? Ну, а с лету предложения : 1) не сочтите за шутку /*---------------------------------------------------------------------------- MINIGUI - Harbour Win32 GUI library source code Copyright 2002 Roberto Lopez <roblez@ciudad.com.ar> http://www.geocities.com/harbour_minigui/ .. а вот оригинал /*---------------------------------------------------------------------------- MINIGUI - Harbour Win32 GUI library source code Copyright 2002-2007 Roberto Lopez <harbourminigui@gmail.com> http://harbourminigui.googlepages.com/ .. "Harbour GUI framework for Win32" Copyright 2001 Alexander S.Kresin <alex@belacy.belgorod.su> Copyright 2001 Antonio Linares <alinares@fivetech.com> www - http://www.harbour-project.org "Harbour Project" Copyright 1999-2007, http://www.harbour-project.org/ "WHAT32" Copyright 2002 AJ Wos <andrwos@aust1.net> "HWGUI" Copyright 2001-2007 Alexander S.Kresin <alex@belacy.belgorod.su> Почему, например, в c_menu.c должен стоять копирайт Lopeza - я не понимаю. 2) следовать примеру HARBOUR, позаботиться о namespace - пространстве имен, ну например, все функции по работе с формами могут иметь префикс frm.. 3) следовать примеру HARBOUR, весь исходный код должен быть единообразно отформатирован, для С кода есть отличный форматер GC, позволяющий подобрать "свой" стиль оформления, для HARBOUR нужно подумать. 4) примеры принимать тоже отформатированные по принятому образцу в них легче будет разбираться всем, а не только автору. 5) не нужно файлов - свалок по образу с_winapimisc.c. 6) убрать ненужные дубляжи функций - из того же с_winapimisc функция IsVista вполне может быть заменена на макрос "Vista"$OS() 7) перенести из winprint библиотеки некоторые функции, которые нужны разработчикам Array2Rect, Array2Point и т.д. 8) создать для сборки библиотеки makefile. 9) если есть файлы сборки MINIGUI EX. для компиляторов отличных от bcc, нужно их выложить, чтобы не наблюдать #ifndef __POCC__, это ведь не решение закомментировать часть кода. И здесь большая роль отводиться вам, Григорий, как основному "держателю" кода MINIGUI EX. В первую очередь принять необходимость изменений самому, в вторых разьяснить на пальцах пользователям почему нужно изменять код, который вроде бы и так работает. А это не легкое дело, вспомните как восприняли изменения GETSTARTUPFOLDER, включение библиотеки propgrid. До чего тогда договорились - человек ни единой строчки кода которого в MINIGUI EX нет, обвиняет члена MiniGUI Team, в попытке навязывания new comer lib..

gfilatov: Петр пишет: как быть с совместимостью ? Нас поймут правильно ? НЕ ПОЙМУТ... Совместимость обязательна - проверено практикой Петр пишет: с лету предложения : 1) знаю, руки не доходили Петр пишет: Почему, например, в c_menu.c должен стоять копирайт Lopeza Поправлю! 2) проблематично в плане совместимости старого кода 3) согласен, присылайте пример отформатированного кода (и инструментарий, конечно ) 4) при наличии форматтера я и сам это могу сделать 5) не проблема - почистим 6) функция IsVista() - это просто значение глобальной переменной _HMG_IsVista 7) некритично, поскольку эта библиотека включается при линковке с помощью compile.bat 8) есть рабочий вариант строго для внутреннего использования 9) из-за узкой направленности на Борланд Си это некритично, хотя я и собирал библиотеку с помощью PelleC - это требует некоторых изменений в Си-коде Петр пишет: большая роль отводиться вам, Григорий, как основному "держателю" кода MINIGUI EX Спасибо за доверие, Ваша поддержка для меня очень ценна. Петр пишет: я посмотрю MidleX Ловлю на слове - это было бы весьма полезно

Петр: gfilatov пишет: 2) проблематично в плане совместимости старого кода Да, но не так все плохо *------------------------------------------------------------------------------* Function controlGetParentForm( hWnd ) *------------------------------------------------------------------------------* Local i := ascan(_HMG_aControlHandles, hWnd), ParenthWnd if i > 0 ParenthWnd := _HMG_aControlParenthandles endif Return ParenthWnd HB_FUNC( _GETPARENT ) { HB_FUNC_EXEC( CONTROLGETPARENTFORM ); } И файл с таким содержанием добавить - так мол и так, не будет больше функции _GetParent, пользуйтесь, pls, controlGetParentForm - это быстрее, надежнее и ориентированное на завтра решение. Поддержка функции _GetParent, оставлена только для поддержания совместимости и в любой момент может быть прекращена. Точно так можно было поступить и с GETWINDOWSFOLDER. 6) функция IsVista() - это просто значение глобальной переменной _HMG_IsVista Да, тут я перепутал с HMG, там в файле с_winapimisc.c определена функция IsVista Но, IMHO такие глобальные переменные не зачем засовывать в _HMG_SYSDATA. Доступ к элементу массива медленее, чем доступ к глобальной переменной. 7) некритично, поскольку эта библиотека включается при линковке с помощью compile.bat Григорий, Array2Rect продублирована в обеих библиотеках (c_controlmisc1.c c_winxp.c ), Rect2Array, Point2Array включены в tsbowse. Вот еще две функции из этой серии Array2Point и PtInRect. HB_FUNC( PTINRECT ) { POINT point; RECT rect; BOOL bIn = FALSE; if( ( Array2Point( hb_param( 1, HB_IT_ARRAY ), &point ) && Array2Rect( hb_param( 2, HB_IT_ARRAY ), &rect ) ) ) { if( PtInRect( &rect, point ) ) { bIn = TRUE; } } hb_retl( bIn ); } /* */ BOOL Array2Point( PHB_ITEM aPoint, POINT *pt ) { if ( HB_IS_ARRAY( aPoint ) && hb_arrayLen( aPoint ) == 2 ) { pt->x = hb_arrayGetNL( aPoint, 1 ); pt->y = hb_arrayGetNL( aPoint, 2 ); return TRUE; } return FALSE; } Все эти функции востребованы при написании ownerdraw control и просто должны быть включены в MiniGUI, как и некоторые другие. 8) есть рабочий вариант строго для внутреннего использования был бы благодарен, если бы вы выслали мне этот вариант gfilatov пишет: 9) из-за узкой направленности на Борланд Си это некритично Да, но тем не менее #ifndef __POCC__. Если у вас сохранился файл сборки для PellesC, я был бы не против посмотреть.

gfilatov: Петр пишет: Все эти функции востребованы при написании ownerdraw control и просто должны быть включены в MiniGUI, как и некоторые другие. Нет проблем, присылайте полный пакет С-функций для добавления Петр пишет: был бы благодарен, если бы вы выслали мне Уже отправил.

Петр: gfilatov пишет: Существует интересная библиотека MidleX. К сожалению, она работает только под xHarbour 0.99.50 Я скачал исходный код MidleX по указанной ссылке и посмотрел. Вы уверены, что она работает с xHarbour 0.99.50? Судя по первому взгляду, в таком своем состоянии она не должна работать с xHb, с Harbour, впрочем, тоже . Да и автор в redme пишет: You really should not base any work for this library yet, it's under heavy changes... Некоторые шаги по реанимации я уже сделал и получил Called from _DEFINEWINDOW(3496) Called from TBROWSE:LOADXML(421) Called from TBROWSE:SHOW(522) Called from MAIN(60) Прошу уточнить - она заточена под MiniGUI Ex или HMG? latests minigui (Build 99b) это что?

gfilatov: Петр пишет: latests minigui (Build 99b) это что? Это старая официальная версия MiniGUI под BCC, датированная 29 июня 2004 года Подробнее о последней рабочей версии MidleX можно прочитать (и скачать) на финском портале xHarbour по адресу http://www.the-holms.org/xharbour/addon.htm Как я понял, закавыка состоит в изменении низкоуровневых функций xHarbour с версии 0,99,60, которые использует MidleX Ну и, конечно, последней версией MiniGUI Ex, которая работает с MidleX, является версия 14e

Петр: gfilatov пишет: Как я понял, закавыка состоит в изменении низкоуровневых функций xHarbour с версии 0,99,60, которые использует MidleX Нет, не совсем. Главная проблема в том, что произошли изменения в MiniGUI и добрую половину MidleX нужно сверять и править или дописывать, все остальное решаемое в рабочем порядке.

gfilatov: Петр пишет: произошли изменения в MiniGUI и добрую половину MidleX нужно сверять и править Я делал адаптацию MidleX для HMG Ex build 23, тестовая программа собиралась, но при запуске получал GPF. Поэтому я и решил, что дело в Си-коде

Петр: gfilatov пишет: но при запуске получал GPF. Вы прилинковывали pcrepos.lib? Убрали ключ /b и debug.lib?

gfilatov: Петр пишет: Вы прилинковывали pcrepos.lib? Нет Петр пишет: Убрали ключ /b и debug.lib? Тоже нет Это критично для запуска приложения с использованием MidleX?

Петр: gfilatov пишет: Это критично для запуска приложения с использованием MidleX? Отладчик использует CLASS TDbgBrowser FROM TBrowse А MidleX переопределяет класс TBrowse class TBrowse inherit TForm Method New(cFormname) Constructor Method EditSelectedRecord(cForm) Method AddRecord() Method AddRecordCopy() Method RegisterControlHandlers() Method DeleteSelectedRecord() end class Естественно это приводит к ошибке.

gfilatov: Петр пишет: MidleX переопределяет класс TBrowse Большое спасибо! Удалось запустить пример Contact Manager после изменения скрипта с Вашей помощью Использовал HMG Ex build 42 и xHarbour 0.99.71 Но возник другой вопрос: Как убрать черное досовское окно при работе программы? В чем прикол - ведь я не использую терминал gtwin, только gtgui? Видимо, в самой библиотеке есть такое указание, поскольку их родной экзешник работает также с черным окном

Петр: Григорий, если бы Вы сбросили мне архив c изменениями, я б не терялся в догадках. Там вроде бы еще где-то ссылки на gtcgi есть. В общем нужно смотреть.



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