Форум » 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: PS SergKis пишет Переписать на клиента в mem:File (или на диск) поля ключи для Relation на осн. базу Забыл, что LetoDb (в отличии от LetoDbF) не имеет механизма SET RELATION ..., потому кроме ключевых и др. полей для локальной индикации, надо сохранять в выборке RecNo() записи на сервере и тогда исп. механизм TsBrowse блок кода oBrw:bOnDrawLine где делать переход на запись сервера, т.е. что то типа oBrw:bOnDrawLine := {|ob,nrow| nrow := (ob:cAlias)->REC_NO, ("ALS_SERVERA")->( dbGoto(nrow) ) } 3. Сделать выборку полностью на сервере ф-ей сервера, написав ее (автономный аналог :FilerFTS(...) или только для этого запроса). Выполнением этой ф-ии на сервере должен быть рез. файл, который можно показывать на клиенте открыв TsBrowse. Из за отсутсвия механизма Relation я перешел на LetoDbF - переход оч. простой получается - код почти не отличается от clipper. Т.к. осн. сервером исторически остался LetoDb (создание, модификация, ...), причем еще старый 2-х поточный, то LetoDbF пошел дополнением к LetoDb. Т.е. оба запущены одновременно (как daemon, а не сервисы), запускаются менеджером (простым на AutoIt 3 давно написанным) и менеджеры следят за наличием программ LetoDb и LetoDbf в памяти. Обе сборки серверов свои и в LetoDbf сделаны изменения по ini и log файлам, их названия LetoDbF.ini и LetoDbF.log. Тогда оба сервера лежат рядом и не конфликтуют по именам файлов. В ini для серверов исп. Share_Tables = 1 и разные порты

sashaBG: Спасибо за ответ Сергей! Попытаюсь написать функцию со стороны сервера, как вы рекомендовали. Если будут вопросы буду задавать :) Я еще не пробовал LetoDBf. Надо найти время попробовать! А он наверное лучше, раз вы на нем перешли! Всего доброго Всем!

SergKis: sashaBG Вот код, как есть, по выборке (за период, клиенты, объекты, ...) событий (охрана) с сервера, показываем ее, связывая со спр. объектов на сервере [pre2] * ----------------------------------------------------------------------------------- * STATIC FUNCTION wSelectEvent( cFile, oBuf ) * ----------------------------------------------------------------------------------- * LOCAL cForm := 'wListSel', i, t, o := Sys.Cargo, ot := o:oBaseText LOCAL cBrw := "oListSel", aHead, aSize, aPict, aAlign, aField, aFoot, aName LOCAL cTitl := " ", cTag LOCAL oBrw, aFont, oCol, nY, nX, nW, nH, nI, nN := 2 LOCAL cAlias := "SELGGMM" LOCAL nArea := Select() LOCAL cAlsO := "OBJ" LOCAL cObj := o:HBK+"obj" LOCAL cPeri := oBuf:cPer LOCAL cCapt := upper(ot:cSele) + CRLF + ot:cPer+": " + cPeri LOCAL lExclude := oBuf:lExclude LOCAL lRowId := Empty(oBuf:lRowID) LOCAL oColor := oKeyData() LOCAL nMaxObj, cMaxEvent, cMaxName, cMaxAdres, cMaxOwner, cTmp, nTmp, cVal IF !Empty(oBuf:cTim) ; cCapt += space(7) + ot:cTime + ": " + oBuf:cTim ENDIF IF ! m_DbUse(cObj, cAlsO, .T.) MsgStop("File not used !"+CRLF+cObj+".dbf", "ERROR") RETURN Nil ENDIF OrdSetFocus("KOD") GO TOP IF ! mDbUse(cFile, cAlias, .T., "DBFCDX") (cAlsO)->( dbCloseArea() ) //MsgStop("File not used !"+CRLF+cFile+".dbf", "ERROR") RETURN Nil ENDIF INDEX ON OBJECTNUM+R_DTM TAG KOD FOR Empty( R_EXC ) INDEX ON OBJECTNUM+R_DTM TAG EXCL FOR !Empty( R_EXC ) IF lExclude INDEX ON OBJECTNUM TAG OBJ FOR !Empty( R_EXC ) UNIQUE ELSE INDEX ON OBJECTNUM TAG OBJ FOR Empty( R_EXC ) UNIQUE ENDIF OrdSetFocus("OBJ") GO TOP nMaxObj := OrdKeyCount() ; i := 0 DO WHILE !EOF() ; oColor:Set( OBJECTNUM, int(i % 2) ) ; i++ ; SKIP ENDDO GO TOP cTag := iif( lExclude, "EXCL", "KOD" ) // OrdSetFocus(cTag) SET RELATION TO OBJECTNUM INTO &cAlsO GO TOP // посчитаем строки с max длиной cMaxEvent := cMaxName := cMaxAdres := cMaxOwner := "" /* DO WHILE !EOF() cTmp := Trim(EVENT) IF Len(cTmp) > Len(cMaxEvent) ; cMaxEvent := cTmp ENDIF cTmp := Trim( (cAlsO)->NAME ) IF Len(cTmp) > Len(cMaxName) ; cMaxName := cTmp ENDIF cTmp := Trim( (cAlsO)->OWNER ) IF Len(cTmp) > Len(cMaxOwner) ; cMaxOwner := cTmp ENDIF cTmp := Trim( (cAlsO)->ADDRESS ) IF Len(cTmp) > Len(cMaxAdres) ; cMaxAdres := cTmp ENDIF SKIP ENDDO GO TOP */ aFont := {"Normal", "FontBold", "FontBold", "FontBold"} aFoot := .T. DEFINE WINDOW &cForm ; TITLE cTitl ; MDICHILD FOCUSED NOMINIMIZE ; ON INIT NIL ; ON RELEASE ( (cAlias)->( dbCloseArea() ), ; (cAlsO)->( dbCloseArea() ), ; dbSelectArea(nArea), ; oMain:Enabled("BtnExcel", .F.), DoEvents() ) nY := nX := 0 nW := This.ClientWidth nH := This.ClientHeight (This.Object):Cargo:oBuf := oBuf (This.Object):Cargo:oBuf:cAlsObj := cAlsO DEFINE TBROWSE &cBrw OBJ oBrw AT nY,nX WIDTH nW HEIGHT nH CELL ; HEADERS aHead ; COLSIZES aSize ; PICTURE aPict ; ALIAS cAlias ; ENUMERATOR NIL ; JUSTIFY aAlign ; TRANSPARENT NIL ; SELECTOR NIL ; COLUMNS aField ; COLNAMES aName ; FOOTERS aFoot ; COLNUMBER { 1, 90 } ; COLEDIT NIL ; WHEN NIL ; VALUE NIL ; FONT aFont ; TOOLTIP NIL ; BACKCOLOR NIL ; FONTCOLOR NIL ; COLORS NIL ; ON GOTFOCUS NIL ; ON CHANGE NIL ; ON LOSTFOCUS NIL ; ON DBLCLICK NIL ; STYLE NIL ; ON HEADCLICK NIL ; FIXED COLSEMPTY GOTFOCUSSELECT LOCK ; BRUSH NIL ; LOADFIELDS ; ON INIT {|ob| ob:lNoHScroll := .F. } :DelColumn("DATETIME" ) ; :DelColumn("COLOR") ; :DelColumn("R_OWN") ; :DelColumn("R_EXC") :MoveColumn( :nColumn("R_DTM"), 3 ) :MoveColumn( :nColumn("EVENT"), 4 ) IF lRowId ; :DelColumn("ROWID") ENDIF :Cargo:nClr6_1 := -CLR_HRED // #define CLR_FOCUSB 6 1 // focused back :Cargo:nClr6_2 := -CLR_HBLUE // #define CLR_FOCUSB 6 2 // focused back :Cargo:nClr12_1 := -CLR_HBLUE // #define CLR_SELEB 12 1 // focused inactive (or selected) back :Cargo:nClr12_2 := -RGB(128,225,225) // #define CLR_SELEB 12 2 // focused inactive (or selected) back aField := {"OWNER"} //"NAME", "ADDRESS", , "PHONE", "PWD", "GRP1ROWID", "GRP2ROWID", "GRP3ROWID", "STATUS"} aName := {"OWNER"} //"NAME", "ADDRESS", , "PHONE", "PWD", "GRP1" , "GRP2" , "GRP3" , "STATUS"} aHead := {"OWNER"} //"NAME", "ADDRESS", , "PHONE", "PWD", "GRP1" , "GRP2" , "GRP3" , "STATUS"} FOR nI := 1 TO Len(aField) ADD COLUMN TO oBrw DATA FieldWBlock(aField[ nI ], select(cAlsO)) ; HEADER aHead[ nI ] FOOTER "" FIXED NAME &(aName[ nI ]) NEXT :SetColor( { 6}, { {|c,n,b| c := b:Cargo, iif( b:nCell == n, c:nClr6_1 , c:nClr6_2 ) } } ) // 6 , фона курсора :SetColor( {11}, { GetSysColor( COLOR_WINDOWTEXT ) } ) // 11, текста неактивного курсора :SetColor( {12}, { {|c,n,b| c := b:Cargo, iif( b:nCell == n, c:nClr12_1, c:nClr12_2 ) } } ) // 12, фона неактивного курсора oMain:Cargo:oBrw := oBrw This.Cargo:oBrw := oBrw This.Cargo:aOrder := {} :aBitMaps := { LoadImage("USS_32") } oCol := :GetColumn("ORDKEYNO") ; oCol:cPicture := "999 999 999" oCol:cFooting := {|nc,ob| nc := (ob:cAlias)->(OrdKeyCount()), iif( Empty(nc), '', Transform(nc, "999 999 999") ) } oCol:bDecode := {|cn| Val(cn) } oCol := :GetColumn("R_DTM") ; oCol:nAlign := DT_CENTER oCol:cPicture := "@R 9999-99-99 99:99:99" oCol:nWidth := oCol:ToWidth(subs(oCol:cPicture, 2)) oCol:bDecode := {|cd| Gmt2Utc(cd, .F., .T.) } oCol:cHeading := StrTran(ot:cDtms, "\", CRLF) oCol := :GetColumn("EVENT") ; oCol:cHeading := ot:cEvnt oCol:nWidth := oCol:ToWidth(45) //nI := int( oCol:ToWidth(cMaxEvent) / 2 ) + 20 //IF nI < oCol:nWidth ; oCol:nWidth := nI //ENDIF oCol := :GetColumn("OBJECTNUM"); oCol:cHeading := ot:cObj oCol:nFAlign := DT_CENTER oCol:cFooting := hb_ntos(nMaxObj) oCol:oCargo:nMaxObj := nMaxObj oCol:oCargo:oColor := oColor oCol:oCargo:lColor := nMaxObj > 1 oCol:oCargo:aColor := { GetSysColor( COLOR_BTNFACE ) } // { CLR_HGRAY } oCol:bDrawCell := {|obrw,ocel,ocol| Local o := ocol:oCargo, nClr, nTo, cKod, nElm IF o:lColor nClr := ocel:nClrBack nTo := ocel:nClrTo cKod := ocel:uValue nElm := o:oColor:Get(cKod, 0) ocel:nClrBack := iif( nElm > 0, o:aColor[ nElm ], nClr ) ocel:nClrTo := iif( nElm > 0, o:aColor[ nElm ], nTo ) ENDIF Return Nil } oCol := :GetColumn("OBJECTNAM"); oCol:nWidth := oCol:ToWidth(40) oCol:cHeading := ot:cName //nI := int( oCol:ToWidth(cMaxName ) / 2 ) + 20 //IF nI < oCol:nWidth ; oCol:nWidth := nI //ENDIF oCol := :GetColumn("OBJECTADR"); oCol:nWidth := oCol:ToWidth(40) oCol:cHeading := ot:cAddr //nI := int( oCol:ToWidth(cMaxAdres) / 2 ) + 20 //IF nI < oCol:nWidth ; oCol:nWidth := nI //ENDIF oCol := :GetColumn("OWNER") ; oCol:nWidth := oCol:ToWidth(35) oCol:cHeading := ot:cCust //nI := int( oCol:ToWidth(cMaxOwner) / 2 ) + 20 //IF nI < oCol:nWidth ; oCol:nWidth := nI //ENDIF nTmp := Max( :nHeightHead, 32 ) ADD SUPER HEADER TO oBrw FROM 1 TO :nColCount() TITLE cCapt HEIGHT nTmp COLOR CLR_BLUE FONT "FontBold" :aSuperHead[1][8] := :aBitMaps[1] //BITMAP "USS_24" //ADD SUPER HEADER TO oBrw FROM 1 TO 2 TITLE cPeri HEIGHT :nHeightHead COLOR CLR_BLUE FONT "FontBold" //ADD SUPER HEADER TO oBrw FROM 3 TO :nColCount() TITLE cCapt HEIGHT :nHeightHead COLOR CLR_BLUE FONT "FontBold" :nHeightCell += 2 ; :nFreeze := 2 + iif( lRowId, 0, 1 ) ; :nCell := :nFreeze + 1 END TBROWSE ON END {|ob| ob:SetNoHoles(), ob:SetFocus(), ob:Refresh() } ON KEY F1 ACTION NIL ON KEY ESCAPE ACTION ThisWindow.Release oMain:Cargo:cFocused := This.Name oMain:Cargo:oFocused := This.Object oMain:Enabled("BtnExcel", .T.) (This.Object):Event( 4, {|ow,ky,nMnu| LOCAL oBrw := ow:Cargo:oBrw LOCAL cBtn := "BtnExcel" LOCAL oCol, cFoot oMain:Enabled(cBtn, .F.) ; DO EVENTS oMain:StatusBar:Say(ot:cWait, 1) oBrw:Enabled(.F.) ; DO EVENTS IF nMnu == 1 ToExcel_1(oBrw) ELSEIF nMnu == 2 oCol := oBrw:GetColumn("OBJECTNUM") cFoot := oCol:cFooting oCol:cFooting := " " ToExcel_2(oBrw) oCol:cFooting := cFoot ELSEIF nMnu == 3 ToExcel_3(oBrw) ENDIF oMain:Enabled(cBtn, .T.) ; DO EVENTS oMain:StatusBar:Say("", 1) oBrw:Enabled(.T.) ; DO EVENTS Return Nil } ) END WINDOW RETURN Nil цветом выделены строки для работы с сервером [/pre2] код не отличается от обычной локальной работы. Есть одно правило SetRddDefault("LETO"), локальные как "DBFCDX", т.е.[pre2] IF ! mDbUse(cFile, cAlias, .T., "DBFCDX") (cAlsO)->( dbCloseArea() ) //MsgStop("File not used !"+CRLF+cFile+".dbf", "ERROR") RETURN Nil ENDIF [/pre2]


Andrey: SergKis пишет: Довел пример с исп. SBrowse до какой то кондиции: Пример ОЧЕНЬ классный... Чуток бы цвета исправить...

SergKis: Andrey пишет Чуток бы цвета исправить... Посмотри строки [pre2] oTsb:bBefore := {|obrw| // before END TSBROWSE Local oCol, oTsb oTsb := obrw:Cargo oCol := obrw:GetColumn("KOD") oCol:Cargo := oHmgData() oCol:Cargo:oColor := oTsb:oKod // keys unique oCol:Cargo:lColor := Len(obrw:aArray) > 1 oCol:Cargo:nColor := GetSysColor( COLOR_BTNFACE ) // Test_Window_2() исп. CLR_HGRAY oCol:bDrawCell := oTsb:bKodCell Return Nil } и в этих строках исп. obrw:SetColor(...) никто не мешает (я использовал по минимуму для курсора, см. Test_Window_2() ) oTsb:bAfter := {|obrw| // after END TSBROWSE Local oTsb, cWnd, nWnd, cTmp, lMsg, nMode, cMain oTsb := obrw:Cargo cWnd := obrw:cParentWnd nWnd := oTsb:nForm lMsg := oTsb:lPostMsg nMode := oTsb:nMode cMain := oMain:Name oMain:Cargo:aForm[ nMode ] := cWnd // ... obrw:AdjColumns() obrw:Refresh(.T.) SetProperty( cWnd, "Topmost", .F. ) IF lMsg cTmp := 'my_OnInit_SBrowse(' + hb_ntos(nMode) + ', "'+cWnd+'")' SetProperty( cWnd, "ONINIT", hb_MacroBlock(cTmp) ) ENDIF DO EVENTS Return Nil } [/pre2] блоки кода oTsb:bAfter := {|obrw| // after END TSBROWSE oTsb:bBefore := {|obrw| // before END TSBROWSE они твои, на выполнение подключаются как написано, уточнить можешь в SBrowse_Viewer(...) В блоке кода oTsb:bBefore не все колонки, только реальные, объявленные В блоке кода oTsb:bAfter уже все колонки SLECTOR и ORDKEYNO или ARRAYNO это надо помнить при написании PS. Дополнить код SBrowse_Viewer(...) предложениями\решениями - я только ЗА

Andrey: Григорий ! В примере SergKis пишет: Довел пример с исп. SBrowse до какой то кондиции: Не работают кнопки Печать и Эксель. Там же стандартный вызов [pre2]SBrowse( uAlias, {oTsb:cTitle, oTsb}, oTsb:bSetUp, , nW, nH, , oTsb:lModal, oTsb:lNumber, oTsb:lCenter )[/pre2] Работать должно сразу или нет ?

SergKis: gfilatov2002 Посмотрел примеры Tsb_Export, Tsb_Export_2. Все режимы с Excel ole у меня падают. Подключил к примеру hbxlsxml.lib - работает Пример https://TransFiles.ru/ag8zw

SergKis: gfilatov2002 Небольшая добавка [pre2] METHOD GotoRec( nRec, nRowPos ) CLASS TSBrowse ... SysRefresh() ELSEIF ::lIsArr hb_default( @nRowPos, ::nRowPos ) ::Gotop() ::Skip( nRec - 1 ) ::nRowPos := nRowPos ::Refresh() SysRefresh() ENDIF ... [/pre2]

gfilatov2002: SergKis пишет: Небольшая добавка Благодарю за предложение! Попробовал эту добавку в примере из папки samples\Advanced\Tsb_array_3 (повесил на клавишу F2 переход на конкретную позицию в массиве, например на 50-ю строку). Но результат перехода получился неудовлетворительным: блокируется движение вверх по клавише <стрелка вверх>, а также происходит в некоторых случаях "залипание" последней строки.

SergKis: gfilatov2002 Получился такой вариант (вроде не глючит у меня) [pre2] ELSEIF ::lIsArr hb_default( @nRowPos, ::nRowPos ) IF nRec > ::nLen nRec := ::nLen ENDIF IF nRec == ::nLen ::GoBottom() ELSE ::GoPos( nRec ) ::nAt := nRec ::nRowPos := iif( nRowPos > ::nRowCount(), ::nRowCount(), nRowPos ) ::lHitTop := ::lHitBottom := .F. ENDIF ::Refresh( ::nRowCount() < ::nLen ) IF ::bChange != NIL Eval( ::bChange, Self, 0 ) ENDIF SysRefresh() ENDIF [/pre2]

SergKis: gfilatov2002 Не знаю, что рыть, с ole не работал никогда, но это примеры hmg выдают Tsb_Export и Tsb_Export_2. Offis\Excel 2016 раньше было Ok! Логи ошибок тут https://TransFiles.ru/mnoow

Haz: SergKis пишет: Не знаю, что рыть, с ole не работал никогда, но это примеры hmg выдают Tsb_Export и Tsb_Export_2. Offis\Excel 2016 раньше было Ok! Если актуально будет после обеда посмотрю. Работа с оле всегда непредсказуемая. А Что автор примеров на эту тему думает?

gfilatov2002: Как и обещал, выложил финальную сборку 23.02 click here Также обновил Unicode версию библиотеки по старому адресу для Сергея

SergKis: Haz пишет Если актуально будет после обеда посмотрю. Не могу сказать об актуальности, но не так давно, на этой же PC все работало, валится у меня одного или у кого то еще ? У меня исп. hbxlsxml.lib для форм. xml\xls и libXL для чтения данных. С xml Excel работает, с libXL тоже.

Haz: SergKis пишет: валится у меня одного или у кого то еще Запустил Tsb_Export все работает, никаких ошибок тоже Excel 2016. Правда с уже успел обновиться на сборку 23.02 Не пойму куда смотреть

Andrey: Haz пишет: Не пойму куда смотреть Пример ниже который свалиться если нажать на кнопке Эксель... SergKis пишет: Довел пример с исп. SBrowse до какой то кондиции: https://TransFiles.ru/ottjz - смена типа окон S\C и немного управления - смена вида курсора - подсветка одинаковых ключей (группы) в просмотре Мои предположения - если 1 поле в бровсе логическое, то при вызове Эксель - оля падает...

SergKis: Andrey пишет если 1 поле в бровсе логическое, то при вызове Эксель - оля падает... Всегда делаю так aYesNo := {"Yes", "No"} всегда можно параметром или еще как поменять aYesNo := {"Да", "Нет"} aYesNo := {"М", "Ж"} aYesNo := {"Открыто", "Закрыто"} ... для лог. колонки меняю .T. - aYesNo[1], .F. - aYesNo[2], самый простой вариант cValToChsr(...)

SergKis: Haz пишет Запустил Tsb_Export все работает, никаких ошибок тоже Excel 2016. Правда с уже успел обновиться на сборку 23.02 Не пойму куда смотреть Игорь, никуда не смотри, на обновленной версии у меня так же валится Буду считать, что крякнулся Excel у меня, с Word работает Ok!

Haz: Andrey пишет: Пример ниже который свалиться если нажать на кнопке Эксель... Проблема не в примере , проблема в h_tbrowse.prg. Достаточно в demo.hbp добавить строку [pre2] # Keys compile #-prgflag=-w0 -es1 -prgflag=-w2 -es1 # Enable multi/single-thread Harbour VM -mt # Incremental-compilation mode -inc # folder where are all * .obj -workdir=OBJ # Name EXE-module -odemo # to list all * .prg demo.prg h_tbrowse.prg # paths to the main and extension *.Lib -lminigui #-lhbmemio [/pre2] Все становится видно.

Haz: Haz пишет: Проблема не в примере , проблема в h_tbrowse.prg. Достаточно в demo.hbp добавить строку в исходниках метода METHOD ExcelOle() есть строки [pre2] IF ::lDrawSuperHd FOR nCol := 1 TO Len( ::aSuperHead ) nVar := iif( lSelector, 1, 0 ) uData := iif( ValType( ::aSuperhead[ nCol, 3 ] ) == "B", Eval( ::aSuperhead[ nCol, 3 ] ), ; ::aSuperhead[ nCol, 3 ] ) oSheet:Cells( nLine, ::aSuperHead[ nCol, 1 ] - nVar ):Value := uData cRange := HeadXls( ::aSuperHead[ nCol, 1 ] - nVar ) + LTrim( Str( nLine ) ) + ":" + ; HeadXls( ::aSuperHead[ nCol, 2 ] - nVar ) + LTrim( Str( nLine ) ) oSheet:Range( cRange ):Borders():LineStyle := xlContinuous oSheet:Range( cRange ):HorizontalAlignment := xlHAlignCenterAcrossSelection oRange := oSheet:Range( cRange ) IF hFont != NIL aFont := GetFontParam( hFont ) oRange:Font:Name := aFont[ 1 ] oRange:Font:Size := aFont[ 2 ] oRange:Font:Bold := aFont[ 3 ] ENDIF NEXT nStart := nLine++ ENDIF [/pre2] вот тут и идет обращение к oSheet:Cells() где номер колонки равен 0 из за этого ОЛЕ и валится как быстрая правка вместо nVar := iif( lSelector, 1, 0 ) сделать nVar := 0 тогда все работает корректно. Ну а дальше разбираться с ::lSelector ( осознанием его практической бесполезности ) и правкой метода.



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