Форум » GUI » TsBrowse в Минигуи (продолжение) » Ответить

TsBrowse в Минигуи (продолжение)

Vlad04: TsBrows определяется в виде строки ПАРМЕТРОВ объекта и их значений К примеру [quote] DEFINE TBROWSE oBrw2 ; AT 60,450 ; ALIAS cAlias ; OF Form1 ; WIDTH 330 ; HEIGHT 340 ; FONT "Verdana" ; SIZE 9 ; ON DBLCLICK CopyRec(); ON GOTFOCUS fModelo_Hab(2) ; AUTOFILTER ; CELLED EDIT; VALUE nRec; GRID [/quote] Здесь я собрал параметры из разных tBrows Можно или нет и какие парметры заменить выражением ( и каким) ? oBrw2:.... oBrw2:....

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

Andrey: Haz пишет: теперь с форума будем собирать идеи по наполнению класса CLASS TSBcell А можно сделать так, чтобы при наведении мышкой на колонку с определённым номером, в ячейке всплывала подсказка ? Как у всех объектов TOOLTIP, или как в примере MiniGUI\SAMPLES\BASIC\COMM_2\demo-main.prg функция My_Message()

SergKis: Andrey пишет:А можно сделать так ... Как у всех объектов TOOLTIP надо внести изменения, на мой взгляд:[pre2] METHOD New( cControlName, nRow, nCol, nWidth, nHeight, bLine, aHeaders, aColSizes, cParentWnd, ; ... было ... EndIf SetToolTip ( ::hWnd , ::cToolTip , hToolTip ) //JP V90 IF nValue > 0 .AND. nValue <= ::nLen ... стало ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, 0) // 0 - new method If Valtype(ctooltip) != "C" ctooltip := "" EndIf EndIf SetToolTip ( ::hWnd , ctooltip , hToolTip ) //JP V90 IF nValue > 0 .AND. nValue <= ::nLen ... METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse ... было If ( lHeader := ::GetTxtRow( nRowPix ) == 0 ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) If nToolTip != nColumn SetToolTip ( ::hWnd , ::aColumns[ nColumn ]:cToolTip , hToolTip ) SysRefresh() EndIf nToolTip := nColumn Else If nToolTip != 0 SetToolTip ( ::hWnd , ::cToolTip , hToolTip ) SysRefresh() endif nToolTip := 0 EndIf ... стало Local ctooltip ... If ( lHeader := ::GetTxtRow( nRowPix ) == 0 ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) If nToolTip != nColumn SetToolTip ( ::hWnd , ::aColumns[ nColumn ]:cToolTip , hToolTip ) SysRefresh() EndIf nToolTip := nColumn Else If nToolTip != 0 ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, nColumn) If Valtype(ctooltip) != "C" ctooltip := "" EndIf EndIf SetToolTip ( ::hWnd , ctooltip , hToolTip ) SysRefresh() endif nToolTip := 0 EndIf ... [/pre2]

SergKis: Haz пишет:будем собирать идеи по наполнению класса CLASS TSBcell просится [pre2] METHOD Desktop() CLASS TSBcell ::nRow := 0 ::nCol := 0 ::nWidth := GetDesktopWidth() ::nHeight := GetDesktopHeight() - GetTaskBarHeight() RETURN Self METHOD App() CLASS TSBcell ::Window() RETURN Self METHOD Window( hWnd ) CLASS TSBcell Default hWnd := _HMG_MainHandle ::nRow := GetWindowRow(hWnd) ::nCol := GetWindowCol(hWnd) ::nWidth := GetWindowWidth(hWnd) ::nHeight := GetWindowHeight(hWnd) RETURN Self METHOD Client( hWnd ) CLASS TSBcell Local actpos := { 0, 0, 0, 0 } Default hWnd := _HMG_MainHandle GetClientRect(hWnd, actpos) ::nCol := actpos[1] ::nRow := actpos[2] ::nWidth := actpos[3]-actpos[1] ::nHeight := actpos[4]-actpos[2] RETURN Self [/pre2] тогда oDesktop := TSBcell():New():Desktop() DEFINE WINDOW ... AT oDesktop:Row, oDesktop:Col ... oAppWin := TSBcell():New():App() oAppCli := TSBcell():New():Client() oFormCli := TSBcell():New():Client(GetFormHandle("Form_1")) ... может название не TSBcell ?


SergKis: SergKis пишет:надо внести изменения Уточненные (проверил) изменения: [pre2] METHOD New( cControlName, nRow, nCol, nWidth, nHeight, bLine, aHeaders, aColSizes, cParentWnd, ; ... было ... EndIf SetToolTip ( ::hWnd , ::cToolTip , hToolTip ) //JP V90 IF nValue > 0 .AND. nValue <= ::nLen ... стало ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self) EndIf SetToolTip ( ::hWnd , ctooltip , hToolTip ) //JP V90 IF nValue > 0 .AND. nValue <= ::nLen ... METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse ... было If ( lHeader := ::GetTxtRow( nRowPix ) == 0 ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) If nToolTip != nColumn SetToolTip ( ::hWnd , ::aColumns[ nColumn ]:cToolTip , hToolTip ) SysRefresh() EndIf nToolTip := nColumn Else If nToolTip != 0 SetToolTip ( ::hWnd , ::cToolTip , hToolTip ) SysRefresh() endif nToolTip := 0 EndIf ... стало Local ctooltip ... If ( lHeader := ::GetTxtRow( nRowPix ) == 0 ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) If nToolTip != nColumn ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, nColumn) EndIf SetToolTip ( ::hWnd , ctooltip , hToolTip ) SysRefresh() EndIf nToolTip := nColumn Else If nToolTip != nColumn ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, nColumn) EndIf SetToolTip ( ::hWnd , ctooltip , hToolTip ) SysRefresh() endif nToolTip := nColumn EndIf ... пример oBrw:cToolTip := {|oBr,nNr| "My TsBrowse tooltip "+str(nNr,3)+str(oBr:nAt,5) } oBrw:aColumns[1]:cToolTip := {|oBr,nNr| "My columns Header tooltip "+str(nNr,3)+str(oBr:nAt,5) } oBrw:aColumns[2]:cToolTip := {|oBr,nNr| "My columns Header tooltip "+str(nNr,3)+str(oBr:nAt,5) } ... или bBlock := {|oBr,nNr| "My columns Header tooltip "+str(nNr,3)+str(oBr:nAt,5) } aEval(oBrw:aColumns, {|oCol| oCol:cToolTip := bBlock }) [/pre2]

Haz: SergKis пишет: oDesktop := TSBcell():New():Desktop() Сергей, это больше на клаасс Windows похоже. Так мы придем к HwGui ( что тоже не плохо ) и будет oWin := Win():New() oWin:name := "Form_1" oWin:Type := 'child' и т.д.

SergKis: Haz oWin - больший класс и его сост. частью является TSBcell (название не очень подходит) в данном случае 4 значения, которые можно заполнить методами и в окнах проще писать (часть кода скрыта в методе) oA := TSBcell():New():Desktop() // можно в стиле VO: oA := TSBcell{}:Desktop() oA:nRow, oA:nCol ... чем Application.Row ... для Desktop аналогично

SergKis: PS можно сгородить ф-ии Func oDesktop() Return TSBcell():New():Desktop() ... и останемся в стиле MiniGui

Haz: SergKis пишет: TSBcell (название не очень подходит) подходит к ячейке бровса , как дочернего класса этого бровса, в твоем случае тогда класс назвать можно :WinRect( hWnd )

SergKis: Haz пишет: назвать можно :WinRect( hWnd ) Согласен, лучше не смешивать.

Andrey: Что то вылетает у меня функция, при повторном входе в бровс ! Делаю так: // по правой кнопки мышки - контекстное меню TBROWSE DEFINE CONTEXT MENU CONTROL oBrw1 ...... MENUITEM "Current record / Текущая запись: " NAME MYTABLETEXT // строка 533 MENUITEM "Record number / Номер записи: " NAME MYTABLERECNO ... END MENU При повторном входе в эту функцию - вылет программы с ошибкой: Error BASE/1132 Переполнение массива: Неверное количество аргументов Called from _GETMENUIDS(648) Called from MENUCAPTIONSET(546) Called from CHANGETABLE(533) Called from (b)MYCREATETABLE(431) Я так подозреваю, что нужно чистить (удалять) объявленные переменные NAME MYTABLETEXT и NAME MYTABLERECNO ? Или что то другое нужно ? P.S. простое удаление (после закрытии формы) не помогает... RELEASE MYTABLETEXT RELEASE MYTABLERECNO Вылетает на строке 648: x := GetControlIndex ( ItemName , FormName ) MsgLog(x, ItemName , FormName) h := _HMG_aControlPageMap [ x ] // строка 648 В отладочном файле _MsgLog.txt следующее: 7 MYTABLETEXT Form_Table45549 8 MYTABLERECNO Form_Table45549 0 MYTABLETEXT Form_Table47864

Andrey: Andrey пишет: А можно сделать так, чтобы при наведении мышкой на колонку с определённым номером, в ячейке всплывала подсказка ? Как у всех объектов TOOLTIP, или как в примере MiniGUI\SAMPLES\BASIC\COMM_2\demo-main.prg функция My_Message() Так как - это можно реализовать ? А то писали-писали, а к чему пришли так и не понял. Или результат в новой версии МиниГуи ждать ?

gfilatov2002: Andrey пишет: Или результат в новой версии МиниГуи Именно так - уже скоро. Сегодня выпустил pre-release версию новой сборки На всякий случай мой контрольный пример для проверки этой фичи ниже: [pre2]rocedure Brw_5() IF !_IsControlDefined ("oBrw5","Form_1") Select("Test") @ 10,630 TBROWSE oBrw5 ; ALIAS "Test" ; OF Form_1 WIDTH 250 HEIGHT 380 ; CELLED ; HEADERS "Code","First","Last","Birth","Bio" ; WIDTHS 50,150,150,100,200 ; FIELDS FieldWBlock( "Code", Select() ),Test->First,Test->Last,FieldWBlock( "Birth", Select() ),FieldWBlock( "Bio", Select() ) ; EDITABLE ; READONLY {.f.,.t.,.t.} ; BACKCOLOR YELLOW ; FONTCOLOR BLUE ; TOOLTIP "TsBrowse - Standard definition" ; ;// MESSAGE " Browse DataBase 2 " ; AUTOSEARCH oBrw5:lNoResetPos := .F. oBrw5:lPickerMode := .F. oBrw5:cToolTip := {|oBr,nCol,nRow| "My TBrowse tooltip. Col ="+str(nCol,3)+" Row ="+str(nRow,3) } aEval(oBrw5:aColumns, {|oCol| oCol:cToolTip := {|oBr,nCol,nRow| "My column tooltip. Col ="+str(nCol,3)+" Row ="+str(nRow,3) } }) endif RETURN [/pre2]

Andrey: Столкнулся с такой непоняткой... Создаю таблицу: DEFINE TBROWSE oBrw1 ; ................ MyCreateTable(....) END TBROWSE SetNoHoles( oBrw1 ) // убрать дырку внизу таблицы перед подвалом MyCreateTableMenu(....) В функции MyCreateTable(....) задаю: 1) цвета // -------------------- Установить цвета в таблице ------------------------------ oBrw1:SetColor( { 1}, { { || CLR_BLACK } } ) // 1 , текста в ячейках таблицы ............ oBrw1:SetColor( { 6}, { { || { 4915199,255} } } ) // 6 , фона курсора 2) создаю столбцы ADD COLUMN TO oBrw1 HEADER "1-столбец" ; ............ // и т.д. 3) и там все остальные назначения... // -------------- Fixed cursor , фиксированный курсор --------- For nI := 1 To oBrw1:nColCount() oBrw1:aColumns[nI]:lFixLite := TRUE Next Пытаюсь после этого считать цвет 6 - фона курсора oCol := oBrw1:aColumns[ 1 ] aColor := oCol:aColorsBack aCursorBC := aColor[6] oBrw1:SetColor( { 6 }, { { |a,b,c| IF( c:nCell == b, aCursorBC ,; { CLR_GRAY, CLR_WHITE } ) } } ) Получаю в aCursorBC чёрный цвет... Почему ? Что нужно ещё сделать для инициализации цвета ? Если цвета поставить ниже, то 6-цвет получается нормально...

Vlad04: Уажаемые ГУРУ! Не могли бы Вы для полноты дополнить некоторые примеры TsBrowse следующим:- это кнопки навигации , добавить , удалить , изменить режим(непосредственное редактирование разрешено - запрещено), вызов контекстного меню. Представляют интерес примеры на основе - Tsb_filter,Tsb_sbrowse (или подобные) , т.е. те, где TsBrows формируется отдельной процедурой.

Andrey: Vlad04 пишет: это кнопки навигации , добавить , удалить , изменить режим(непосредственное редактирование разрешено - запрещено), вызов контекстного меню. Смотри пример SAMPLES\Advanced\Tsb_config Могу дать на его базе более продвинутый пример из двух TsBrowse (кнопка цвет) - https://cloud.mail.ru/public/2CHr/h9u2vn7JR Вот еще один пример с картинками и продвинутым контекстным меню - https://cloud.mail.ru/public/2s2Z/gmH9d5VWD

Vlad04: Примеры хорошие, но это не то.Речь шла о примерах, где TsBrows формируется отдельной процедурой, а в этих - все в одной и создание окна и создание Бровса в нем. Ниже - твой пример, где я добавил кнопки навигации.При добавлении новой записи экран не обновляется. TsBrows с навигацией

SergKis: Vlad04 пишет:При добавлении новой записи экран не обновляется. на базе Tsb_addrecord AddRecord(obrw) сделал похоже (в примере) - работает [pre2] ******************** Static Procedure Append(obrw) ******************** (obrw:cAlias)->( DbAppend() ) (obrw:cAlias)->( FieldPut( 1, Procname()+": "+strzero(RecNo(),7 )+str(procline(), 7) ) ) (obrw:cAlias)->( FieldPut( 2, RecNo() ) ) obrw:GoToRec( RecNo() ) obrw:SetFocus() Return [/pre2] или надо как то иначе ?

Vlad04: Это учел. На основе Tsb_addrecord другой пример Tsb_addrecord2 Здесь возникают ошибки, неувязки в Procedure Edit(met,cForm,oBrw,cAlias) // &(cForm).readRec.Visible:=.t. // &(cForm).readRecN.Visible:=.f. Здесь должна меняться видимость картинок. И в STATIC FUNCTION MyKeyAction(l_Key,cForm,oBrw, cParent) // &(cForm).STATUSBAR.Item(1):='Точный поиск:'+sSeek //'Точный поиск:'+

SergKis: Vlad04 [pre2] CASE l_key>32.and.l_key<254 sl_key := KeyToChar(l_key ) // моя функция обработки клавиш / my processing function keys sSeek:=sSeek+sl_key nRec:=Recno() Seek sSeek if Found() nRec := RecNo() endif oBrw:GotoRec(nRec) [/pre2] только, на мой взгляд, проще сделать GetBox вместе с tsb, скрыть его, на lostfocus\return\esc повесить переход на tsb и скрытие, а на onchange подвод или scope, show GetBox делать в координатах ячейки в Footer tsb

SergKis: PS подсветку того, что набрали посимвольно , все равно надо делать (нужно место), а GetBox и с этим справится

Andrey: SergKis пишет: проще сделать GetBox вместе с tsb Это действительно проще. В примере который я дал выше - есть такой метод....

SergKis: Andrey пишет:есть такой метод.... Я такой имел ввиду: [pre2] /* * MINIGUI - Harbour Win32 GUI library Demo * */ #include "minigui.ch" #include "tsbrowse.ch" Memvar oBrw Static Ledit:=.F.,nOrd :=0,sSeek:='' *----------------------------------- PROCEDURE Main *----------------------------------- LOCAL i,nArea SET SOFTSEEK ON SET DELETED ON REQUEST DBFCDX , DBFFPT Use STREET Via "DBFCDX" ALIAS BASE shared New if !File('STREET.cdx') INDEX ON Upper(NAME) Tag NAME endif dbSetOrder(1) nArea:=Select() DEFINE WINDOW win_1 AT 0, 0 WIDTH 1200 HEIGHT 700 ; MAIN TITLE "TSBrowse Add Record Demo" NOMAXIMIZE NOSIZE @ 5,10 BUTTON ttop PICTURE "First" TOOLTIP "Первая " ACTION TbMove(1,obrw,nArea) WIDTH 20 HEIGHT 18 // (EkspeD->(DbGoTop()),EkspeDitor.Brw_1.Value := EkspeD->(RecNo())) @ 5,10+20 BUTTON prev PICTURE "prior" TOOLTIP "Предыдущая" ACTION TbMove(3,obrw,nArea) WIDTH 20 HEIGHT 18 @ 5,10+40 BUTTON nnext PICTURE "next" TOOLTIP "Следующая " ACTION TbMove(4,obrw,nArea) WIDTH 20 HEIGHT 18 @ 5,10+60 BUTTON bott PICTURE "Last" TOOLTIP "Последняя " ACTION TbMove(6,obrw,nArea) WIDTH 20 HEIGHT 18 @ 5,10+100 BUTTON delRec PICTURE "Delete" TOOLTIP "Удалить !" ACTION {||DeleteRecall(obrw,nArea), oBrw:Refresh(.t.) } WIDTH 20 HEIGHT 18 @ 5,10+120 BUTTON readRec PICTURE "editNo" TOOLTIP "Редактированиe " ACTION Edit(1,'win_1',obrw,nArea) WIDTH 20 HEIGHT 18 // (EkspeDitor.Brw_1.ALLOWEDIT:=.T.) @ 5,10+120 BUTTON readRecN PICTURE "edit" TOOLTIP "Изменить " ACTION Edit(2,'win_1',obrw,nArea) WIDTH 20 HEIGHT 18 // (EkspeDitor.Brw_1.ALLOWEDIT:=.T.) @2,10+180 BUTTON BRUN CAPTION "Add Record" ACTION AddRecord( obrw,nArea ) DEFAULT DEFINE STATUSBAR STATUSITEM '' WIDTH 20 END STATUSBAR OpenBrows( "oBrw", 'win_1', 30, 2, win_1.Width-20, win_1.Height-95,nArea ) // 'BASE' // oBrw:bKeyDown := { | nKey | MyKeyAction(nKey,oBrw,'win_1'), lOk := nKey != VK_ESCAPE } oBrw:bKeyDown := { | nKey | MyKeyAction(nKey,'win_1',oBrw,'win_1'), lOk := nKey != VK_ESCAPE } @ 0, 0 GETBOX MyFind HEIGHT 10 WIDTH 10 VALUE "" ; ON LOSTFOCUS ( win_1.MyFind.Hide, win_1.oBrw.SetFocus ) ; ON CHANGE ( MyFind(oBrw) ) oBrw:SetFocus() END WINDOW CENTER WINDOW win_1 ACTIVATE WINDOW win_1 RETURN *-------------------------------- FUNCTION OpenBrows( cBrw, cParent, nRow, nCol, nWidth, nHeight, cAlias ) Public &cBrw DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS cAlias ; OF &cParent ; WIDTH nWidth ; HEIGHT nHeight ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 :SetAppendMode( .F. ) :SetDeleteMode( .F. ) :lNoHScroll := .T. :lCellBrw := .F. ADD COLUMN TO obrw HEADER "Name" FOOTER "" ; SIZE 600 ; DATA FieldWBlock( "name", Select( "base" ) ) EDITABLE ADD COLUMN TO obrw HEADER "SOCR" FOOTER "" ; SIZE 350 ; DATA FieldWBlock( "SOCR", Select( "base" ) ) EDITABLE ADD COLUMN TO obrw HEADER "CODE" FOOTER "" ; SIZE 400 ; DATA FieldWBlock( "CODE", Select( "base" ) ) EDITABLE &cBrw:nHeightCell += 6 &cBrw:nHeightHead += 14 &cBrw:nHeightFoot := &cBrw:nHeightHead &cBrw:nWheelLines := 1 &cBrw:lDrawFooters := .T. &cBrw:lNoHScroll := .T. // LoadFields( cBrw, cParent ) END TBROWSE // !!! RETURN Static Function MyFind( oBrw ) Local cVal := win_1.MyFind.Value If ! empty(cVal) (oBrw:cAlias)->( dbSeek(upper(trim(cVal))) ) oBrw:GotoRec((oBrw:cAlias)->( RecNo()) ) EndIf Return nil *----------------------------------- PROCEDURE AddRecord( obrw ,cAlias) *----------------------------------- Local nRec:=Recno() Local nArea := Select() Select(cAlias) /* DbAppend() nRec:=Recno() obrw:GoToRec( nRec ) oBrw:Refresh(.t.) */ (obrw:cAlias)->( DbAppend() ) (obrw:cAlias)->( FieldPut( 1, Procname()+": "+strzero(RecNo(),7 )+str(procline(), 7) ) ) (obrw:cAlias)->( FieldPut( 3, Str(RecNo(),5) ) ) obrw:GoToRec( RecNo() ) obrw:SetFocus() Select(nArea) RETURN /*-------------------------------- */ FUNCTION TbMove(met,oBrw,cAlias) Local nArea := Select() Select(cAlias) DO CASE CASE met == 1 oBrw:GoTop() CASE met == 2 oBrw:PageUp() CASE met == 3 oBrw:GoUp() CASE met == 4 oBrw:GoDown() CASE met == 5 oBrw:PageDown() CASE met == 6 oBrw:GoBottom() ENDCASE oBrw:Refresh(.t.) Select(nArea) RETURN NIL *---------------------------------- Static Procedure DeleteRecall(obrw,cAlias) Local nArea := Select() Select(cAlias) if MsgOkCancel('Запись будет удалена! Удалить?','Удаление записи!') = .T. if ( Rlock() ) ( DbDelete()) ( dbUnlock() ) oBrw:Refresh(.t.) endif end Select(nArea) Return Static Procedure Edit(met,cForm,oBrw,cAlias) ******************** Local nArea := Select() Select(cAlias) if met = 1 // oBrw:lCellBrw := .t. // выделена строка или ячейка // Ledit := .t. // &(cForm).readRec.Visible:=.t. // &(cForm).readRecN.Visible:=.f. else // oBrw:lCellBrw := .f. // выделена строка или ячейка // Ledit := .f. // &(cForm).readRec.Visible:=.t. // &(cForm).readRecN.Visible:=.f. endif // &(cForm).Brw_1.SetFocus oBrw:Refresh(.t.) Select(nArea) Return //------------------------------------------------------------------------------ Function KeyToChar( nVirtKey ) //------------------------------------------------------------------------------ LOCAL i, cRetChar := "" LOCAL nKeyboardMode := GetKeyboardMode() LOCAL lShift := CheckBit( GetKeyState( 16 ), 32768 ) LOCAL aKeysNumPad := { 96,97,98,99,100,101,102,103,104,105,106,107,109,110,111 } LOCAL cKeysNumPad := "0123456789*+-./" LOCAL aKeys1 := { 192,189,187,219,221,220,186,222,188,190,191 } LOCAL cKeys1US := "`-=[]\;',./" LOCAL cKeys1ShiftUS := '~_+{}|:"<>?' LOCAL cKeys1RU := "Ё-=ХЪ\ЖЭБЮ." LOCAL cKeys1ShiftRU := "Ё_+ХЪ/ЖЭБЮ," LOCAL cKeys2US := "1234567890QWERTYUIOPASDFGHJKLZXCVBNM " LOCAL cKeys2ShiftUS := "!@#$%^&*()QWERTYUIOPASDFGHJKLZXCVBNM " LOCAL cKeys2RU := "1234567890ЙЦУКЕНГШЩЗФЫВАПРОЛДЯЧСМИТЬ " LOCAL cKeys2ShiftRU := '!"№;%:?*()ЙЦУКЕНГШЩЗФЫВАПРОЛДЯЧСМИТЬ ' i := ascan( aKeysNumPad, nVirtKey ) if i > 0 RETURN substr( cKeysNumPad, i, 1 ) endif i := ascan( aKeys1, nVirtKey ) if i > 0 if nKeyboardMode == 1033 // US if lShift cRetChar := substr( cKeys1ShiftUS, i, 1 ) else cRetChar := substr( cKeys1US, i, 1 ) endif elseif nKeyboardMode == 1049 // RU if lShift cRetChar := substr( cKeys1ShiftRU, i, 1 ) else cRetChar := substr( cKeys1RU, i, 1 ) endif endif RETURN cRetChar endif i := at( chr( nVirtKey ), cKeys2US ) if i > 0 if nKeyboardMode == 1033 // US if lShift cRetChar := substr( cKeys2ShiftUS, i, 1 ) else cRetChar := substr( cKeys2US, i, 1 ) endif elseif nKeyboardMode == 1049 // RU if lShift cRetChar := substr( cKeys2ShiftRU, i, 1 ) else cRetChar := substr( cKeys2RU, i, 1 ) endif endif endif RETURN cRetChar ************************** STATIC FUNCTION MyKeyAction(l_Key,cForm,oBrw, cParent) Local sL_key:='',nRec:=0 Local oCell, hBrw, nRow, oGet, uRet //MsgInfo('l_key='+Str(l_key)) Select(oBrw:cAlias) If Indexord() =0 Return endif DO CASE // CASE l_key==8 //VK_BACK //.or.l_key>31.and.l_key<242 // if l_key==VK_BACK // if Len(sSeek) > 0 // sSeek:=left(sSeek,Len(sSeek)-1) // &(cForm).STATUSBAR.Item(1):=sSeek // endif // else CASE l_key>32.and.l_key<254 // sl_key := KeyToChar(l_key ) // моя функция обработки клавиш / my processing function keys oCell := oBrw:GetCellInfo() hBrw := oBrw:hWnd nRow := GetWindowHeight(hBrw) + win_1.oBrw.Row - oBrw:nHeightFoot win_1.MyFind.Row := nRow win_1.MyFind.Col := oCell:nCol win_1.MyFind.Width := oCell:nWidth win_1.MyFind.Height := oBrw:nHeightFoot win_1.MyFind.Show() win_1.MyFind.SetFocus() win_1.MyFind.Value := space(10) _PushKey(l_key) uRet := .F. // обработка завершена (nil - продолжит tsb) ENDCASE Return uRet #pragma begindump #include <windows.h> #include "hbapi.h" HB_BOOL flag_hhk = FALSE; HB_BOOL PAUSE_hhk = FALSE; HHOOK hhk = NULL; HB_LONG VK_PRESIONADO = 0; HB_LONG VK_lParam = 0; HB_FUNC( GETKEYBOARDMODE ) { HKL kbl; HWND CurApp; DWORD idthd; int newmode; CurApp=GetForegroundWindow(); idthd=GetWindowThreadProcessId(CurApp,NULL); kbl=GetKeyboardLayout(idthd); newmode=(int)LOWORD(kbl); hb_retnl(newmode); } #pragma enddump [/pre2]

SergKis: PS пропустил после @ 0, 0 GETBOX MyFind ... win_1.MyFind.Hide

Vlad04: SergKis Поиск и фунукцию обработки клавиатуры прикрутил из другого примера ( Окно и бровс в одной функции), там все нормально работает. В этом примере ругается на &(cForm), так как надо чтобы форма реагирвала на события.

Vlad04: SergKis ок! Нормальный поиск

SergKis: Vlad04 Совет. используйте блоки код (параметры), как прописаны их вызовы в tsb, проще будет и проблем меньше, например [pre2] METHOD KeyDown( nKey, nFlags ) CLASS TSBrowse ... If ::bUserKeys != Nil uReturn := Eval( ::bUserKeys, nKey, nFlags, Self ) If uReturn != Nil .and. ValType( uReturn ) == "N" .and. uReturn < 200 // interpreted as a virtual key code to nKey := uReturn // change the original key pressed ElseIf uReturn != Nil .and. ValType( uReturn ) == "L" .and. ! uReturn ::nUserKey := 255 // want to inhibit the KeyDown and KeyChar Methods for key pressed Return 0 EndIf EndIf ... [/pre2] т.е. вместо oBrw:bKeyDown := { | nKey | MyKeyAction(nKey,'win_1',oBrw,'win_1'), lOk := nKey != VK_ESCAPE } делать oBrw:bKeyDown := { | nKey,nFlags,oBrw| MyKeyAction(nKey,nFlag,oBrw) } где Funct MyAction(l_key, nFlags, oBrw ) Local cForm := oBrw:cParentWnd Local cBrw := oBrw:cControlName Local hBrw := oBrw:hWnd ... см. свойства tsb

SergKis: PS по инерции копипастил не oBrw:bKeyDown, на мой взгляд, а oBrw:bUserKeys := ...

Vlad04: SergKis Не сочтите за наглость, не могли бы вы подправить ПРИМЕР в Вашей редакции. Думаю, многим было бы полезно. Спасибо.

SergKis: Vlad04 пишет: подправить ПРИМЕР в Вашей редакции. тут [pre2] /* * MINIGUI - Harbour Win32 GUI library Demo * */ #include "minigui.ch" #include "tsbrowse.ch" *----------------------------------- PROCEDURE Main *----------------------------------- LOCAL i,nArea LOCAL nY := 5, nX := 10 LOCAL nW := 24, nH := 24 SET SOFTSEEK ON SET DELETED ON REQUEST DBFCDX , DBFFPT Use STREET Via "DBFCDX" ALIAS BASE shared New if !File('STREET.cdx') INDEX ON Upper(NAME) Tag NAME endif dbSetOrder(1) DEFINE WINDOW win_1 AT 0, 0 WIDTH 1200 HEIGHT 700 ; MAIN TITLE "TSBrowse Add Record Demo" NOMAXIMIZE NOSIZE @ nY, nX BUTTON ttop PICTURE "First" TOOLTIP "Первая " ; ACTION ( oBrw:Gotop() , oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON prev PICTURE "prior" TOOLTIP "Предыдущая" ; ACTION ( oBrw:GoUp() , oBrw:SetFocus() ) WIDTH nH HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON nnext PICTURE "next" TOOLTIP "Следующая " ; ACTION ( oBrw:GoDown() , oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON bott PICTURE "Last" TOOLTIP "Последняя " ; ACTION ( oBrw:GoBottom() , oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW + 40 @ nY, nX BUTTON delRec PICTURE "Delete" TOOLTIP "Удалить !" ; ACTION ( oBrw:DeleteRow(), oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON readRec PICTURE "editNo" TOOLTIP "Редактированиe " ; ACTION ( MsgBox(_HMG_ThisControlName, _HMG_ThisFormName), oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON readRecN PICTURE "edit" TOOLTIP "Изменить " ; ACTION ( MsgBox(_HMG_ThisControlName, _HMG_ThisFormName), oBrw:SetFocus() ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW @ nY, nX BUTTON BRUN PICTURE "AddRec" TOOLTIP "Добавить " ; ACTION ( AddRecord( oBrw ) ) WIDTH nW HEIGHT nH ; NOTABSTOP nX += nW DEFINE STATUSBAR STATUSITEM " " END STATUSBAR OpenBrows( "oBrw", 'win_1', 30, 2, win_1.Width-20, win_1.Height-95,nArea ) // 'BASE' oBrw:bUserKeys := {|nKy,nFlg,oBr| MyKeyAction(nKy,nFlg,oBr) } @ 0, 0 GETBOX MyFind HEIGHT 10 WIDTH 10 VALUE "" ; ON LOSTFOCUS ( win_1.MyFind.Hide, win_1.oBrw.SetFocus ) ; ON CHANGE ( MyFind(oBrw) ) ; INVISIBLE oBrw:SetFocus() END WINDOW CENTER WINDOW win_1 ACTIVATE WINDOW win_1 RETURN *-------------------------------- FUNCTION OpenBrows( cBrw, cParent, nRow, nCol, nWidth, nHeight, cAlias ) Public &cBrw DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS cAlias ; OF &cParent ; WIDTH nWidth ; HEIGHT nHeight ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 oBrw:SetAppendMode( .F. ) oBrw:SetDeleteMode( .T., .T. ) oBrw:lNoHScroll := .T. oBrw:lCellBrw := .F. ADD COLUMN TO obrw HEADER "Name" FOOTER "" SIZE 600 ; DATA FieldWBlock( "name", Select( "base" ) ) EDITABLE ADD COLUMN TO obrw HEADER "SOCR" FOOTER "" SIZE 350 ; DATA FieldWBlock( "SOCR", Select( "base" ) ) EDITABLE ADD COLUMN TO obrw HEADER "CODE" FOOTER "" SIZE 200 ; DATA FieldWBlock( "CODE", Select( "base" ) ) EDITABLE &cBrw:nHeightCell += 6 &cBrw:nHeightHead += 14 &cBrw:nHeightFoot := &cBrw:nHeightHead &cBrw:nWheelLines := 1 &cBrw:lDrawFooters := .T. &cBrw:lNoHScroll := .T. // LoadFields( cBrw, cParent ) END TBROWSE // !!! RETURN Static Function MyFind( oBrw ) Local cVal := win_1.MyFind.Value If ! empty(cVal) (oBrw:cAlias)->( dbSeek(upper(trim(cVal))) ) oBrw:GotoRec((oBrw:cAlias)->( RecNo()) ) EndIf Return nil *----------------------------------- PROCEDURE AddRecord( oBrw ) *----------------------------------- Local nRec (obrw:cAlias)->( DbAppend() ) nRec := (obrw:cAlias)->( RecNo() ) (obrw:cAlias)->( FieldPut( 1, Procname()+": "+strzero(nRec,7 )+str(procline(), 7) ) ) (obrw:cAlias)->( FieldPut( 3, Str(nRec,5) ) ) obrw:GoToRec( nRec ) obrw:SetFocus() RETURN STATIC FUNCTION MyKeyAction( nKey, nFlag, oBrw ) Local oCell, hBrw, nRow, uRet If nKey > 32 .and. nKey < 254 If (oBrw:cAlias)->( Indexord() ) == 0 Return endif oCell := oBrw:GetCellInfo(1, 1) hBrw := oBrw:hWnd nRow := GetWindowHeight(hBrw) + win_1.oBrw.Row - oBrw:nHeightFoot win_1.MyFind.Row := nRow win_1.MyFind.Col := oCell:nCol win_1.MyFind.Width := oCell:nWidth win_1.MyFind.Height := oBrw:nHeightFoot win_1.MyFind.Show() win_1.MyFind.SetFocus() win_1.MyFind.Value := space(10) _PushKey(nKey) uRet := .F. // обработка завершена (nil - продолжит tsb) EndIf Return uRet [/pre2]

SergKis: PS подправить OpenBrows( "oBrw", 'win_1', 30, 2, win_1.Width-20, win_1.Height-95, Alias() )

Vlad04: оК Спасибо, но вопросы остались. Как обратится к элементам, объектам формы из функций ? &(cForm) вместо win_1 не работает ?

Andrey: SetProperty( ThisWindow.Name, "объект", "Enabled", .F. ) или SetProperty( cForm, "MyFind", "Value", "проба" ) // записать в объект cVal := GetProperty( cForm, "MyFind", "Value" ) // считать из объекта

SergKis: Vlad04 тот же пример без Public переменной click here

Vlad04: SergKis Ок. Все четко работает, но что ж так сложно. Все сложности должны быть в библиотеке (может у вас так и сделано). А если на форме несколько Бровзов и другие компоненты ?

SergKis: Vlad04 В чем сложность ? По моему очень похоже, как было в clipper tbrowse (координаты, алиас и UserFunc). Ф-ии TBrw_... надергал из своего класса TBrw (служит надстройкой над tsb) и лежит вместе с TBrowse в либе. Убрав этот код, что останется от примера ?

Vlad04: По моему очень похоже ,, как было в clipper tbrowse Так понятно Ф-ии TBrw_... надергал из своего класса TBrw Буду разбираться..

Andrey: Можно ли определить нажатие мышки в подвале таблицы ? Т.е. на какой колонке подвала была нажата мышка, ну и вызвать функцию какую либо...

SergKis: Andrey пишет:Можно ли определить нажатие мышки в подвале таблицы ? см. TSCOLUMN.PRG а то будет снова твоя цитата Спасибо ! Не сообразил сразу там посмотреть !

Andrey: Можно ли определить нажатие мышки в подвале таблицы ? Можно сделать так: For nI := 1 To oBrw1:nColCount() oBrw1:aColumns[ nI ]:bFLClicked := &("{|| MyFunctionSelect("+HB_NtoS(nI)+") }") Next

SergKis: Andrey Если поищешь в h_tbrowse.prg bFLClicked (всего одно место), то увидишь [pre2] If ::aColumns[ nAtCol ]:bFLClicked != Nil Eval( ::aColumns[ nAtCol ]:bFLClicked, uPar1, uPar2, ::nAt, Self ) ... выше увидишь uPar1 := nRowPix, ; uPar2 := nColPix, ; и твой блок кода будет таким {|nRowPix,nColPix,nAt,oBrw| MyFunctionSelect(nRowPix,nColPix,nAt,oBrw) } и номер колонки в ф-ии будет oBrw:nCell, а oBrw:nRowPos тек. строка и т.д. [/pre2]

Andrey: Блин, пробовал до этого так {|nRow,nCo| MyFunctionSelect(nRow,nCol) } Увидел что пикселы это и бросил... а зря оказывается.... Спасибо !

SergKis: Andrey пишет:и твой блок кода будет таким {|nRowPix,nColPix,nAt,oBrw| MyFunctionSelect(nRowPix,nColPix,nAt,oBrw) } Номера подвала колонки нет ! Andrey, а посмотреть указанное место трудно ? там есть ответ буквально несколькими строками ниже от uPar1 := nRowPix, ; uPar2 := nColPix, ; ... nClickRow := ::GetTxtRow( nRowPix ) nAtCol := Max( ::nAtCol( nColPix ), 1 ) поставь и подсвети в свою ф-ю

Andrey: Рано радовался... oBrw1:aColumns[ nI ]:bFLClicked := {|nRowPix,nColPix,nAt,oBrw| SelectRunColumns(nRowPix,nColPix,nAt,oBrw) } Как получить номер нажатого подвала колонки ? nAt - это номер строки таблицы. Нельзя в исходнике добавить НОМЕР подвала нажатой колонки ?

Haz: Andrey пишет: Нельзя в исходнике добавить НОМЕР подвала нажатой колонки Во первых он там есть Во вторых , то что Сергей в посте 925 написал , не подходит что ли ? SergKis: и номер колонки в ф-ии будет oBrw:nCell, а oBrw:nRowPos тек. строка и т.д.

Andrey: Haz пишет: Во вторых , то что Сергей в посте 925 написал , не подходит что ли ? Это я написал, а потом смотрю ответ выше моего появился... SergKis пишет: поставь и подсвети в свою ф-ю Спасибо БОЛЬШОЕ !

Andrey: Погонял я нажатие мышкой подвала таблицы и заметил ляпы: под 8.1 ширина нажатия подвала - чуть больше половины подвала. Нижняя половина подвала на нажатие мышки никак не реагирует. Под 7-кой срабатывание при нажатии мышкой сужается до 1/3 подвала таблицы. А почему так ? For nI := 2 To oBrw1:nColCount() oBrw1:aColumns[ nI ]:bFLClicked := {|nRowPix,nColPix,nAt,oBrw| SelectRunColumns(nRowPix,nColPix,nAt,oBrw) } Next ............ ////////////////////////////////////////////////////////////////// FUNCTION SelectRunColumns(nRowPix,nColPix,nAt,oBrw) LOCAL nClickRow := oBrw:GetTxtRow( nRowPix ) LOCAL nAtCol := Max( oBrw:nAtCol( nColPix ), 1 ) LOCAL cRet //MsgDebug(nRowPix,nColPix,nAt,"----",nClickRow,nAtCol) cRet := Form_SelectRunColumns(nAtCol) IF LEN(cRet) > 0 // выбрана настройка формул oBrw1:aColumns[nAtCol]:cFooting := cRet oBrw1:DrawFooters() ENDIF RETURN NIL

Andrey: Andrey пишет: Погонял я нажатие мышкой подвала таблицы и заметил ляпы: под 8.1 ширина нажатия подвала - чуть больше половины подвала. Нижняя половина подвала на нажатие мышки никак не реагирует. Сделал обработку подвала в другом примере - заработало без проблем. Вернулся к этому же примеру и понял, что при увеличение высоты подвала + ширины колонки подвала будет такая проблема (см.описание выше) ! Как решить эту проблему ?

Andrey: Вот ещё одна проблемка.... Назначаю подсказку на один столбец: oBrw1:cToolTip := {|oBr,nCol,nRow| IIF( nCol==2, cToolTip + " "+HB_NtoS(nRow), "") } Ставлю мышку на суперхидер - подсказка всё равно отображается: Как убрать подсказку с суперхидера ?

Vlad04: Имеется TsBrows на форме.Отображаются данные таблицы 1, после некоторых действий надо на этом же месте отобразить данные другой таблицы . Структура та же, алиас другой. Как правильно переопределить TsBrows

Haz: Vlad04 пишет: Как правильно переопределить TsBrows Brw:cAlias := cNewAlias то что ниже Brw:Reset() перед Brw:Reset() важно переопределить блоки кода бровса ( в них остался прежний алиас ). Я работаю с ADS и для него годится так [pre2] Brw:cAlias := cAlias Brw:bGoTop := {|| ( cAlias )->( DbGoTop() ) } Brw:bGoBottom := {|| ( cAlias )->( DbGoBottom() ) } Brw:bSkip := {| n | If( n == Nil, n := 1, Nil ), Brw:DbSkipper( n ) } Brw:bBof := {|| ( cAlias )->( Bof() ) } Brw:bEof := {|| ( cAlias )->( Eof() ) } // отсюда специфика ADS cAdsKeyNo := "{| n, oBrw | If( n == Nil, Round( " + cAlias + "->( ADSGetRelKeyPos() ) * oBrw:nLen, 0 ), " + ; cAlias + "->( ADSSetRelKeyPos( n / oBrw:nLen ) ) ) }" cAdsKeyCount := "{|cTag| " + cAlias + "->( ADSKeyCount(cTag,, 1 ) ) }" Brw:bKeyNo := &cAdsKeyNo Brw:bKeyCount := &cAdsKeyCount Brw:bLogicLen := &cAdsKeyCount Brw:bTagOrder := {|uTag| ( cAlias )->( OrdSetFocus( uTag ) ) } Brw:bGoToPos := {|n| Eval( Brw:bKeyNo, n, Brw ) } /* А это для других RDD Brw:bKeyNo := {| n | ( cAlias )->( If( n == Nil, If( IndexOrd() > 0, OrdKeyNo(), RecNo() ), ; If( IndexOrd() > 0, OrdKeyGoto( n ), DbGoTo( n ) ) ) ) } Brw:bKeyCount := {|| ( cAlias )->( If( IndexOrd() > 0, OrdKeyCount(), LastRec() ) ) } Brw:bLogicLen := {|| ( cAlias )->( If( IndexOrd() == 0, LastRec(), OrdKeyCount() ) ) } Brw:bTagOrder := {|uTag| ( cAlias )->( OrdSetFocus( uTag ) ) } Brw:bGoToPos := {|n| Eval( ::bKeyNo, n ) } */ Brw:SetDbf( cAlias ) [/pre2] PS. в случае когда структура другая , нужно убить старый бровс и на его месте создать новый . В случае когда отличия только в части полей - проще в первом бровсе удалить колонки , которых не должно быть во втором и добавить новые, потом Reset()

Vlad04: Haz нужно убить старый бровс А как ?

Haz: Vlad04 пишет: А как ? Элементарно ) DoMethod('Form_1', 'Brw', 'Release')

SergKis: Vlad04 пишет: Как правильно переопределить TsBrows можно закрыть dbf с oBrw:cAlias и в той же область открыть аналогичный dbf с таким же алиасом, если использовались oCol:cOrder (сортировка на колонках), то аналогичный dbf должен иметь и аналогичные индексы

Haz: SergKis пишет: открыть аналогичный dbf с таким же алиасом, Подтверждаю, это самый простой способ. Использую именно его когда получаю алиас из SQL запроса. т.к. управляющий индекс не нужен ( сортировка ставится как ORDER BY ) , то достаточно одного Brw:Reset()

Vlad04: оК! Все нормально!

Vlad04: С открытием и закрытием все нормально. Как избежать повторного закрытия (открытия) соответственно уже закрытого или открытого бровза ( исключаем человеческий фактор )? Для окна делаем так if !IsWindowDefined(Frm_klient) а для элемента окна ?

Andrey: Наверно так: IF GetControlIndex("Timer_1", cForm ) > 0

SergKis: или #translate IsControlDefined ( <ControlName> , <FormName> ) ; => ; _IsControlDefined ( <"ControlName"> , <"FormName"> )

Vlad04: *-------------------------------- Удаляем Контрол, при его наличии Procedure Del_Brv() if _IsControlDefined ( "oBrw" , "DEMO" ) = .t. //вариант // IF GetControlIndex("oBrw",'Demo' ) > 0 DoMethod('Demo', 'oBrw', 'Release') endif Return *------------------------------- Открывам контрол , если его нет Procedure Open_Brw() IF GetControlIndex("oBrw",'Demo' ) = 0 // вариант // if _IsControlDefined ( "oBrw" , "DEMO" ) = .f. OpenBrows( "oBrw", 'DEMO', 80, 15, dEMO.Width-20, DEMO.Height-130 , Alias() ) endif Return *----------------------------------------- Оба способа работают, только функции проверки возвращают разные значения.

Haz: Григорий, просьба в два метода ::DrawLine() и ::DrawSelect() добавить проверку условия ::lVisible в строках [pre2] lCheck := ( oColumn:lCheckBox .and. ValType( uData ) == "L" .and. oColumn:lVisible ) [/pre2] примерные номера строк в исходнике 2932 и 3253 без этой проверки , если lCheckBox истина и колонка скрыта, в соседнюю выдает мусор от битмапа. Тестовый пример писать не стал, т.к. и так все просто. В любом примере TS в колонке по логическому полю задать то что ниже и посмотреть [pre2] oBrw:aColumns[n]:lCheckBox := .T. oBrw:Hidecolumns(n, .T. ) [/pre2] PS. Хорошо кстати тестится на примере Сергея Tsb_BitMaps

gfilatov2002: Haz пишет: без этой проверки , если lCheckBox истина и колонка скрыта, в соседнюю выдает мусор от битмапа Благодарю за помощь Поправил, конечно...

Haz: Григорий Пропущено указание алиаса и метод работает только если oBrw:cAlias является текущей METHOD LoadFields() ... nE := If( aNames == Nil, n, ( ::cAlias )->(FieldPos( aNames[ n ] )) )

gfilatov2002: Haz пишет: Пропущено указание алиаса Снова благодарю за исправление Кстати, эта опечатка есть и у автора библиотеки...

Haz: gfilatov2002 пишет: Кстати, эта опечатка есть и у автора не важно у кого есть , важно что исправлено я минут 15 тупил почему то работает то нет, пока не полез в сырцы

gfilatov2002: Haz пишет: пока не полез в сырцы Сейчас обнаружил, что не могу прикрутить подсказки к датам в Вашем календаре, т.к. при динамическом определении данных в массиве у блока кода cTooltip параметр номер колонки nCol всегда равен номеру последнего столбца. При обычном присвоении массива типа oBrw3:SetArray( aItems ), все работает нормально. Может гляните, что нужно поправить, у меня НЕ выходит...

Haz: gfilatov2002 пишет: параметр номер колонки nCol всегда равен номеру последнего столбца. я это через макроподстановку делаю [pre2] oBrw:aColumns[ i ]:bData := &( "{|| GetDate( " + NTOC( i ) + ")}") [/pre2] Выложите сюда кусок кода , может что придумаем вместе

gfilatov2002: Haz пишет: Выложите сюда кусок кода Да весь код - это одна строка oBrw:cToolTip := {|oBr,nCol,nRow| if( nRow > 0, "Col ="+str(nCol,3)+" Row ="+str(nRow,3), ) } который выдает для любой колонки Col = 7, а ряд показывает правильно...

Haz: gfilatov2002 пишет: Да весь код - это одна строка ок, сейчас что нибудь сделаю

Haz: Все из-за замороженных колонок В примере они заморожены все 7 , ::nFreeze := 7 но lLockFreeze := FALSE Это чтоб бровс не панарамировался при перемещении к последней колонке При показе cToolTip используется вычисление колонки исходя из позиции мыши, при этом автоматом прибавляется замороженный кусок это метод ::nAtCol() . Либо менять его , либо тут [pre2] METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse Local nI, nIcon, lHeader, lMChange, nFirst, nLast, nDestCol, ; cMsg := ::cMsg, ; nColPixPos := 0, ; lFrozen := .F., ; nColumn := Max( 1, ::nAtCol( nColPix, .T. ) ), ; [/pre2]

Haz: Haz пишет: nColumn := Max( 1, ::nAtCol( nColPix, .T. ) ), ; Но это тоже не правильно нужно переделывать ::nAtCol() , это он дурит при наличии заморозки. Пока не готов сказать как, думаю ... Посмотрел внимательнее - беда всеже в методе MouseMove , там нужно именно nColumn := Max( 1, ::nAtCol( nColPix, .T. ) ), тогда номер видимой колонки определяется правильно ( именно видимой на экране а не порядковый в бровсе ) Дальше нужно менять логику получения номера колонки бровса из видимого на экране с учетом фриз и скрола и скрытых Опять есть над чем думать ...

SergKis: Haz переделывать nAtCol не надо, надо сделать так: [pre2] METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse ... nRowLine := ::GetTxtRow( nRowPix ), ctooltip, nCol ... If ::nToolTip != nColumn .or. nRowLine != ::nToolTipRow ctooltip := ::aColumns[ nColumn ]:cToolTip If Valtype( ctooltip ) == "B" nCol := ::nAtCol(nColPix, .T.) ctooltip := Eval( ctooltip, Self, nCol, nRowLine ) EndIf ... If ::nToolTip != nColumn .or. nRowLine != ::nToolTipRow ctooltip := ::cToolTip If Valtype( ctooltip ) == "B" nCol := ::nAtCol(nColPix, .T.) ctooltip := Eval( ctooltip, Self, nCol, nRowLine ) EndIf [/pre2] этого достаточно

SergKis: PS через ncol := Max(1, ::nAtCol(...)) может лучше

Haz: SergKis пишет: переделывать nAtCol не надо, надо сделать так: тоже переделал MouseMove .... nCol := ::nAtCol(nColPix, .T.) показывает видимую ( как мы видим ) на экране колонку и не понимаем на взгляд сколько заморожено и сколько скрыто скролом ( ушло влево за границу ) или сколько из того что видим скрыты логически т.е. ::HideColumn() соответственно nCol не равен номеру колонки бровса. В примере календяря заморозил 1 колонку и скролом спрятал вторую потом проверял что кажет Может я не прав , но по сырцам ::nAtCol зависим от ::nColPos я попробывал рассчитать заново [pre2] Сначала всю заморозку For nI := 1 To ::nFreeze IF nColPix > nColPixPos nColumn := nI END nColPixPos += ::GetColSizes()[ nI ] Next Потом с учетом видимости For nI := 1 To ::nColCount() IF nI > ::nFreeze IF nColPix > nColPixPos nColumn ++ END nColPixPos += IF(::IsColVis2(nI), ::GetColSizes()[ nI ], 0 ) END End [/pre2] Вроде кажет правильно , nColumn равен номеру колонки бровса

SergKis: У себя сделал:[pre2] METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse ... Local ctooltip, nCol := Max( 1, ::nAtCol( nColPix, .T. ) ) ... If ( lHeader := nRowLine == 0 ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nCol ]:cToolTip ) If ::nToolTip != nCol .or. nRowLine != ::nToolTipRow ctooltip := ::aColumns[ nCol ]:cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, nCol, nRowLine) EndIf SetToolTip ( ::hWnd , ctooltip , ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nCol Else If ::nToolTip != nCol .or. nRowLine != ::nToolTipRow ctooltip := ::cToolTip If Valtype(ctooltip) == "B" ctooltip := Eval(ctooltip, Self, nCol, nRowLine) EndIf SetToolTip ( ::hWnd , ctooltip , ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine endif ::nToolTip := nCol EndIf ... [/pre2] заменил nColumn на nCol, что касается ToolTip - вроде нормально ... пример: click here

Haz: Сергей А такой тест проходит ? В примере календяря заморозил 1 колонку и скролом спрятал вторую потом проверял что кажет или скинь полный код MouseMove , проверю

SergKis: Haz пишет:скинь полный код MouseMove тут: [pre2] * ============================================================================ * METHOD TSBrowse:MouseMove() Version 9.0 Nov/30/2009 * ============================================================================ METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse Local nI, nIcon, lHeader, lMChange, nFirst, nLast, nDestCol, ; cMsg := ::cMsg, ; nColPixPos := 0, ; lFrozen := .F., ; nColumn := Max( 1, ::nAtCol( nColPix ) ), ; nRowLine := ::GetTxtRow( nRowPix ), ctooltip Local nCol := Max( 1, ::nAtCol( nColPix, .T. ) ) Default ::lMouseDown := .F., ; ::lNoMoveCols := .F., ; ::lDontChange := .F. If ::lIconView If ( nIcon := ::nAtIcon( nRowPix, nColPix ) ) != 0 If ::nIconPos != 0 .and. ::nIconPos != nIcon ::DrawIcon( ::nIconPos ) EndIf ::nIconPos := nIcon ::DrawIcon( nIcon, .T. ) CursorHand() Return 0 EndIf EndIf If ::nFreeze > 0 For nI := 1 To ::nFreeze nColPixPos += ::GetColSizes()[ nI ] Next If nColPix < nColPixPos lFrozen := .T. EndIf EndIf If ( lHeader := ( nRowLine == 0 ) ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nCol ]:cToolTip ) If ::nToolTip != nCol .or. nRowLine != ::nToolTipRow ctooltip := ::aColumns[ nCol ]:cToolTip If Valtype( ctooltip ) == "B" ctooltip := Eval( ctooltip, Self, nCol, nRowLine ) EndIf SetToolTip( ::hWnd, ctooltip, ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nCol Else If ::nToolTip != nCol .or. nRowLine != ::nToolTipRow ctooltip := ::cToolTip If Valtype( ctooltip ) == "B" ctooltip := Eval( ctooltip, Self, nCol, nRowLine ) EndIf SetToolTip( ::hWnd, ctooltip, ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nCol EndIf lHeader := ( ::GetTxtRow( nRowPix ) == 0 .or. ::GetTxtRow( nRowPix ) == -2 ) If ! ::lGrasp .and. ( lFrozen .or. ! lHeader .or. ! ::lMChange ) // don't allow MouseMove to drag/resize columns // unless in header row and not in frozen zone CursorArrow() If ::lCaptured If ::lLineDrag ::VertLine() ::lLineDrag := .F. EndIf ReleaseCapture() ::lColDrag := ::lCaptured := ::lMouseDown := .F. ElseIf ::lDontChange CursorStop() Return 0 EndIf lMChange := ::lMChange // save it for restore ::lMChange := .F. If ::lCellBrw .and. ! Empty( ::aColumns[ Max( 1, ::nAtCol( nColPix ) ) ]:cMsg ) ::cMsg := ::aColumns[ Max( 1, ::nAtCol( nColPix ) ) ]:cMsg Else ::cMsg := cMsg EndIf ::cMsg := If( ValType( ::cMsg ) == "B", Eval( ::cMsg, Self, Max( 1, ::nAtCol( nColPix ) ) ), ::cMsg ) ::Super:MouseMove( nRowPix, nColPix, nKeyFlags ) ::lMChange := lMChange ::cMsg := cMsg Return 0 EndIf If ::lMChange .and. ! ::lNoMoveCols .and. ! ::lDontChange If lHeader If ! Empty( ::aSuperHead ) .and. !::lLineDrag nFirst := 0 nLast := 0 Aeval( ::aSuperHead, { | aSup, nCol | nFirst := If( ::nDragCol >= aSup[1] .and. ::nDragCol <= aSup[ 2 ],nCol,nFirst ), ; nLast := max(nLast,aSup[ 2 ])} ) nDestCol := ::nAtCol( nColPix ) if nLast < nDestCol nLast := nFirst+1 else Aeval( ::aSuperHead, { | aSup, nCol | nlast := If( nDestCol >= aSup[1] .and. nDestCol <= aSup[ 2 ],nCol,nlast )} ) endif If nLast != nFirst ::lGrasp := .F. CursorHand() ::lColDrag := ::lCaptured := ::lMouseDown := .F. endif endif If ::lGrasp // avoid dragging between header & rows ::lGrasp := .F. CursorArrow() // restore default cursor EndIf If ::lColDrag CursorSize() Else If ::lLineDrag ::VertLine( nColPix ) CursorWE() Else If AScan( ::GetColSizes(), { | nColumn | nColPixPos += nColumn, ; nColPix >= nColPixPos - 2 .and. nColPix <= nColPixPos + 2 }, ::nColPos ) != 0 CursorWE() Else CursorHand() EndIf EndIf EndIf ElseIf ::lGrasp ::lCaptured := ::lColDrag := .F. // to avoid collision with header/column dragging ::lMouseDown := .T. // has to be down until dragging finishes ::Super:MouseMove( nRowPix, nColPix, nKeyFlags ) Else CursorArrow() EndIf Else If ::lDontChange CursorStop() Else CursorArrow() EndIf EndIf Return 0 [/pre2]

Haz: Cергей, проверил не катит 1 В исходнике календаря пропиши oBrw:nFreeze := 1 oBrw:lLockFreeze := TRUE 2 Запусти и кнопкой вправо до упора пока не появится пустое поле 3 Поставь грызуна на колонку "СР " покажет 2 На экране видим мы ее второй но в бровсе она третья

SergKis: Игорь, конечно, с учетом видимости, ты прав, будет врать. Решить можно новым методом или вводить еще параметр в nAtCol (менять алгоритм nAtCol опасно - задействован сильно кругом)

Haz: SergKis пишет: (менять алгоритм nAtCol опасно - задействован сильно кругом) А что думаешь про смену алгоритма ::MouseMove как я предложил ( расчет номера колонки двумя циклами , можно в один свести ) Ведь там у тебя nColumn, это именно номер колонки бровса. и кроме как в тултипе нигде не используется ( есть в блоке , но там как параметр - локальная переменная ) а ::nAtCol менять не надо [pre2] * ============================================================================ * METHOD TSBrowse:MouseMove() Version 9.0 Nov/30/2009 * ============================================================================ METHOD MouseMove( nRowPix, nColPix, nKeyFlags ) CLASS TSBrowse Local nI, nIcon, lHeader, lMChange, nFirst, nLast, nDestCol, ; cMsg := ::cMsg, ; nColPixPos := 0, ; lFrozen := .F., ; // nColumn := Max( 1, ::nAtCol( nColPix , .T.) ), ; nRowLine := ::GetTxtRow( nRowPix ), ctooltip Default ::lMouseDown := .F., ; ::lNoMoveCols := .F., ; ::lDontChange := .F. If ::lIconView If ( nIcon := ::nAtIcon( nRowPix, nColPix ) ) != 0 If ::nIconPos != 0 .and. ::nIconPos != nIcon ::DrawIcon( ::nIconPos ) EndIf ::nIconPos := nIcon ::DrawIcon( nIcon, .T. ) CursorHand() Return 0 EndIf EndIf If ::nFreeze > 0 For nI := 1 To ::nFreeze IF nColPix > nColPixPos nColumn := nI END nColPixPos += ::GetColSizes()[ nI ] Next If nColPix < nColPixPos lFrozen := .T. EndIf EndIf For nI := 1 To ::nColCount() IF nI > ::nFreeze IF nColPix > nColPixPos nColumn ++ END nColPixPos += IF(::IsColVis2(nI), ::GetColSizes()[ nI ], 0 ) END End If ( lHeader := ( nRowLine == 0 ) ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) If ::nToolTip != nColumn .or. nRowLine != ::nToolTipRow ctooltip := ::aColumns[ nColumn ]:cToolTip If Valtype( ctooltip ) == "B" ctooltip := Eval( ctooltip, Self, nColumn, nRowLine ) EndIf SetToolTip( ::hWnd, ctooltip, ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nColumn Else If ::nToolTip != nColumn .or. nRowLine != ::nToolTipRow ctooltip := ::cToolTip If Valtype( ctooltip ) == "B" ctooltip := Eval( ctooltip, Self, nColumn, nRowLine ) EndIf SetToolTip( ::hWnd, ctooltip, ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nColumn EndIf lHeader := ( ::GetTxtRow( nRowPix ) == 0 .or. ::GetTxtRow( nRowPix ) == -2 ) If ! ::lGrasp .and. ( lFrozen .or. ! lHeader .or. ! ::lMChange ) // don't allow MouseMove to drag/resize columns // unless in header row and not in frozen zone CursorArrow() If ::lCaptured If ::lLineDrag ::VertLine() ::lLineDrag := .F. EndIf ReleaseCapture() ::lColDrag := ::lCaptured := ::lMouseDown := .F. ElseIf ::lDontChange CursorStop() Return 0 EndIf lMChange := ::lMChange // save it for restore ::lMChange := .F. If ::lCellBrw .and. ! Empty( ::aColumns[ Max( 1, ::nAtCol( nColPix ) ) ]:cMsg ) ::cMsg := ::aColumns[ Max( 1, ::nAtCol( nColPix ) ) ]:cMsg Else ::cMsg := cMsg EndIf ::cMsg := If( ValType( ::cMsg ) == "B", Eval( ::cMsg, Self, Max( 1, ::nAtCol( nColPix ) ) ), ::cMsg ) ::Super:MouseMove( nRowPix, nColPix, nKeyFlags ) ::lMChange := lMChange ::cMsg := cMsg Return 0 EndIf If ::lMChange .and. ! ::lNoMoveCols .and. ! ::lDontChange If lHeader If ! Empty( ::aSuperHead ) .and. !::lLineDrag nFirst := 0 nLast := 0 Aeval( ::aSuperHead, { | aSup, nCol | nFirst := If( ::nDragCol >= aSup[1] .and. ::nDragCol <= aSup[ 2 ],nCol,nFirst ), ; nLast := max(nLast,aSup[ 2 ])} ) nDestCol := ::nAtCol( nColPix ) if nLast < nDestCol nLast := nFirst+1 else Aeval( ::aSuperHead, { | aSup, nCol | nlast := If( nDestCol >= aSup[1] .and. nDestCol <= aSup[ 2 ],nCol,nlast )} ) endif If nLast != nFirst ::lGrasp := .F. CursorHand() ::lColDrag := ::lCaptured := ::lMouseDown := .F. endif endif If ::lGrasp // avoid dragging between header & rows ::lGrasp := .F. CursorArrow() // restore default cursor EndIf If ::lColDrag CursorSize() Else If ::lLineDrag ::VertLine( nColPix ) CursorWE() Else If AScan( ::GetColSizes(), { | nColumn | nColPixPos += nColumn, ; nColPix >= nColPixPos - 2 .and. nColPix <= nColPixPos + 2 }, ::nColPos ) != 0 CursorWE() Else CursorHand() EndIf EndIf EndIf ElseIf ::lGrasp ::lCaptured := ::lColDrag := .F. // to avoid collision with header/column dragging ::lMouseDown := .T. // has to be down until dragging finishes ::Super:MouseMove( nRowPix, nColPix, nKeyFlags ) Else CursorArrow() EndIf Else If ::lDontChange CursorStop() Else CursorArrow() EndIf EndIf Return 0 [/pre2]

SergKis: Haz пишет:А что думаешь про смену алгоритма ::MouseMove По мне лучше метод (думаю пригодиться в использовании). У себя сделал так на базе твоего алгоритма:[pre2] METHOD nAtColReal( nColPixel ) CLASS TSBrowse Local nColumn := 0, ; aSizes := ::GetColSizes(), ; nI := 0, ; nColPix := 0 For nI := 1 To ::nFreeze IF nColPixel > nColPix nColumn := nI ENDIF nColPix += aSizes[ nI ] Next For nI := 1 To ::nColCount() IF nI > ::nFreeze IF nColPixel > nColPix nColumn ++ ENDIF nColPix += IF(::IsColVis2(nI), aSizes[ nI ], 0 ) ENDIF Next Return nColumn тогда в MouseMove Local nCol := Max( 1, ::nAtColReal( nColPix ) ) ... [/pre2] у себя проверил - нормальненько вроде

gfilatov2002: SergKis пишет: По мне лучше метод Огромная благодарность за помощь! Добавил этот новый метод, но переименовал его в nAtColActual Вот что получилось

Haz: gfilatov2002 пишет: Вот что получилось Нормальненько получилось , в тултип можно добавить еще и номер недели [pre2] //Find number of week within year FT_WOY( <dDate> ) -> <nResult> [/pre2]

Dima: gfilatov2002 пишет: Вот что получилось Поправил линк на картинку (не видно было)

Andrey: В новой версии 1604 ушёл баг про который писал в Пост N: 4819 и N: 4822 Спасибо !

Andrey: Тестирую новую версию - попал на БОЛЬШОЙ БАГ ! Проверил старую, там тоже "падает" программа... Что делать, не знаю... Из основного Tsbrowsa (свои переменные STATIC цвета, PUBLIC oBrw и т.д.) вызываю другой Tsbrowse (со своими STATIC, PUBLIC oBrw_5 - переменными). У основного в цветах таблицы определяю типа так: AADD( aStatClsUsl , { { || Master->KDoljn == 0 .OR. Master->KMaster == 0 }, "12/4" } ) AADD( aStatClsUsl , { { || LEN( ALLTRIM(Master->Master) ) == 0 } , {128, 255} } ) AADD( aStatClsUsl , { { || Master->KDel == 0 }, "4/2" } ) Как в примере MiniGUI\SAMPLES\Advanced\Tsb_config После вызова другого Tsbrowse отладка не действует, окно с MsgDebug() не появляется. Хотя ставлю MsgLog(Alias()) - видно что база переключилась на новую. И тип ошибки вообще убивает: Error BASE/1003 Переменная не существует: KMASTER Called from (b)FIELDBLOCK(0) Called from TSBROWSE:DRAWLINE(2928) Called from TSBROWSE:DRAWSELECT(3176) Called from TSBROWSE:LOSTFOCUS(8108) Called from TCONTROL:HANDLEEVENT(898) Called from TSBROWSE:HANDLEEVENT(7342) Called from EVENTS(75) Так в новой базе и нету такого поля !!!! Причём тут запрос этого поля, я его не делаю... Или это oBrw:bChange отрабатывает ? Как тогда остановить его на время обращения к другой базе ? Вот стек вызов процедур: Помогите пожалуйста решить мою проблему !

SergKis: Andrey для блока отображения используй FieldWBlock(cFieldName, select(cAlias)) вместо FieldBlock

Andrey: SergKis пишет: для блока отображения используй FieldWBlock(cFieldName, select(cAlias)) вместо FieldBlock Блин, так просто... Сразу заработало !!! Спасибо БОЛЬШОЕ !!!

gfilatov2002: Andrey пишет: Как в примере MiniGUI\SAMPLES\Advanced\Tsb_config Просто к сведению. Поправил эту неточность в вышеуказанном примере

Andrey: Всем привет ! Что-то неправильно работает в Tsbrowse следующее cDateBlock := 'FieldWblock( "VidOpl", Select("VidOpl") )' или '{ || VidOpl->VidOpl }' , использую oBrw:aColumns[nI]:bData := &( cDateBlock ) Вот скрин: Если делаю через свою функцию cDateBlock := '{ || SAY_SEL((Alias())->KVidOpl,"VidOpl","VidOpl") }', то показывает правильно: Соседнюю колонку показывает правильно, там делаю cDateBlock := 'FieldWblock( "StDogov", Select("StDogov") )' ! База не битая, индексы правильные... Из-за чего такое может быть ?

Haz: *PRIVAT*

Andrey: Вот ещё одна непонятка в новой программе... Если редактируемое поле в таблице подключено в индексное выражение, то после окончания редактирования его, курсор уходит неизвестно куда, а потом при движении стрелка вверх/вниз появляется вторая фантомная таблица-дубль ! Т.е. все координаты Tsbrowsa сместились на новые... Вот так на экране это выглядит: И куда здесь "копать" ?

Haz: Andrey пишет: И куда здесь "копать" ? Самое простое. - после редактирования oBrw:GotoRecNo( (oBrw:cAlias)->(Recno()) )

Andrey: Да есть такая обработка у меня. ( наверно опечатался - GotoRecNo ?) oBrw:aColumns[nJ]:bPrevEdit := {|| nRecBuff := (oBrw:cAlias)->(RecNo()), MyFieldEdit( oBrw:aColumns[oBrwS:nCell]:Cargo ) } oBrw:aColumns[nI]:bPostEdit := {|| oBrw:GoToRec(nRecBuff), oBrw:GoLeft(), oBrw:Refresh(.T.) } А координаты бровса почему "улетают" ? Если убрать bPostEdit то улёт прекращается, но только тогда курсор может оказаться после редактирования на другой позиции. У меня еще в обработке сидит oBrw:bUserKeys := { |a,b,c| MyKeyCheck(a,b,c) }, где отслеживается набор букв и делается фильтр по этому полю. CASE nKey > 47 .AND. nKey < 254 cStSearchValue := cStSearchValue + KeyToChar(nKey)//LatRus( CHR(nKey) ) Form_Spr.Text_1.Value := cStSearchValue RefreshBrowse() STATIC FUNCTION RefreshBrowse() LOCAL cSeek := Alltrim( Form_Spr.Text_1.Value ) LOCAL cStrSeek, cExp cExp := "'" + UPPER(cSeek) + "' $ UPPER("+cStPole_DbRelation+")" cStrSeek := '('+ oBrwS:cAlias +')->'+cStPole_DbSetFilter IF !Empty(cSeek) ( oBrw:cAlias )->( DbSetFilter( &("{||" + cExp + "}"), cExp ) ) ELSE ( oBrw:cAlias )->( DbClearFilter() ) END oBrwS:Reset() Form_Spr.oBrw.Setfocus RETURN NIL

Haz: Andrey пишет: Если убрать bPostEdit то улёт прекращается, но только тогда курсор может оказаться после редактирования на другой позиции. замени на :bEditEnd А это nRecBuff := (oBrw:cAlias)->(RecNo()) совершенно лишнее если спецом не меняешь текущую запись то она же и осталась. Можно просто GotoRec( (oBrw:cAlias)->(Recno()) )

Haz: gfilatov2002 пишет: Добавил этот новый метод, но переименовал его в nAtColActual еще мелкий фикс, сейчас объясню Часто использую перестройку бровса на лету - удаляю все колонки кроме первой в ней у меня ID записи и потом добавляю нужные для конкресного случая ::HideColumns() не катит для широких таблиц т.к. начинаются тормоза с пропусками скрытых колонок и прочие не нужные прорисовки Если в этот момент курсор стоит правее первой колонки то ::MouseMove высчитывает nColumn как 2 и при попытке проверить ToolTip получаем вылет с ошибкой. Вот код, на входе nColumn уже равен 1 , nFreeze = 0 , ::nColCount() = 1 т.к. все кроме 1 поудалял [pre2] ::MouseMove() строка 8182 For nI := 1 To ::nColCount() IF nI > ::nFreeze IF nColPix > nColPixPos nColumn ++ // Тут получим 2 END nColPixPos += IF(::IsColVis2(nI), ::GetColSizes()[ nI ], 0 ) END End [/pre2] Далее в строке 8192 пытаемся влезть в несуществующую колонку [pre2] If ( lHeader := ( nRowLine == 0 ) ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) .... [/pre2] предлагаю ВЕСЬ кусок кода с выводом тултипа по колонке заключить в условие [pre2] IF nColumn <= ::nColCount() // то есть курсор на области колонок А тут все с тултипами END [/pre2]

gfilatov2002: Haz пишет: предлагаю ВЕСЬ кусок кода с выводом тултипа по колонке Благодарю за разъяснение! Переработал этот кусок кода таким образом: [pre] If nColumn <= ::nColCount() If ( lHeader := ( nRowLine == 0 .or. nRowLine == -2 ) ) .and. ! Empty( ::aColumns ) .and. ; ! Empty( ::aColumns[ nColumn ]:cToolTip ) cToolTip := ::aColumns[ nColumn ]:cToolTip // column's header tooltip Else cToolTip := ::cToolTip // grid's tooltip EndIf If ::nToolTip != nColumn .or. nRowLine != ::nToolTipRow If Valtype( ctooltip ) == "B" cToolTip := Eval( cToolTip, Self, nColumn, nRowLine ) EndIf SetToolTip( ::hWnd, cToolTip, ::hToolTip ) SysRefresh() ::nToolTipRow := nRowLine EndIf ::nToolTip := nColumn EndIf ... [/pre]

Andrey: Всем привет ! Использую SetArrayTo(). Как в нём сделать сортировку сразу по ДВУМ колонкам ? Или такое сделать нельзя ? У меня графа квартира сделаны в двух колонках: номер квартиры (NKVAR) и буква квартиры (CKVAR). Заранее спасибо за помощь.

Haz: Andrey пишет: Как в нём сделать сортировку сразу по ДВУМ колонкам ? Asort () с блоком кода для сортировки. Хоть повсем сразу.

Andrey: Haz пишет: Asort () с блоком кода для сортировки. Хоть повсем сразу. Покрутил, так и эдак. Если добавлять новую запись и ставить новый номер квартиры, или изменить любую запись с номером квартиры, то тогда нужно опять делать aSort(). Решил пойти по другому пути: делаю скрытую колонку, помещаю туда STR(NKVAR)+CKVAR и делаю сортировку oBrw:SetOrder(2, , .F. ) Единственно что не понял/не знаю как сделать в первой колонке нумерацию автоматом по возрастанию ? Сейчас после добавления/удаления записи приходиться ручками пересчитывать нумерацию: FOR nI := 1 TO oBrw:nLen oBrw:aArray[ nI, 1 ] := nI // новая нумерация №№ NEXT

Haz: Andrey пишет: Единственно что не понял/не знаю как сделать в первой колонке нумерацию автоматом по возрастанию ? а oBrw:nAt не подходит ? Бровс по массиву использую редко, но вроде там ::nAt правильный

Andrey: Haz пишет: а oBrw:nAt не подходит ? А если добавляется/удаляется запись ? Он автоматом пересчитывается ?

Haz: Andrey пишет: Он автоматом пересчитывается ? ХЗ попробуй

Andrey: Попробовал так: nI := 1 oBrw:aColumns[ nI ]:cHeading := "№№" oBrw:aColumns[ nI ]:bData := {|| oBrw:nLogicPos } Вроде работает правильно, при удалении/добавлении записи счетчик ставиться правильно. Это при сортировке по скрытой колонке по содержимому STR(NKVAR)+CKVAR - oBrwA:SetOrder(2, , .F. )

Andrey: Заметил такую особенность. Если есть первые скрытые столбцы, то при движение маркера/курсора на первые столбцы, он пропадает. Юзер не видит курсор, у него паника.... Как исправить пропадание курсора из таблицы ?

Haz: Andrey пишет: Как исправить пропадание курсора из таблицы ? Не использовать скрытые столбцы или менять исходники TS я отказался от скрытых...

Andrey: Нашёл один вариант. Если колонки скрытые стоят первыми, то можно делать так: oBrwA:nFreeze := 3 // Заморозить первых ХХ столбца И ещё тогда наверно можно скрытые колонки переместить в первые ряды и заморозить их.

Haz: Andrey пишет: Нашёл один вариант зачем они вообще нужны если их скрыли, их лучше удалить . Потребуется - добавить Удаляются ведь только колонки , поля в алиасе остаются

Haz: Григорий . можно в метод ::Edit() первыми строками добавить [pre2] IF !IsInsertActive() iif( _HMG_IsXPorLater, KeyToggleNT( VK_INSERT ), KeyToggle( VK_INSERT ) ) END [/pre2] Не все владеют слепой печатью, пользователи плачут что печатают уткнувшись в клаву, а когда глаза поднимают, то видят что был режим замены и стерто половина того что было в длинном текстовом поле Как универсальный вариант, можно добавить флаг oBrw:lInsert и если его выставили в .Т. как oBrw:lInsert := .T. при инициализации бровса , то так [pre2] IF ValType(::lInsert) == "L" IF IsInsertActive() <> ::lInsert iif( _HMG_IsXPorLater, KeyToggleNT( VK_INSERT ), KeyToggle( VK_INSERT ) ) END END [/pre2] тогда можно не только назначать по умолчанию, но и отключать обработку как oBrw:lInsert := NIL

gfilatov2002: Haz пишет: IF ValType(::lInsert) == "L" IF IsInsertActive() <> ::lInsert iif( _HMG_IsXPorLater, KeyToggleNT( VK_INSERT ), KeyToggle( VK_INSERT ) ) END END Дельное предложение! Принимается

Andrey: Привет всем ! Работаю с SetArrayTo(). В процессе удаляю все записи с таблицы. Одна всегда остаётся. И не редактируется. Наверно это мираж-запись, чтобы SetArrayTo() не сломался. Как определить что юзер удалил все записи из таблицы и закрыть таблицу ? oBrw:nAt возвращает всегда 1.

Haz: Andrey пишет: Наверно это мираж-запись, чтобы SetArrayTo() не сломался. Сейчас придет SergKis и расскажет зачем он туда миражей напихал ... я воздержусь, скажу только по следующему вопросу Andrey пишет: oBrw:nAt возвращает всегда 1. ::nAt используется в исходнике TS как индекс массива , к примеру строка 1252 исходника [pre2] ::aArray[ ::nAt, 1 ] ) [/pre2] Вывод думаю очевиден Andrey пишет: Как определить что юзер удалил все записи из таблицы и закрыть таблицу ? или переходить на ARRAYRDD какой нить и смотреть на RecCount() или в самом массиве держать признак и анализировать его

SergKis: Andrey пишет:В процессе удаляю все записи с таблицы. Одна всегда остаётся. И не редактируется А посмотреть, что прописано в TsBrowse при удалении слабо ? Ты используешь метод DeleteRow(lAll) для удаления, и вряд ли бы ты хотел, что бы всегда сваливалась программа при удалении последней записи. поэтому сделано для массива:[pre2] METHOD DeleteRow(lAll) CLASS TSBrowse ... If Len( ::aArray ) == 0 ::aArray := { AClone( ::aDefValue ) } ::lPhantArrRow := .T. If ::aArray[ 1, 1 ] == Nil ARRDEL_( ::aArray[ 1 ], 1 ) EndIf EndIf ... [/pre2] Проверять удаление последней записи и др. валидности за тебя никто делать не будет.

SergKis: Andrey пишет:Работаю с SetArrayTo() Ты работаешь\используешь TsBrowse, а не SetArrayTo(), SetArray(), SetFields() - это методы установки начальных данных для работы TsBrowse, чем отличаются можно глянуть текст, для ясности в голове, что и как применять, а то складывается впечатление и примеров много сделал, а суть (откуда ноги растут) пропустил

Andrey: SergKis пишет: а то складывается впечатление и примеров много сделал, а суть (откуда ноги растут) пропустил Это точно !

SergKis: Andrey пишет:Это точно ! Надеюсь ты увидел в приведенном куске текста ::lPhantArrRow := .T. можешь для массива воспользоваться после вызова метода удаления If oBrw:lPhantArrRow // тек.\последняя\первая запись фантомная // тут дейсвия по закрытию TsBrowse EndIf Другой (общий) вариант задать oBrw:bDelete := {| nAt,oBr,lAll | lDeleteRec := .T., .T. } и в функции удаления делаем: Private lDeleteRec := .F. oBrw:DeleteRow() If lDeleteRec .and. Len(oBrw:aArray) == 1 // тут дейсвия по закрытию TsBrowse EndIf

Andrey: SergKis , спасибо за разъяснения ! Понял куда двигаться !

SergKis: Andrey пишет:Понял куда двигаться ! Тогда не забудь, что есть и oBrw:bPostDel := {|oBr| ... } и если в oBrw:bDelete обрабатывается логический возврат ( при .F. отменяется удаление), то bPostDel выполняется всегда после удаления. Устанавливать режим удаления желательно oBrw:SetDeleteMode( lOnOff, lConfirm, bDelete, bPostDel )

Haz: SergKis пишет: Тогда не забудь Ну все разжевал Тогда и я спрошу, вдруг мне так же повезет Как отловить событие изменения ширины колонки мышкой? Хочу автосохранение для пользователя сделать. Вчера озадачился не успел закончить. Отложил на послепраздники. Пока лезу через событие мыши - отпускание левой кнопки. Прямого признака колонки типа bHeightChange нет. Есть просто прорисовка вертикали vertline() Блок напрашивается туда, но пока хочу подобраться стандартными путями

SergKis: Haz пишет: вдруг мне так же повезет повезло или нет, сам решай - протокол сообщений (вывод вставлен в TSBROWSE:HANDLEEVENT и TCONTROL:HANDLEEVENT): ... TSBROWSE:HANDLEEVENT 135 WM_GETDLGCOD TSBROWSE:HANDLEEVENT 513 WM_LBUTTONDO TCONTROL:HANDLEEVENT 513 WM_LBUTTONDO TSBROWSE:HANDLEEVENT 512 WM_MOUSEMOVE TCONTROL:HANDLEEVENT 512 WM_MOUSEMOVE ... TCONTROL:HANDLEEVENT 512 WM_MOUSEMOVE TSBROWSE:HANDLEEVENT 512 WM_MOUSEMOVE TCONTROL:HANDLEEVENT 512 WM_MOUSEMOVE TSBROWSE:HANDLEEVENT 514 WM_LBUTTONUP TCONTROL:HANDLEEVENT 514 WM_LBUTTONUP TSBROWSE:HANDLEEVENT 533 WM_CAPTURECHANGED // думаю это TCONTROL:HANDLEEVENT 533 WM_CAPTURECHANGED TSBROWSE:HANDLEEVENT 132 WM_NCHITTEST TCONTROL:HANDLEEVENT 132 WM_NCHITTEST

SergKis: Haz На мой вхгляд мудришь, воспользуйся уже готовым[pre2] METHOD Destroy() CLASS TSBrowse LOCAL i Default ::lDestroy := .F. If ::bDestroy != Nil Eval(::bDestroy, Self) EndIf [/pre2] т.е. при завершении работы с Tsb сохраняй размеры колонок (с кол-вом их), а перед созданием tsb, считывай, а в процессе работы пусть двигают колонки сколько хотят

Haz: SergKis пишет: Destroy() Надо тестить сработает ли при закрытии парент окна. Мож проще будет на само окно повесить. За идею спасибо

SergKis: Haz пишет:сработает ли Думаю да, т.к. переменные объекта существуют, метотоды доступны и destroy() - собственный метод

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

SergKis: Haz пишет:у пользователей свои понятия, хлоп крестом на главном окне и и насрать на все методы Используй ON INTERACTIVECLOSE <interactivecloseprocedure> , проверяя, наличие окон в _HMG_aFormNames, кроме майн и при наличии таковых, можно спросить о завершении или просто возвращать .F. - запрещая закрытие маин окна.

SergKis: Haz при нажатии креста в маин окне срабатывает ф-я ReleaseAllWindows()б а там цепочка WM_CLOSE, WM_DESTROY для контролов каждого окна, т.е. аварийного завершения нет, есть нормальное екстренное завершение всех окон.

Haz: SergKis пишет: ON INTERACTIVECLOSE Сергей , да это все понятно. пока попытаюсь найти подход как узнать в процессе, а не бороться с последствиями.Ведь может быть и так - пользователь надвигал колонок под себя , уснул на ночь ( оставил задачу и сбежал домой ) и в это время запустились регламентные процедуры на серваке. Все висячие задачи срублены и с ними потеряны все настройки. У меня может паранойя , я и так протоколирую ВСЕ действия каждого пользователя по изменению данных, хочу еще и за настройками шпионить . А то иногда приходят умники , типа пол дня неразгибаясь работали и ничего не сохранено, Когда ему весь лог вываливаешь из которог следует что он в носу ковырял пол дня - вопросы сразу исчезают

SergKis: Haz пищет:хочу еще и за настройками шпионить пробни тогда, мне тоже интересно (из протокола выше) что выйдет. TSBROWSE:HANDLEEVENT 514 WM_LBUTTONUP TCONTROL:HANDLEEVENT 514 WM_LBUTTONUP TSBROWSE:HANDLEEVENT 533 WM_CAPTURECHANGED // думаю это TCONTROL:HANDLEEVENT 533 WM_CAPTURECHANGED

Haz: SergKis пишет: пробни тогда, мне тоже интересно (из протокола выше) что выйдет. договорились

SergKis: Haz пишет:договорились Но в реальности это столько мусора будет в логах ... может все таки кнопку (меню) для перевода в режим настройки (отключив др. режимы) и повторное нажатие для возврата в нормальный режим (сохранив настройки). тогда в журнале переход в настройки и завершение (ели было). я бы как то так шел.

Haz: SergKis пишет: На мой вхгляд мудришь, воспользуйся уже готовым METHOD Destroy() CLASS TSBrowse LOCAL i Default ::lDestroy := .F. If ::bDestroy != Nil Eval(::bDestroy, Self) EndIf Где ты это нашел взял последний MG там и в помине нет bDestroy Или это было предложение поменять исходник ?

SergKis: Haz пишет:Где ты это нашел Так в своей версии hmg, но уже так сроднился и забыл, что сам вставлял

Haz: SergKis пишет: Так в своей версии hmg, но уже так сроднился и забыл, что сам вставлял Как ты обновляешь MG этож надо незабыть все с чем сроднился )))

SergKis: Haz пишет:надо незабыть все с чем сроднился Ты прав, надо и в принципе у меня у переменных класса отмечено (в destroy() пропустил повторно) [pre2] DATA bDestroy // BK 14.02.2015 DATA lKeyChar AS LOGICAL INIT .F. // BK .F. - KeyChar(...) execute отключение ... METHOD KeyChar( nKey, nFlags ) CLASS TSBrowse ... If ! ::lKeyChar // BK Return 0 ElseIf ::nUserKey == 255 // from KeyDown() method Return 0 EndIf ... [/pre2]

Andrey: Haz пишет: я и так протоколирую ВСЕ действия каждого пользователя по изменению данных, хочу еще и за настройками шпионить Поправь исходники MiniGUI\SAMPLES\Advanced\Tsb_config, как себе сделаешь. Там я тоже делаю (Григорий помогал) сохранение колонок, шрифтов и размеров, но это давно было уже... Всем интересно будет знать - как правильно работать с Tsbrowse !

SergKis: Григорий, предложение по методу DeleteRow, сейчас он возвращает Self, а сделать надо возврат логический, тогда упроститься использования в простых ситуациях. [pre2] METHOD DeleteRow(lAll) CLASS TSBrowse Local lRecall, lUpStable, nAt, nRowPos, nRecNo, lRefresh, cAlias, lEval, uTemp Local lReturn := .F. DEFAULT lAll := .f. If ! ::lCanDelete .OR. ::nLen == 0 // Modificado por Carlos - Erro Keychar Return lReturn // Self EndIf If ::lIsDbf cAlias := ::cAlias EndIf nRecNo := ( cAlias )->( RecNo() ) lRecall := ! Set( _SET_DELETED ) lUpStable := ! lRecall If ! ::lIsTxt If ::lConfirm .and. !lAll .and.; ! MsgYesNo( If( ::lIsDbf, ::aMsg[ 37 ], ::aMsg[ 38 ] ), ::aMsg[ 39 ] ) Return lReturn // Self EndIf If ::lAppendMode Return lReturn // Self EndIf ::SetFocus() If ::lIsDbf ( cAlias )->( DbGoTo( nRecNo ) ) EndIf Do Case Case ::lIsDbf lEval := .T. If ::bDelete != Nil lEval := Eval( ::bDelete, nRecNo, Self ) EndIf If ValType( lEval ) == "L" .and. ! lEval Return lReturn // Self EndIf if !("SQL" $ ::cDriver) If ! ( cAlias )->( RLock() ) MsgStop( ::aMsg[ 40 ] , ::aMsg[ 28 ] ) Return lReturn // Self EndIf endif If ! ( cAlias )->( Deleted() ) ( cAlias )->( DbDelete() ) lReturn := .T. if !("SQL" $ ::cDriver) ( cAlias )->( DbUnlock() ) endif ::nLen := ( cAlias )->( Eval( ::bLogicLen ) ) If lUpStable ( cAlias )->( DbSkip() ) lRefresh := ( cAlias )->( EOF() ) ( cAlias )->( DbSkip( -1 ) ) ::nRowPos -= If( lRefresh .and. ; ! ( cAlias )->( BOF() ), 1, 0 ) ::Refresh( .T. ) EndIf ElseIf lRecall ( cAlias )->( DbRecall() ) ( cAlias )->( DbUnlock() ) lReturn := .T. EndIf If ::lCanAppend .and. ::nLen == 0 ::nRowPos := ::nColPos := 1 ::PostMsg( WM_KEYDOWN, VK_DOWN, nMakeLong( 0, 0 ) ) EndIf If ::bPostDel != Nil Eval( ::bPostDel , Self ) EndIf ::lHasChanged := .T. Case ::lIsArr nAt := ::nAt nRowPos := ::nRowPos lEval := .T. If ::bDelete != Nil lEval := Eval( ::bDelete, nAt, lAll, Self ) EndIf If ValType( lEval ) == "L" .and. ! lEval Return lReturn // Self EndIf If lAll ::aArray := {} ::aSelected := {} Else ADel( ::aArray, nAt ) ASize( ::aArray, Len( ::aArray ) - 1 ) IF ::lCanSelect .and. Len( ::aSelected ) > 0 If ( uTemp := AScan( ::aSelected, nAt ) ) > 0 ADel( ::aSelected, uTemp ) ASize( ::aSelected, Len( ::aSelected ) - 1 ) EndIf AEval( ::aSelected, {|x,nEle| ::aSelected[nEle] := IF(x > nAt, x-1, x)} ) ENDIF EndIf If Len( ::aArray ) == 0 ::aArray := { AClone( ::aDefValue ) } ::lPhantArrRow := .T. If ::aArray[ 1, 1 ] == Nil ADel( ::aArray[ 1 ], 1 ) ASize( ::aArray[ 1 ], Len( ::aArray[ 1 ] ) - 1 ) EndIf EndIf If ::bPostDel != Nil Eval( ::bPostDel , Self ) EndIf lReturn := .T. ::lHasChanged := .T. ::nLen := Len( ::aArray ) ::nAt := Min( nAt, ::nLen ) ::nRowPos := Min( nRowPos, ::nLen ) ::Refresh( ::nLen < ::nRowCount() ) ::DrawSelect() Endcase Else ::SetFocus() ::DrawSelect() EndIf Return lReturn // Self [/pre2] Использование If oBrw:DeleteRow() ... EndIf

gfilatov2002: SergKis пишет: сделать надо возврат логический Не вопрос, конечно, сделаю, если это полезно для работы с этим методом

Haz: Haz пишет: Как отловить событие изменения ширины колонки мышкой? Вобщем подобраться стандартными средствами удалось только через событие отпускания левой мыши с анализом позиции курсора ( в заголовке и какая колонка ). При этом есть погрешность позиции по горизонтали примерно в 10 пикселей, т.к. курсор WS имеет граничные допуски. Потестировал - не понравилось т.к. все же через событие мыши это не правильно. Все остальные попытки так или иначе требуют изменения исходников, поэтому решил если менять то менять правильно и адресно. в TsBrowse.prg добавил [pre2] DATA bLineDrag DATA bColDrag [/pre2] и их обработку [pre2] :12077 If nColPixPos == Nil .and. nColInit == Nil // We have finish draging ::aColSizes[ nsCol ] -= ( nsWidth - nsOldPixPos ) ::aColumns[ nsCol ]:nWidth -= ( nsWidth - nsOldPixPos ) ::Refresh() if ValType(::bLineDrag) == "B" Eval( ::bLineDrag, nsCol, ( nsOldPixPos - nsWidth) ) end EndIf [/pre2] [pre2] :6986 // we gotta be on header row within listbox and not same colm If nClickRow == 0 .or. nClickRow == -2 if nColPix > ::nLeft .and. ::nDragCol != nDestCol If ::lMoveCols ::MoveColumn( ::nDragCol, nDestCol ) Else ::Exchange( ::nDragCol, nDestCol ) EndIf if ValType(::bColDrag) == "B" Eval(::bColDrag, nDestCol, ::nDragCol ) end elseif ::nDragCol = nDestCol If ::aColumns[ nDestCol ]:bHLClicked != Nil ::DrawHeaders() Eval( ::aColumns[ nDestCol ]:bHLClicked, nRowPix, nColPix, ::nAt, Self ) ::DrawHeaders() EndIf Endif EndIf EndIf EndIf [/pre2] Теперь события изменения ширины колонки и перетаскивания колонки ловятся элементарно и автосохранение позиций и ширин делается тоже элементарно [pre2] oBrw:bLineDrag := {|a,b| MsgDebug(oBrw:GetColumn(a):cName, b)} // где a - номер колонки в которой изменили ширину, b -на сколько изменили oBrw:bColDrag := {|a,b| MsgDebug(oBrw:GetColumn(a):cName, b, a)} // где a - новый номер колонки которую перетащили , b - старый номер [/pre2]

SergKis: Haz просьба добавить Self в вызов блоков кода Eval( ::bLineDrag, nsCol, ( nsOldPixPos - nsWidth), Self ) Eval(::bColDrag, nDestCol, ::nDragCol, Self )

Haz: SergKis пишет: просьба добавить Self в вызов блоков кода я то добавлю, не вопрос Ждем что Григорий скажет

gfilatov2002: Haz пишет: что Григорий скажет Благодарю за помощь Конечно, я добавил обработку этих 2-х кодовых блоков в класс TsBrowse. Еще бы не помешал небольшой пример их использования...

Haz: gfilatov2002 пишет: Конечно, я добавил обработку этих 2-х кодовых блоков в класс TsBrowse. Отлично Еще бы не помешал небольшой пример их использования... завтра постараюсь маленький примерчик сделать

Haz: Haz пишет: завтра постараюсь маленький примерчик сделать Вобщем как то так, в примере просто ловим изменение ширины и позиции в колонке и тупо пишем в INI При старте - читаем из INI [pre2] #include "minigui.ch" #include "TSBrowse.ch" MEMVAR aFont PROCEDURE Main LOCAL aStr := {} LOCAL cDbf := "TEST.DBF" LOCAL cAlias := "" LOCAL n := 0 SET DATE FORMAT 'DD.MM.YYYY' REQUEST DBFCDX RDDSETDEFAULT('DBFCDX') IF ! File( cDbf ) AAdd( aStr, { 'F1', 'D', 8, 0 } ) AAdd( aStr, { 'F2', 'C', 60, 0 } ) AAdd( aStr, { 'F3', 'N', 10, 2 } ) AAdd( aStr, { 'F4', 'L', 1, 0 } ) DbCreate( cDbf, aStr ) END USE (cDbf) ALIAS "TEST" NEW WHILE TEST->(RecCount()) < 100 TEST->(dbAppend()) TEST->F1 := Date() + n++ TEST->F2 := STR(n) TEST->F3 := n TEST->F4 := (n % 2) == 0 END DEFINE WINDOW Form_0 ; At 0, 0 ; WIDTH 600 ; HEIGHT 400 ; TITLE "TsBrowse Save/Restore settings Demo" ; MAIN ; NOMAXIMIZE NOSIZE DEFINE STATUSBAR STATUSITEM "Item 1" WIDTH 0 FONTCOLOR BLACK STATUSITEM "Item 2" WIDTH 230 FONTCOLOR BLACK STATUSITEM "Item 3" WIDTH 230 FONTCOLOR BLACK STATUSITEM "Item 4" WIDTH 230 FONTCOLOR BLACK DATE CLOCK KEYBOARD END STATUSBAR CreateBrowse() MsgBox( "Restoring from INI" ) END WINDOW DoMethod( "Form_0", "Center" ) DoMethod( "Form_0", "Activate" ) RETURN FUNCTION CreateBrowse() LOCAL oBrw LOCAL i LOCAL aStr := {} DEFINE TBROWSE oBrw ; AT 5, 5 ; ALIAS "TEST" ; OF Form_0 ; WIDTH Form_0.WIDTH - 2 * GetBorderWidth() ; HEIGHT Form_0.HEIGHT - GetTitleHeight() - GetTitleHeight() - ; GetProperty( "Form_0", "StatusBar", "Height" ) - 2 * GetBorderHeight() ; GRID ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 ; :SetAppendMode( .F. ) :SetDeleteMode( .F. ) :lNoHScroll := .T. :lCellBrw := .F. END TBROWSE ReadSettings( oBrw ) oBrw:nWheelLines := 1 oBrw:nClrLine := COLOR_GRID oBrw:lNoChangeOrd := TRUE oBrw:lCellBrw := TRUE oBrw:lNoVScroll := TRUE oBrw:hBrush := CreateSolidBrush( 242, 245, 204 ) // prepare for showing of Double cursor AEval( oBrw:aColumns, {| oCol| oCol:lFixLite := oCol:lEdit := TRUE } ) oBrw:nHeightCell += 10 oBrw:nHeightHead += 5 oBrw:SetColor( { 1 }, { RGB( 0, 12, 120 ) } ) oBrw:SetColor( { 2 }, { RGB( 242, 245, 204 ) } ) oBrw:SetColor( { 5 }, { RGB( 0, 0, 0 ) } ) oBrw:SetColor( { 6 }, { {|a, b, c| IF( c:nCell == b, { RGB( 66, 255, 236 ), RGB( 111, 183, 155 ) }, ; { RGB( 255, 255, 255 ), RGB( 200, 200, 200 ) } ) } } ) // cursor backcolor oBrw:bLineDrag := {|a,b,c| SaveSettings(a,b,c, "Width")} oBrw:bColDrag := {|a,b,c| SaveSettings(a,b,c, "Position")} RETURN NIL FUNC SaveSettings( a, b, c, cKey ) local hIni := HB_Hash() local cIniFile := SUBSTR( Exename(), 1, RAT( '.', Exename() ) ) + 'ini' local n := 0 local cSection := c:GetColumn(a):cName FOR n := 1 TO c:nColCount() hIni[ c:GetColumn(n):cName ] := hb_hash() hIni[ c:GetColumn(n):cName ]["Position"] := n hIni[ c:GetColumn(n):cName ]["Width"] := c:GetColumn(n):nWidth hIni[ c:GetColumn(n):cName ]["Heading"] := c:GetColumn(n):cHeading END hb_iniWrite( cIniFile, hIni ) MsgBox(IF( UPPER( cKey ) == "WIDTH", "Width changed and stored in INI", "Position Changed and stored in INI")) RETURN NIL FUNCTION ReadSettings( oBrw ) local hIni := HB_Hash() local cIniFile := SUBSTR( Exename(), 1, RAT( '.', Exename() ) ) + 'ini' local n := 0 local aArray := {}, aField := {} IF !File( cIniFile ) FOR n := 1 TO TEST->(FCOUNT()) hIni[ TEST->(Field(n)) ] := hb_hash() hIni[ TEST->(Field(n)) ]["Position"] := n hIni[ TEST->(Field(n)) ]["Width"] := 100 hIni[ TEST->(Field(n)) ]["Heading"] := "F" + NTOC(n) END hb_iniWrite( cIniFile, hIni ) aField := { "F2", "F1", "F3", "F4" } ELSE hIni := hb_iniRead( cIniFile ) FOR n := 1 TO TEST->(FCOUNT()) AADD( aArray, {TEST->(Field(n)), CTON(hIni[ TEST->(Field(n)) ]["Position"]) } ) END // Sorting column aSort( aArray,,, { |a,b| a[2] < b[2] } ) aEval( aArray, {|e| AADD( aField, e[1] )} ) END LoadFields( "oBrw", "Form_0", .F., aField) // Set column width oBrw:SetColSize( oBrw:nColumn( "F1" ), CTON(hIni[ "F1" ]["Width"]) ) oBrw:SetColSize( oBrw:nColumn( "F2" ), CTON(hIni[ "F2" ]["Width"]) ) oBrw:SetColSize( oBrw:nColumn( "F3" ), CTON(hIni[ "F3" ]["Width"]) ) oBrw:SetColSize( oBrw:nColumn( "F4" ), CTON(hIni[ "F4" ]["Width"]) ) RETURN NIL [/pre2]

gfilatov2002: Haz пишет: в примере просто ловим изменение ширины и позиции в колонке Благодарю за пример

Haz: gfilatov2002 пишет: Благодарю за пример Немного поленился и сохраняю все колонки , а не только ту которая изменилась. Но в блок номер измененной колонки передается и кому захочется - можно сделать самостоятельно .

gfilatov2002: gfilatov2002 пишет: Благодарю за пример Выкладываю итоговый вариант для проверки [pre]/* * MINIGUI - Harbour Win32 GUI library Demo * * Author: Igor Nazarov * * Revised by Grigory Filatov <gfilatov@inbox.ru> */ #include "minigui.ch" #include "TSBrowse.ch" REQUEST DBFCDX PROCEDURE Main LOCAL aStr := {} LOCAL cDbf := "TEST.DBF" LOCAL n := 0 SET DATE FORMAT 'DD.MM.YYYY' rddSetDefault( 'DBFCDX' ) IF ! File( cDbf ) AAdd( aStr, { 'F1', 'D', 8, 0 } ) AAdd( aStr, { 'F2', 'C', 60, 0 } ) AAdd( aStr, { 'F3', 'N', 10, 2 } ) AAdd( aStr, { 'F4', 'L', 1, 0 } ) dbCreate( cDbf, aStr ) ENDIF USE ( cDbf ) ALIAS "TEST" NEW WHILE TEST->( RecCount() ) < 100 TEST->( dbAppend() ) TEST->F1 := Date() + n++ TEST->F2 := Str( n ) TEST->F3 := n TEST->F4 := ( n % 2 ) == 0 END DEFINE WINDOW Form_0 ; At 0, 0 ; WIDTH 600 ; HEIGHT 400 ; TITLE "TsBrowse Save/Restore Settings Demo" ; MAIN ; NOMAXIMIZE NOSIZE ; ON RELEASE dbCloseArea( "TEST" ) DEFINE STATUSBAR STATUSITEM "Item 1" WIDTH 0 STATUSITEM "TsBrowse Power Ready" WIDTH 230 FONTCOLOR BLUE DATE CLOCK KEYBOARD END STATUSBAR CreateBrowse() END WINDOW DoMethod( "Form_0", "Center" ) DoMethod( "Form_0", "Activate" ) RETURN FUNCTION CreateBrowse() LOCAL oBrw DEFINE TBROWSE oBrw ; AT 5, 5 ; ALIAS "TEST" ; OF Form_0 ; WIDTH Form_0.Width - 2 * GetBorderWidth() ; HEIGHT Form_0.Height - GetTitleHeight() - ; GetProperty( "Form_0", "StatusBar", "Height" ) - 2 * GetBorderHeight() ; GRID ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 :SetAppendMode( .F. ) :SetDeleteMode( .F. ) :lNoHScroll := .T. :lCellBrw := .F. :lInsertMode := .T. END TBROWSE // Restoring settings from INI ReadSettings( oBrw ) oBrw:nWheelLines := 1 oBrw:nClrLine := COLOR_GRID oBrw:lNoChangeOrd := TRUE oBrw:lCellBrw := TRUE oBrw:lNoVScroll := TRUE oBrw:hBrush := CreateSolidBrush( 242, 245, 204 ) // prepare for showing of Double cursor AEval( oBrw:aColumns, {| oCol | oCol:lFixLite := oCol:lEdit := TRUE } ) oBrw:nHeightCell += 10 oBrw:nHeightHead += 5 oBrw:SetColor( { 1 }, { RGB( 0, 12, 120 ) } ) oBrw:SetColor( { 2 }, { RGB( 242, 245, 204 ) } ) oBrw:SetColor( { 5 }, { RGB( 0, 0, 0 ) } ) oBrw:SetColor( { 6 }, { { | a, b, oBr | IF( oBr:nCell == b, { RGB( 66, 255, 236 ), RGB( 111, 183, 155 ) }, ; { RGB( 255, 255, 255 ), RGB( 200, 200, 200 ) } ) } } ) // cursor backcolor oBrw:bLineDrag := { | a, b, oBr | SaveSettings( a, b, oBr, "Width" ) } oBrw:bColDrag := { | a, b, oBr | SaveSettings( a, b, oBr, "Position" ) } RETURN NIL STATIC FUNCTION SaveSettings( a, b, oBr, cKey ) LOCAL hIni := hb_Hash() LOCAL cIniFile := ChangeFileExt( Application.ExeName, '.ini' ) LOCAL n HB_SYMBOL_UNUSED( a ) HB_SYMBOL_UNUSED( b ) FOR n := 1 TO oBr:nColCount() hIni[ oBr:GetColumn( n ):cName ] := hb_Hash() hIni[ oBr:GetColumn( n ):cName ][ "Position" ] := hb_ntos( n ) hIni[ oBr:GetColumn( n ):cName ][ "Width" ] := hb_ntos( oBr:GetColumn( n ):nWidth ) hIni[ oBr:GetColumn( n ):cName ][ "Heading" ] := oBr:GetColumn( n ):cHeading NEXT hb_iniWrite( cIniFile, hIni ) MsgInfo( iif( Upper( cKey ) == "WIDTH", "Width changed and stored in INI", "Position changed and stored in INI" ) ) RETURN NIL STATIC FUNCTION ReadSettings( oBrw ) LOCAL hIni := hb_Hash() LOCAL cIniFile := ChangeFileExt( Application.ExeName, '.ini' ) LOCAL n LOCAL aArray := {}, aField := {} IF ! File( cIniFile ) FOR n := 1 TO TEST->( FCount() ) hIni[ TEST->( Field( n ) ) ] := hb_Hash() hIni[ TEST->( Field( n ) ) ][ "Position" ] := hb_ntos( n ) hIni[ TEST->( Field( n ) ) ][ "Width" ] := hb_ntos( 100 ) hIni[ TEST->( Field( n ) ) ][ "Heading" ] := "F" + NTOC( n ) NEXT hb_iniWrite( cIniFile, hIni ) // initial column order aField := { "F2", "F1", "F3", "F4" } ELSE hIni := hb_iniRead( cIniFile ) FOR n := 1 TO TEST->( FCount() ) AAdd( aArray, { TEST->( Field( n ) ), CTON( hIni[ TEST->( Field( n ) ) ][ "Position" ] ) } ) NEXT // Sorting column ASort( aArray,,, { | a, b | a[ 2 ] < b[ 2 ] } ) // Fill field array AEval( aArray, { | e | AAdd( aField, e[ 1 ] ) } ) ENDIF LoadFields( "oBrw", "Form_0", .F., aField ) // Set column width oBrw:SetColSize( oBrw:nColumn( "F1" ), CTON( hIni[ "F1" ][ "Width" ] ) ) oBrw:SetColSize( oBrw:nColumn( "F2" ), CTON( hIni[ "F2" ][ "Width" ] ) ) oBrw:SetColSize( oBrw:nColumn( "F3" ), CTON( hIni[ "F3" ][ "Width" ] ) ) oBrw:SetColSize( oBrw:nColumn( "F4" ), CTON( hIni[ "F4" ][ "Width" ] ) ) RETURN NIL [/pre]

Haz: gfilatov2002 пишет: Выкладываю итоговый вариант для проверки Проверил, работает однако только я забыл добавить в ReadSettings() oBrw:GetColumn( "F1" ):cHeading := hIni[ "F1" ][ "Heading" ] oBrw:GetColumn( "F2" ):cHeading := hIni[ "F2" ][ "Heading" ] oBrw:GetColumn( "F3" ):cHeading := hIni[ "F3" ][ "Heading" ] oBrw:GetColumn( "F4" ):cHeading := hIni[ "F4" ][ "Heading" ] а то заголовки из ини не читает

Alex_Cher: Haz пишет: Проверил, работает однако ... мужики, а у меня не работает, в чем проблема ? Application: C:\MiniGUI\SAMPLES\MY_BASIC\Ishod\demo.exe Date: 05.05.2016 Time: 08:56:40 Time from start: 0 days 0 hours 0 mins 0 secs Error BASE/1005 Message not found: TSBROWSE:_LINSERTMODE Called from __ERRRT_SBASE(0) Called from TSBROWSE:ERROR(0) Called from (b)HBOBJECT(0) Called from TSBROWSE:MSGNOTFOUND(0) Called from TSBROWSE:_LINSERTMODE(0) Called from CREATEBROWSE(91) Called from MAIN(60)

Haz: Alex_Cher пишет: мужики, а у меня не работает, в чем проблема ? Ждать новой сборки или самостоятельно внести все изменения в исходники библиотеки

gfilatov2002: Haz пишет: Ждать новой сборки Выпустил сегодня первый релиз-кандидат для новой сборки 16.05 Спмсок изменений см. ниже [pre2] * Fixed: The problem with a splitbox handling into the Modal windows (introduced in the build 16.03). Contributed by Grigory Filatov <gfilatov@inbox.ru> * Fixed: The problem with an assigning of the 'Value' property at deleting of the last row in a celled GRID. Contributed by Grigory Filatov <gfilatov@inbox.ru> (see demo2.prg in folder \samples\Basic\Grid_7) * Enhanced: TOOLBAR control supports the changing of a ToolButton 'Picture' property at runtime for BMP, PNG, GIF and TIF images. You can set/get this property: - function syntax: SetProperty ( FormName, ToolButtonName, 'Picture', cImage ) cImage := GetProperty ( FormName, ToolButtonName, 'Picture' ) - pseudo-OOP syntax: FormName.ToolBarName.ToolButtonName.Picture := cImage FormName.ToolButtonName.Picture := cImage Requested by Ronaldo Batista Lima. Based upon a contribution by Claudio Soto <srvet@adinet.com.uy> (see demo1.prg in folder \samples\Basic\CONTAINERS\TOOLBAR) * Enhanced: The Browse and Grid controls supports now the code-blocks with an input Value as parameter in the VALIDMESSAGES array. Sample code: VALIDMESSAGES { 'Code Range: 0-1000', 'First Name Cannot Be Empty',; 'Last Name Cannot Be Empty',; {|uVal| MsgStop('Check your input value:' + CRLF + DtoC( uVal))}, , } Contributed by Grigory Filatov <gfilatov@inbox.ru> (see browse5.prg in folder \samples\Basic\BROWSE_3) * Modified: The 'Notify Balloon Click' event is available for MAIN window only. Contributed by Grigory Filatov <gfilatov@inbox.ru> (see demo in folder \samples\Advanced\TrayBalloon_2) * Updated: The C-code cleaning for warnings at MinGW32 compiler with a warning level is set to max in hbmk2 utility. The foregoing warnings were found into the Minigui core, PropGrid and Socket libraries. Reported by Pete D. <pete_westg/at/yahoo.gr>. Contributed by Grigory Filatov <gfilatov@inbox.ru> * Updated: Synchronized Extended HMG for compatibility with Official HMG: - Changed: BROWSE edit is always inplace without regarding about 'InPlace' value (Edit and Inplace properties has now the same meaning). Note: an obsolete behaviour may be restored via adding the definition of the constant HMG_LEGACY_ON to the header file minigui.ch. (see Browse2.prg in folder \samples\Basic\Browse_1) * Updated: Header file i_hmgcompat.ch for compatibility with mixed button's Picture Alignment 'Right' and 'Bottom' styles. Contributed by Grigory Filatov <gfilatov@inbox.ru> * Updated: 'Bos Taurus' Graphics Library version 1.06: - added the new functions BT_DrawTextEx(), BT_DrawTextSize(), BT_DrawPolygon(), BT_DrawPolyBezier(), BT_DrawArc(), BT_DrawChord() and BT_DrawPie(). Based upon a contribution of Claudio Soto <srvet@adinet.com.uy> (see source in folder \Source\BosTaurus) * Updated: PropSheet library source code (see in folder \Source\PropSheet): - Fixed: code cleaning for warnings with Harbour switch -w2. Contributed by Grigory Filatov <gfilatov@inbox.ru> * Updated: Adaptation FiveWin Class TSBrowse 9.0 in HMG: - added handling of the variable :lInsertMode in the method Edit(); - added the new code-blocks bLineDrag and bColDrag; - method DeleteRow() returns a logical value now. Contributed by Igor Nazarov and SergKis (see demo in folder \samples\Advanced\Tsb_linedrag) * Updated: HbSQLite3 library: - update for using SQLITE3 version 3.13.0dev (from 3.12.2). Contributed by Grigory Filatov <gfilatov@inbox.ru> * Updated: Harbour Compiler 3.2.0dev (SVN 2016-04-29 16:25). Contributed by Grigory Filatov <gfilatov@inbox.ru> (look at ReadMe.txt in folder \harbour) * New: 'Labeled TextBox pseudo-control' sample. Based upon a contribution of Pete D. <pete_westg/at/yahoo.gr> (see in folder \samples\Basic\Say_Get) * New: 'SplitBox Resize' sample. Based upon a contribution of Claudio Soto <srvet@adinet.com.uy> (see demo8.prg in folder \samples\Basic\CONTAINERS\Splitbox) * Updated: 'MiniGUI Browse' samples. Contributed by Grigory Filatov <gfilatov@inbox.ru> (see in folder \samples\Basic\BROWSE_3) * Updated: SQLCipher encryption for SQLite (https://www.zetetic.net/sqlcipher). It is Mingw32-based library only. Contributed by S.Rathinagiri <srgiri@dataone.in> (see in folder \samples\sqlcipher) * Updated: 'Minigui Form Designer Utility' sample: - added tree and timer controls; - added compilation via batch file build.bat; - fixed warnings in PRG output. Contributed by Rafael Moran <webrmoran[at]yahool.com>. Revised by Grigory Filatov <gfilatov@inbox.ru> (see in folder \Utils\xForm) [/pre2] Благодарю за поддержку данного проекта Также принимаются пожервования на PayPal от заинтересованных в выпуске новых сборок

Vlad04: 2 tsbrowsa- brw_1(таблица1) и brw_2 (таблица2) на форме. Имя формы через подстановку &cForm. Как организовать отображение в brw_2 данных, если таблица2 подчинена к таблице1(возможно set ralation или OrdScope или filter )

Haz: Vlad04 пишет: Как организовать отображение в brw_2 данных, если таблица2 подчинена к таблице1(возможно set ralation или OrdScope или filter ) если отношение один к одному то можно и реляцию, если один ко многим то только скоп или фильтр. Я с ADS ставлю фильтр ( он там быстрый ) в других RDD SCOPE предпочтительнее. Методика простая, на brw_1:bChange вешается процедура которая ставит скоп или фильтр brw_2 [pre2]brw_1:bChange := { || (brw_2:cAlias)->( тут фильтр или скоп ), brw_2:Reset() }[/pre2] Посмотри в примерах tsb_filter.prg, там фильтр ставиться в зависимости от содержимого строки ввода.

Vlad04: Haz brw_1:bChange := { || (brw_2:cAlias)->( тут фильтр или скоп ), brw_2:Reset() } Ошибка Reset не экспортируемый метод У меня так DEFINE TBROWSE Brw_1 ; AT 40, 10 ; OF &(cForm) ; ALIAS cBase ; WIDTH nWidth-5 ; HEIGHT nHeight-500 ; FONT "MS Sans Serif" ; SIZE 10 BOLD ON CHANGE {||ScRoll(cForm,Brw_1),UpdateItems(),brw_2:Reset() }

Vlad04: Из формы могу обратиться к объекту формы , к примеру FUNCTION TbMove(met,cForm,oBrw,cBase) // Select(oBrw:cAlias) Alias(cBase) DO CASE CASE met == 1 oBrw:GoTop() ... Но с объекта формы Brw_2 эту же функцию вызвать не могу !

gfilatov2002: Vlad04 пишет: Как организовать отображение в brw_2 данных, если таблица2 подчинена к таблице1 Попробуйте посмотреть как это сделано в базовом примере из папки samples\Advanced\TsBrowse [pre2]... Else // One to More @ 0, 0 TBROWSE oBrw2 ALIAS "sta" WIDTH 800 HEIGHT 185 ; FONT "Font_1" ON CHANGE SincroTb(obrw,invert) ; CELL oBrw2:LoadFields() oBrw2:nWheelLines := 1 @ 185, 0 TBROWSE oBrw ALIAS "Employee" WIDTH 800 HEIGHT 185 ; FONT "Font_1" CELL oBrw:LoadFields() oBrw:Exchange(3, 5) oBrw:ChangeFont(GetFontHandle( "Font_4" ), 0, 2 ) oBrw:ChangeFont(GetFontHandle( "Font_1" ), 0, 1 ) oBrw:ChangeFont(GetFontHandle( "Font_3" ), 3, 1 ) oBrw:nWheelLines := 1 FORM_10.OBRW2.SETFOCUS ... *------------------------------------------------------------------------------* Function SincroTb(obrw,Invert) *------------------------------------------------------------------------------* LOCAL cSelState default invert to .F. if invert cSelState := Employee->state oBrw:SetFilter( "State", cSelState ) else cSelState := SubStr(sta->state,1,2) oBrw:SetFilter( "State+Last", cSelState ) Endif _setitem("statusbar","Form_10",2,cSelState) oBrw:cPrefix := cSelState IF FieldGet(FieldPos("State")) != cSelState oBrw:Enabled(.f.) ELSE oBrw:Enabled(.T.) endif oBrw:Refresh( .T. ) oBrw:lHasChanged := .T. oBrw:lNoGrayBar := .T. return NIL [/pre2]Эта конструкция работает вполне прилично для небольших баз (до 5 тысяч записей)

Haz: Vlad04 пишет: Ошибка Reset не экспортируемый метод У меня так brw_1 j объявлен раньше Brw_2 и в момент интерпритации кода DEFINE BROWSE Brw_1 и прорисовке бровса выполняется его ::bChange который пока ничего не знает о brw_2 но его использует . Постоянно наступал на эти грабли когда один контрол использует данные другого ниже по тексту. Вариантов решения много, вот парочка 1 Располагать контролы в тексте PRG в порядке их логического использования ( если поменять brw_1 и brw_2 местами - скорее всего заработает ) 2 Использовать на форме флаг CHECKBOX lReady c Visible .F. и выставлять его в .Т. перед Form.Activate, далее примерно так IF( Getproperty( 'Form', lReady, 'Value'), brw_2:Reset(), NIL ) 3 вместо флага проверять существование переменной brw_2 и т.д. на что фантазии хватит PS всего кода ты не дал, поэтому и рекомендации общие

Vlad04: ок Все отлично, переставил brw_1 и brw_2 местами и все заработало ! Однако

Andrey: Всем привет. Очередная ошибка у меня. Делаю таблицу, вывод первой колонки делаю так: ADD COLUMN TO oBrwS HEADER "№№" ; DATA {|| OrdKeyNo() } ; ........... Вот результат: Стоит только маркером/курсором или мышкой сдвинуть ниже последней записи , как нумерация разрушается и при движении курсором меняется нумерация первой колонки: Как исправить (убрать) это изменение ?

Dima: Andrey пишет: DATA {|| OrdKeyNo() } ; OrdKeyNo() не нужно уточнить алиасом ?

Haz: Dima пишет: OrdKeyNo() не нужно уточнить алиасом ? Обязательно , OrdkeyNo() работает в текущей рабочей области , а какая она текущая из картинки не понять Думаю все станет ясно если написать так {|| Select() }

Andrey: Dima пишет: OrdKeyNo() не нужно уточнить алиасом ? Да можно. Это не поможет. Там удалённые записи в нумерацию встревают. Всего в базе 28 записей, из них 7 не удалённых !DELETED(). Фильтра нет. Т.е. использую просто SET DELETED ON P.S. пробовал поставить: DATA {|| (Alias())->(OrdKeyNo()) } - такая же фигня.

Haz: Andrey пишет: Т.е. использую просто SET DELETED ON База одна открыта ? SET DELETED ON - команда которая включает игнорирование удаленных правда INDEX и REINDEX всегда игнорируют установку SET DELETED но это не тот случай.

Andrey: Если делаю SET DELETED OFF, то будет так: Черным цветом, я удалённые записи раскрашиваю. Haz пишет: База одна открыта ? Нет, несколько - 5 штук. Одна основная и 4 для set relation.

Haz: Haz пишет: если написать так DATA {|| Select() } что покажет ?

Haz: Andrey пишет: DATA {|| (Alias())->(OrdKeyNo()) } - такая же фигня. извини , но написанную фигню, фигню и показывает DATA {|| (oBrw:cAlias)->(OrdKeyNo())

Haz: Сделай так , уверен все увидишь DATA {|| Select() }

Dima: Андрей пишет: DATA {|| (Alias())->(OrdKeyNo()) } - такая же фигня. Ну ясный пень. Я бы указал реальный алиас по которому ходишь , а так выходит что если ты где то сменил рабочую область то фигню и получишь.

Andrey: Вот переделанный пример Tsb_config версии 1.2 - https://cloud.mail.ru/public/2CHr/h9u2vn7JR Там просто ставлю: ADD COLUMN TO oBrw ; HEADER "№№" ; DATA {||OrdKeyNo()} ; Но там используется фильтр. А у меня без фильтра.

Haz: Haz пишет: Haz пишет:  цитата: если написать так DATA {|| Select() } что покажет ? а потом будем теоретизировать про фильтры

Andrey: Haz пишет: если написать так DATA {|| Select() } Вот что показывает: Haz пишет: извини , но написанную фигню, фигню и показывает DATA {|| (oBrw:cAlias)->(OrdKeyNo()) Написал как советовал. Всё равно нумерация сбивается.

Haz: Andrey пишет: Вот что показывает: а ниже курсором проехать ...

Andrey: Ничего не происходит. Показывает всегда 1, т.е. select() !

Haz: вот так проехать ! Andrey пишет: сдвинуть ниже последней записи

Haz: Andrey пишет: Написал как советовал. Всё равно нумерация сбивается. Как именно , код покажи

Haz: Почему в картинках ниже 3 записи строки другого цвета ? какое условие их красит по разному ?

Andrey: Haz пишет: Как именно , код покажи ADD COLUMN TO oBrwS HEADER "№№" ; DATA {|| (oBrwS:cAlias)->(OrdKeyNo()) } ; Haz пишет: Почему в картинках ниже 3 записи строки другого цвета ? какое условие их красит по разному ? ; //* -------- Цвет условий в TBrowse ---------------------- Цвет_условия_1 = { { || Master->KDoljn == 0 .OR. Master->KMaster == 0 }, "12/4" } Цвет_условия_2 = { { || LEN( ALLTRIM(Master->Master) ) == 0 } , {128, 255} } Цвет_условия_3 = { { || Master->KDel == 0 }, "4/2" } Цвет_условия_4 = { { || Master->KDel == 2 }, "8/2" } Цвет_условия_5 = { { || Master->KSITE == 1 }, "0/2" } Цвет_условия_6 = { { || Master->KSITE == 9 }, "4/2" } Цвет_условия_7 = { { || Master->KDel == 1 }, "14/2" } Цвет_условия_8 = { { || Master->KDel == 3 }, "15/2" } Цвет_условия_9 = { { || 1 == 1 }, { MyRGB(COLOR_LGREEN()), MyRGB({0,0,0}) } } Цвета вытащены в ини-файл, функция покраски как в SAMPLES\Advanced\Tsb_config

Andrey: Как уходишь за границу записей, так нумерация сбивается у функции (oBrwS:cAlias)->(OrdKeyNo()) и oBrwS:nAt : DEFINE TBROWSE oBrwS ; ON CHANGE { || ChangeTable() } ; ON GOTFOCUS ChangeTable() ; //////////////////////////////////////////////////////////// STATIC FUNCTION ChangeTable() LOCAL cVal, nLen, cLen, cText LOCAL cForm := oBrwS:cParentWnd LOCAL lMark, lPrint, lMail, lSave LOCAL cCaption1, cCaption2 cVal := HB_NToS( (oBrwS:cAlias)->(OrdKeyNo()) ) nLen := (oBrwS:cAlias)->(OrdKeyCount()) cLen := HB_NToS( nLen ) cCaption1 := "Текущая запись базы: " + HB_NtoS((oBrwS:cAlias)->(RecNo())) cCaption2 := "Номер записи таблицы: " + HB_NtoS(oBrwS:nAt) MenuCaptionSet( "MYTABLETEXT " , cForm , cCaption1 ) MenuCaptionSet( "MYTABLERECNO" , cForm , cCaption2 ) oBrwS:aColumns[3]:cFooting := { || " Запись: " + cVal + "/" + cLen + " " } oBrwS:DrawFooters() // выполнить прорисовку подвала TblFocus() RETURN Nil

Haz: Andrey пишет: Как уходишь за границу записей, так нумерация сбивается у функции (oBrwS:cAlias)->(OrdKeyNo()) и oBrwS:nAt nAt там вообще вне всякой логики , не годится как нумератор

Haz: По коду, визуально все ок какой управляющий индекс задан ? вот это TblFocus() что ?

Haz: Скорее всего это SET DELETED ON - команда которая включает игнорирование удаленных правда INDEX и REINDEX всегда игнорируют установку SET DELETED но это не тот случай. то есть OrdKeyNo() всегда учитывает удаленные записи, как ни ставь SET DELETED Если это не условный индекс !Deleted() , такой индекс пропустит удаленные. Вопрос почему идет смена нумерации остается открытым , мне все же кажется что где-то меняется рабочая область или управляющий индекс. выведи в поле не просто номер OrdKeyNo() , а Alias() + "/" + oBrwS:cAlias + "/" + NTOC((oBrwS:cAlias)->(OrdKeyNo())) + "/" + (oBrwS:cAlias)->(OrdKeyFocus()) иначе не понять

Andrey: А как тогда первую колонку сделать ? ADD COLUMN TO oBrwS HEADER "№№" ; DATA {|| (oBrwS:cAlias)->(OrdKeyNo()) } ;

Haz: Andrey пишет: А как тогда первую колонку сделать ? выведи в поле не просто номер OrdKeyNo() , а Alias() + "/" + oBrwS:cAlias + "/" + NTOC((oBrwS:cAlias)->(OrdKeyNo())) + "/" + (oBrwS:cAlias)->(OrdKeyFocus()) {|| Alias() + "/" + oBrwS:cAlias + "/" + NTOC((oBrwS:cAlias)->(OrdKeyNo())) + "/" + (oBrwS:cAlias)->(OrdKeyFocus()) } ну и посмотреть что меняется за последней записью

Andrey: Haz пишет: (oBrwS:cAlias)->(OrdKeyFocus()) Что за функция ? Не компилируется.

Haz: Andrey пишет: Что за функция ? http://www.ousob.com/ng/53guide/ng89ad4.php

Haz: опечатка OrdSetFocus() можно заменить любой возвращающей активный TEG

Andrey: Понял что надо OrdSetFocus()

Andrey: Сделал. Вот до нажатия вниз стрелкой за пределы бровса: Вот после нажатия вниз. А потом стрелка вверх: ///////////////////////////////////////////////////////////////////////////////// STATIC FUNCTION TblFocus() DoMethod(oBrwS:cParentWnd, oBrwS:cControlName, "SetFocus") RETURN NIL

Andrey: Я понимаю, что в индекс можно добавить условие FOR "!Deleted()" - и будет работать. Но я тогда не смогу переключаться на удалённые записи.

Haz: Andrey пишет: Я понимаю, что в индекс можно добавить условие FOR "!Deleted()" - и будет работать. Но я тогда не смогу переключаться на удалённые записи. Сможешь если будет два индекса и переключение между ними А так - вторая картинка правильная где 25 ,26, 27 На первой что то не то с OrdKeyNo()

Dima: Andrey пишет: FOR "!Deleted()" Без кавычек только.

Andrey: Haz пишет: На первой что то не то с OrdKeyNo() Может что-то в исходниках не то...

Andrey: Столкнулся с другой непоняткой: Стою на записи - допустим 5. Меняю поле входящее в индекс - допустим KDEL := 2 Заканчиваю редактирование, запись-5 улетает по индексу правильно, а я остаюсь на другой записи. Если же делаю такую обработку: oBrwS:aColumns[nJ]:bPrevEdit := {|| nRecBuff := (oBrwS:cAlias)->(RecNo()), ; MyFieldEdit( oBrwS:aColumns[oBrwS:nCell]:Cargo ) } oBrwS:aColumns[nI]:bPostEdit := {|| oBrwS:GoToRec(nRecBuff), oBrwS:GoLeft(), oBrwS:Refresh(.T.) } то у меня создаётся полностью вторая таблица (я выше об этом писал и приводил картинку). Как мне сейчас делать ? Т.е. поле попадает в индексное выражение....

Haz: Andrey пишет: Как мне сейчас делать ? Т.е. поле попадает в индексное выражение.... позже. ок ?

Haz: Andrey пишет: Как мне сейчас делать ? так отвечал вроде oBrwS:aColumns[nJ]:bPrevEdit := {|| nRecBuff := (oBrwS:cAlias)->(RecNo()), ; MyFieldEdit( oBrwS:aColumns[oBrwS:nCell]:Cargo ) } oBrwS:aColumns[nI]:bPostEdit := {|| oBrwS:GoToRec(nRecBuff), oBrwS:GoLeft(), oBrwS:Refresh(.T.) } oBrwS:aColumns[nI]:bEditEnd := {|| oBrwS:GoToRec((oBrwS:cAlias)->(RecNo())) } ЗЫ для внешнего редактирования есть :bExtEdit и пример есть

Andrey: Haz пишет: ЗЫ для внешнего редактирования есть :bExtEdit и пример есть А что за метод :bExtEdit ? Чуток описать можно ?

Haz: Andrey пишет: А что за метод :bExtEdit ? Чуток описать можно ? вызывается для организации внешнего редактирования Пример в C:\MiniGUI\SAMPLES\Advanced\TsBrowse\ через меню в Sample4 колонка Age редактируется внешне остальное описание - только в исходниках там 5 строк к нему относится и так все понятно

SergKis: Andrey пишет:Как мне сейчас делать ? вот пример, похож на твой, вроде работает click here

Andrey: Haz пишет: oBrwS:aColumns[nI]:bEditEnd := {|| oBrwS:GoToRec((oBrwS:cAlias)->(RecNo())) } Вот это помогло. Спасибо ! SergKis пишет: вот пример, похож на твой, вроде работает click here Принял к сведению. Главное не забыть бы про него...

Vlad04: oBrwS:aColumns[nI]:bEditEnd := {|| oBrwS:GoToRec((oBrwS:cAlias)->(RecNo())) } Вот это помогло. Если после редактирования значение индексированного поля возрастает, то происходит перемещение курсора но новую позицию вниз, а если уменьшается, то курсор вверх но новую позицию не поднимается.

Vlad04: И можно в общем случае как-то избавиться от указания номера колонки ?

Andrey: Vlad04 пишет: И можно в общем случае как-то избавиться от указания номера колонки ? Присоединяюсь обеими руками !!! Зачем для простой таблицы приходиться указывать обработку при смене значений индекса ? Сам Tsbоrwse не может это отследить и остаться на той записи, которую редактировали ?

Vlad04: не может это отследить и остаться на той записи, которую редактировали ? Должен, наверно. В консольном Клиппере , а затем в Харборе Бровз с этой задачей справлялся отлично. В той редакции, которой я пользовался и пользуюсь было так: XNEWKEY := IF( EMPTY(INDEXKEY()), NIL, &(INDEXKEY()) ) IF .NOT. (XNEWKEY == XOLDKEY) Ob:REFRESHALL() while ( !oB:stabilize() ) ; end DO WHILE &(INDEXKEY()) > XNEWKEY .AND. .NOT. Ob:HITTOP() ob:UP() while ( !oB:stabilize() ) ; end ENDDO ENDIF

Haz: Vlad04 пишет: И можно в общем случае как-то избавиться от указания номера колонки ? можно не использовать внешнее редактирование и все будет норм. Или использовать и самому заботиться о прорисовке теми методами которые есть в TS ( а их там полно ) или написать свои

Vlad04: можно не использовать внешнее редактирование и все будет норм Это в каком примере ?

Haz: В частности в этом примере о котором спич редактирование внешнее. Отсюда и все потуги вернуться на нужную запись после него. Или о чем вопрос?

Haz: Andrey пишет: Присоединяюсь обеими руками !!! Зачем для простой таблицы приходиться указывать обработку при смене значений индекса ? Сам Tsbоrwse не может это отследить и остаться на той записи, которую редактировали ? Руки можно опустить и выдохнуть Проверил на тестовом примере , при in-line редактировании значения поля которое входит в индексное выражение , не только Recno() остается той записи которую редактировали, но и сортировка в бровсе выполняется правильно и курсор встает куда надо , вне зависимости увеличили индексный ключ или уменьшили.

Andrey: Haz пишет: Проверил на тестовом примере Давай тест. Будем смотреть его. Может я что-то неправильно делаю... У меня в бровсе частенько курсор переходит непонятно куда. Я делаю редактирование полей в карточке, в бровсе не делаю.

Haz: Andrey пишет: Давай тест. Будем смотреть его А чего там смотреть - тест пустой как барабан [pre2] #include "minigui.ch" #include "tsbrowse.ch" MEMVAR oBrw_1 FUNCTION Main() LOCAL cDbf := GetStartupFolder() + '\Test.dbf' LOCAL i := 0 LOCAL aStr := {} REQUEST DBFCDX , DBFFPT SET CENTURY ON SET DELETED ON RDDSETDEFAULT('DBFCDX') IF ! File( cDbf ) AAdd( aStr, { 'FX', 'N', 10, 2 } ) DbCreate( cDbf, aStr ) cAlias := cFileNoExt(cDbf) USE (cDbf) SHARED ALIAS (cAlias) NEW if ! File( "test.cdx") INDEX ON FIELD->FX TAG FX endif FOR i := 1 TO 100 Test->(dbAppend()) TEST->FX := i END ELSE cAlias := cFileNoExt(cDbf) USE (cDbf) SHARED ALIAS (cAlias) NEW END Test->(OrdSetfocus(1)) DEFINE WINDOW Form_0 ; At 0, 0 ; WIDTH 600 ; HEIGHT 400 ; TITLE 'TsBrowse sample: Order' ; MAIN ; NOMAXIMIZE ; NOSIZE ON KEY ESCAPE ACTION ThisWindow.Release END WINDOW CreateBrowse( "oBrw_1", 'Form_0', 30, 2, Form_0.Width-10, Form_0.Height-60, 'TEST' ) oBrw_1:aColumns[1]:cHeading := "Number" oBrw_1:SetColSize(1, 500) oBrw_1:aColumns[1]:nAlign := DT_LEFT oBrw_1:aColumns[1]:lEdit := TRUE oBrw_1:aColumns[1]:nEditMove := DT_DONT_MOVE Form_0.Center Form_0.Activate RETURN Nil FUNCTION CreateBrowse( cBrw, cParent, nRow, nCol, nWidth, nHeight, cAlias ) LOCAL i PUBLIC &cBrw DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS cAlias ; OF &cParent ; WIDTH nWidth ; HEIGHT nHeight ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 :SetAppendMode( .F. ) :SetDeleteMode( .F. ) :lNoHScroll := .T. :lCellBrw := .T. :nSelWidth := 16 END TBROWSE LoadFields( cBrw, cParent ) &cBrw:nHeightCell += 6 &cBrw:nHeightHead += 14 &cBrw:nWheelLines := 1 &cBrw:lNoChangeOrd := TRUE &cBrw:SetColor( { 16 }, { RGB( 43, 149, 168 )}) // SyperHeader backcolor &cBrw:SetColor( { 3 }, { RGB( 255, 255, 255 )}) // Header font color &cBrw:SetColor( { 4 }, { { || { RGB( 43, 149, 168 ), RGB( 0, 54, 94 )}}}) // Header backcolor &cBrw:SetColor( { 17 }, { RGB( 255, 255, 255 )}) // Font color in SyperHeader &cBrw:SetColor( { 6 }, { { || { RGB( 255, 255, 74 ), RGB( 240, 240, 0 )}}}) // Cursor backcolor &cBrw:SetColor( { 12 }, { { || { RGB( 128, 128, 128 ), RGB( 250, 250, 250 )}}}) // Inactive cursor backcolor &cBrw:SetColor( { 2 }, { { || RGB( 230, 240, 255 )}}) // Grid backcolor &cBrw:SetColor( { 1 }, { { || RGB( 0, 0, 0 )}}) // Text color in grid &cBrw:SetColor( { 5 }, { { || RGB( 0, 0, 255 )}}) // Text color of cursor in grid &cBrw:SetColor( { 11 }, { { || RGB( 0, 0, 0 )}}) // Text color of inactive cursor in grid &cBrw:nClrLine := COLOR_GRID &cBrw:ResetVScroll() RETURN Nil [/pre2]

Haz: Andrey пишет: Я делаю редактирование полей в карточке, в бровсе не делаю. я и так и так делаю, правда есть одно но - работаю с ADS через SQL и управляющий индекс всегда нулевой. Но для скорости выполнения запросов индексы есть практически по всем полям

Vlad04: В реалии во многих случаях сложно обойтись без внешнего редактирования.

Haz: Vlad04 пишет: В реалии во многих случаях сложно обойтись без внешнего редактирования. ну так если УВЕРЕНЫ В ТОМ ЧТО RecNo() НЕ ПОМЕНЯЛОСЬ во многих случаях достаточно ::UpStable() ::Refresh( T )

Vlad04: Успокаивает, то, что в что в стандартных задачах, все работает как надо (почти) . Значит, будет работать и вне стандартных. Алгоритм, примерно, ясен: 1) - Перед редактированием определяем, колонку, которую редактируем, индексный ключ и запоминаем их в переменных 2)- После редактирования определяем новый ключ и после его сравнения с исходным организуем движение курсора по бровсу.

Haz: Не надо никуда двигаться по бровсе и не надо ничего запоминать. При нормальной организации внешнего редактирования ячейки текущая запись не меняется и Алгоритм, примерно, ясен: Вызов_внешнего_редактирования() oBrw:UpStable() oBrw:Refresh( .T. ) все [pre2] #include "minigui.ch" #include "tsbrowse.ch" MEMVAR oBrw_1 FUNCTION Main() LOCAL cDbf := GetStartupFolder() + '\Test.dbf' LOCAL i := 0 LOCAL aStr := {} REQUEST DBFCDX , DBFFPT SET CENTURY ON SET DELETED ON RDDSETDEFAULT('DBFCDX') IF ! File( cDbf ) AAdd( aStr, { 'FX', 'N', 10, 2 } ) DbCreate( cDbf, aStr ) cAlias := cFileNoExt(cDbf) USE (cDbf) SHARED ALIAS (cAlias) NEW if ! File( "test.cdx") INDEX ON FIELD->FX TAG FX endif FOR i := 1 TO 100 Test->(dbAppend()) TEST->FX := i END ELSE cAlias := cFileNoExt(cDbf) USE (cDbf) SHARED ALIAS (cAlias) NEW END Test->(OrdSetfocus(1)) DEFINE WINDOW Form_0 ; At 0, 0 ; WIDTH 600 ; HEIGHT 400 ; TITLE 'TsBrowse sample: Order' ; MAIN ; NOMAXIMIZE ; NOSIZE ON KEY ESCAPE ACTION ThisWindow.Release END WINDOW CreateBrowse( "oBrw_1", 'Form_0', 30, 2, Form_0.Width-10, Form_0.Height-60, 'TEST' ) oBrw_1:aColumns[1]:cHeading := "Number" oBrw_1:SetColSize(1, 500) oBrw_1:aColumns[1]:nAlign := DT_LEFT oBrw_1:aColumns[1]:lEdit := TRUE oBrw_1:aColumns[1]:nEditMove := DT_DONT_MOVE oBrw_1:aColumns[1]:bPrevEdit := { || ExtEdit(), .F. } Form_0.Center Form_0.ACTIVATE RETURN Nil FUNCTION CreateBrowse( cBrw, cParent, nRow, nCol, nWidth, nHeight, cAlias ) LOCAL i PUBLIC &cBrw DEFINE TBROWSE &cBrw ; AT nRow, nCol ; ALIAS cAlias ; OF &cParent ; WIDTH nWidth ; HEIGHT nHeight ; COLORS { CLR_BLACK, CLR_BLUE } ; FONT "MS Sans Serif" ; SIZE 8 :SetAppendMode( .F. ) :SetDeleteMode( .F. ) :lNoHScroll := .T. :lCellBrw := .T. :nSelWidth := 16 END TBROWSE LoadFields( cBrw, cParent ) &cBrw:nHeightCell += 6 &cBrw:nHeightHead += 14 &cBrw:nWheelLines := 1 &cBrw:lNoChangeOrd := TRUE &cBrw:ResetVScroll() RETURN Nil Func ExtEdit() DEFINE WINDOW Form_E ; AT 0,0; WIDTH 150 ; HEIGHT 100 ; TITLE "" ; MODAL ; NOSIZE END WINDOW DEFINE GETBOX NUM PARENT Form_e ROW 10 COL 5 WIDTH 130 HEIGHT 22 VALUE TEST->FX PICTURE "99999.99" FONTNAME 'Arial' FONTSIZE 12 TOOLTIP '' END GETBOX DEFINE BUTTONEX Button_Cancel ROW Form_E.Height - 60 COL 2 PARENT Form_E WIDTH 68 HEIGHT 24 ACTION { || Form_E.Release } CAPTION "Отмена" END BUTTONEX DEFINE BUTTONEX Button_Ok ROW Form_E.Height - 60 COL 73 PARENT Form_E WIDTH 68 HEIGHT 24 ACTION { || IF( test->(dbRlock()), TEST->FX := GetProperty( "Form_E", "Num", "Value" ), NIL ), Test->(dbUnlock()) , Form_E.Release } CAPTION "Выбрать" END BUTTONEX Form_e.Center Form_e.Activate oBrw_1:Upstable() oBrw_1:Refresh(.T.) oBrw_1:ResetVScroll() Return NIL [/pre2]

SergKis: Игорь с какой целью в примерах есть[pre2] DEFINE WINDOW Form_1 ; AT 0,0 ; WIDTH 600 ; HEIGHT 40 ; CHILD ; NOSYSMENU ; NOCAPTION END WINDOW [/pre2] что ты этим хотел сказать ?

Haz: SergKis пишет: что ты этим хотел сказать ? Делал просто на базе другого примера и не весь мусор вычистил Полезной нагрузки Form_1 не несет. Весь пример делался ради трех строк [pre2] oBrw_1:Upstable() oBrw_1:Refresh(.T.) oBrw_1:ResetVScroll() [/pre2] PS. вычистил мусор из примеров, спасибо за наводку. т.к. сам примеры свои же и не смотрю

SergKis: Haz пишет:не весь мусор вычистил Ясненько, а то подумал, что ты хотел еще, что то показать, но забыл

Vlad04: Haz oBrw_1:Upstable() oBrw_1:Refresh(.T.) oBrw_1:ResetVScroll() По сути нужно из подчиненной формы обновить объект на главной. У меня уже программа разрослась, куча файлов, форм( каждые по принадлежности). Вызов из формы Form_2 после сохранения изменений &(cForm). oBrw_1:Upstable() невозможен ? Или как-то можно это сделать ?

Haz: Vlad04 пишет: &(cForm). oBrw_1:Upstable() невозможен ? Или как-то можно это сделать ? oBrw_1 - это переменная, тип которой - "О". Нужно просто обеспечить ее видимость в Form_2 и достаточно просто oBrw_1:Upstable(), возможно перед этим потребуется oBrw_1:Setfocus() У себя я все бровсы объявляю как PUBLIC и все равно из какой формы вызов. В примере же это есть

Vlad04: В MiniGui объекты и формы можно объявить как 1)- Form_1.Brw_1 2)- &(cForm).Brw_1 3) - Form.&(oBrw) Наверно, еще есть варианты. Я выбрал второй вариант. У меня несколько десятков подобных справочников. Я меняю параметры (имя формы , размеры, алиасы) и все работает. Но Бровсы у всех имеют одно имя, но разных хозяев. И без привязки к имени формы к нему не обратишься. Вот такая неувязка

Haz: Vlad04 пишет: Вот такая неувязка DEFINE TBROWSE oLbx AT 10,15 ; oLbx это переменная, явно или неявно указанная . Если неявно то она local в этом модуле и никто не запрещает давать в разных модулях одни и те же имена. По этой причине и "все работает" Посмотри примеры в минигуи , в большинстве своем это именно Local переменные, в главном примере это Public. Vlad04 пишет: И без привязки к имени формы к нему не обратишься. Вот такая неувязка Тоже мне неувязка - передавай по ссылке в функцию в которой рисуется окно для внешнего редактирования. Или подбирайся по алгоритму 1) получи хендл окна Form_1 как h := GetFormHandle("Form_1") 2) просканируй массив _HMG_aControlParentHandles в каких позициях найдено будет h 3) просканируй массив _HMG_aControlNames в позициях найденных выше. где значение будет равно имени твоего бровса и запомни позицию ( пусть х ) 4) в массиве _HMG_aControlIds[ x ] и лежит твой бровс, _HMG_aControlIds[ x ]:Upstable() _HMG_aControlIds[ x ]:Refresh( .T. ) итд ЗЫ Но проще все же сразу давать нормальные имена переменным и обеспечивать нужную видимость

Haz: Haz пишет: Или подбирайся по алгоритму Примерно так [pre2] ... GetBrw( "Form_1", "oBrw" ):Upstable() ... Func GetBrw( cFormName, cBrwName ) local h := GetFormHandle(cFormName) local k := 0 for k := 1 to Len(_HMG_aControlNames) if _HMG_aControlParentHandles[ k ] == h .AND. _HMG_aControlNames[ k ] == cBrwName Exit end end RETURN _HMG_aControlIds[k] [/pre2]

SergKis: Vlad04 В примере Tsb_seek2 уже было показано [pre2] *----------------------------------- Static Function oMyBase( cForm ) // Get Tbrowse object *----------------------------------- Return TBrw_Obj("MyBase", cForm) ... *----------------------------------- Function TBrw_Obj( cTbrw, cForm ) *----------------------------------- Local oBrw, i Default cForm := _HMG_ThisFormName If ( i := GetControlIndex(cTBrw, cForm) ) > 0 oBrw:= _HMG_aControlIds [ i ] EndIf Return oBrw [/pre2]

Haz: SergKis пишет: В примере Tsb_seek2 уже было показано Сергей, не обратил внимания. Пусть будет 2 варианта, хотя твой короче

SergKis: Haz пишет:Пусть будет 2 варианта, хотя твой короче Дело не в этом, пример создавался специально для Vlad04 на его базе

Vlad04: Haz , SergKis Спасибо, цель достигнута !!

Haz: Vlad04 пишет: цель достигнута а в чем она была ? что то я уже не пойму )

Vlad04: Из подчиненной формы обновить бровс на Главной

Vlad04: Для выбранного метода определения Формы и бровсов

Dima: Как показать (редактировать) в Tsbrowse базу если кодировка в ней 866 а сырец проги в 1251 ? Сейчас показывает крякозяблы. В oBrw:aColumns[...]:bData:= я так понимаю ни чего не сделать....

SergKis: Dima USE ( cTable ) ALIAS ( cAlias ) CODEPAGE "RU866" SHARED NEW

Dima: SergKis пишет: USE ( cTable ) ALIAS ( cAlias ) CODEPAGE "RU866" SHARED NEW Так и есть

SergKis: Dima пишет:Так и есть т.е. REQUEST HB_CODEPAGE_RU1251, HB_CODEPAGE_RU866 ... SET LANGUAGE TO RUSSIAN SET CODEPAGE TO RUSSIAN ... USE ( cTable ) ALIAS ( cAlias ) CODEPAGE "RU866" SHARED NEW ... и кракозябы ?

Dima: SergKis да у меня вот так REQUEST HB_CODEPAGE_RU1251, HB_CODEPAGE_RU866, HB_LANG_RUWIN REQUEST HB_LANG_RUWIN REQUEST HB_LANG_RU866 SET CODEPAGE TO RUSSIAN HB_LANGSELECT( "RU" )

SergKis: Dima пишет:HB_LANGSELECT( "RU" ) i_lang.ch #translate SET LANGUAGE TO RUSSIAN => _HMG_LANG_ID := ' ' ; REQUEST HB_LANG_RUWIN ; HB_LANGSELECT( "RUWIN" ) ; InitMessages()

Dima: SergKis Мой косяк , не досмотрел. База под ADS а у меня заявлено было AdsSetCharType(2 , .T.) Второй параметр нужно указывать только для консольных приложений

Dima: Отредактировал запись , нажал ввод и курсор улетает на поле правее , как это запретить ? В сырце что то ни чего не вижу...

SergKis: Dima пишет: курсор улетает на поле правее , как это запретить ? oCol:nEditMove := DT_MOVE_RIGHT // по умолчанию стоит Tbrowse.ch ...[pre2] // Cursor movement after editing #define DT_DONT_MOVE 0 #define DT_MOVE_RIGHT 1 #define DT_MOVE_DOWN 2 #define DT_MOVE_LEFT 3 #define DT_MOVE_UP 4 #define DT_MOVE_NEXT 5 ...[/pre2]

gfilatov2002: Dima пишет: как это запретить ? Попробуй указать oBrw_1:aColumns[ 1 ]:nEditMove := DT_DONT_MOVE для редактируемого столбца

Dima: gfilatov2002 Точно , работает. Видимо я смотрел не там )) Спасибо.

Dima: В окне живет бровс и BTNTEXTBOX. [pre2] @ 10, obrw:aColumns[1]:nwidth+1 BTNTEXTBOX Text_1 WIDTH obrw:aColumns[2]:nwidth ; HEIGHT 20 VALUE sea FONT "Lucida Console" SIZE 10 ; ACTION {|| Nsea( sirie.Text_1.Value,obrw,"naim" )} ; PICTURE "find" BUTTONWIDTH 20 [/pre2] Процедура поиска по бровсу [pre2] Func Nsea(cstr,o,fldnm) local nrec:=(o:cAlias)->(recno()) cstr:=alltrim(upper(cstr)) if empty(cstr) o:setfocus() return .t. endif (o:cAlias)->(dbskip()) __Dblocate({|| cstr $ upper((o:cAlias)->&(fldnm)) }, , , ,.t.) if (o:cAlias)->(found()) nrec:=(o:cAlias)->(recno()) endif o:GoToRec( nRec ) return .t. [/pre2] если строка поиска пустая и нажимается кнопка в BTNTEXTBOX тогда бровс должен получать фокус ввода , но этого не происходит. Почему ?

Dima: Dima пишет: если строка поиска пустая и нажимается кнопка в BTNTEXTBOX тогда бровс должен получать фокус ввода , но этого не происходит. Почему ? Решил добавлением в BTNTEXTBOX конструкции [pre2] ON LOSTFOCUS {|| if ( empty(sirie.Text_1.Value),obrw:setfocus(),) } [/pre2]

Dima: Есть редактируемый бровс по базе. В другой проге я заблочил какую то запись в той же базе. В бровсе нашел эту же запись и пытаюсь ее редактировать , бровс легко это дает но после окончания редактирования вежливо сообщает что запись заблочена :) Можно как то изменить поведение бровса (переключатель может есть какой) что бы в редактирование не пускало если запись уже заблочена ?

Haz: Dima пишет: Можно как то изменить поведение бровса (переключатель может есть какой) что бы в редактирование не пускало если запись уже заблочена ? oBrw:bPrevEdit := { |a, b, lLock| If( lLock := RLock(), dbUnLock(), MsgBox("Запись залочена") ), lLock }

Dima: Haz Спасибо. Ты вроде ж в отпуске )) Режим отметки при obrw:lCanSelect:=TRUE повешен на пробел , можно ли изменить эту педаль на свою ?

Haz: Dima пишет: Режим отметки при obrw:lCanSelect:=TRUE повешен на пробел , можно ли изменить эту педаль на свою ? На что угодно, определив обработку в bUserKeys этой кнопки как ::Selection() ::GoDown() и вернув FALSE Да , и учти что отметка реализована через массив с номерами записей ( вроде так , давно не смотрел ) так что реализовать альтернативу со своей цветовой схемой - пустяк

Dima: Haz пишет: На что угодно, определив обработку в bUserKeys этой кнопки как Это я понял уже , вопрос звучал иначе , есть ли какой то флаг позволяющий заюзать другую педаль. Похоже его нет , да и ладно , сделаю своё ,через bUserKeys как и ты и советовал.

Dima: Что бы освежить только текущую строку достаточно o:RefreshARow(o:nRowPos) или нужен o:Refresh() ? PS Хожу по базе.

Haz: Dima пишет: освежить только текущую строку ::Refresh(FASLE) или ::DrawSelect()

Dima: Haz пишет: ::Refresh(FASLE) Понял , только при этом "дрыгается" весь бровс на выпуклый морской глаз , впрочем как и при RefreshARow )) А вот DrawSelect() самое то (все красиво и без лишних прорисовок) !

Dima: Есть какой то метод что бы дернуть данные с ячейки , типа obrw:GETCELLDATA(nrow , ncol) ? PS Хожу по базе. Для массива понятно все.

SergKis: Dima Для тек.записи Eval(oBrw:aColumns[nCol]:bData) для др. записи dbGoto(nRec) или dbSkip(nCount) и снова Eval(oBrw:aColumns[nCol]:bData)

Dima: SergKis Я не много не о том. Хотел для базы заюзать oBrw:cToolTip{|oBr, nCol, nRow| if( ncol ==2,..... Строка и колонка известна. Указатель записи дергать не хотелось бы , но при наведении мышки на нужную ячейку в колонке 2 , хотелось дернуть данные от туда и показать в cToolTip. Изначально я так и поступил как ты пишешь но тогда показывает на любой ячейке 2-го столбца - данные записи на которой лежит курсор (что и понятно).

SergKis: Dima пишет: хотелось дернуть данные от туда и показать в cToolTip Без перемещения на нужную запись этого сделать не получиться, надо использовать значение nCol для получения bData, а nRow для вычисления nCount перемещения от тек. записи ( dbSkip(nCount) ), считывание данных с колонки и возврат на запись, где были ранее

Dima: SergKis Понял , думал можно проще , без дергания указателя записи. Спасибо.

Dima: Поймал косяк в Tsbrowse Есть 2 открытых справочника в разных Child окнах. В одном из них я начал редактировать запись и не закончив редактирование переключаюсь на другой справочник мышкой и получаю вылет [pre2] Error BASE/1004 Метод не экспортирован: SHOW Called from SHOW(0) Called from TSBROWSE:EDIT(4003) Called from TSBROWSE:KEYDOWN(6584) Called from TSBROWSE:HANDLEEVENT(7348) Called from EVENTS(0) Called from DOEVENTS(0) Called from TCONTROL:HANDLEEVENT(875) Called from TSBROWSE:HANDLEEVENT(7385) Called from EVENTS(0) Called from UPDATEWINDOW(0) Called from EVENTS(0) Called from DOMESSAGELOOP(0) Called from _ACTIVATEWINDOW(0) [/pre2]

Dima: Тот же глюк в C:\MiniGUI\SAMPLES\Advanced\TsBrowse\ если запустить DEMO.EXE и заюзать 4 и 5 пример одновременно Первоначально ломается бровс

SergKis: Dima пишет:Тот же глюк в C:\MiniGUI\SAMPLES\Advanced\TsBrowse\ если запустить DEMO.EXE и заюзать 4 и 5 пример одновременно Как это тебе удалось ? Вкл. edit в одном, переключаю фокус на др. тот edit выключился новый включается и так все время, не зависимо с какого примера 4\5 начинать

SergKis: SergKis пишет:Как это тебе удалось ? Получил на колонке Age, но там диалоговое окно MODAL. Почему оно дает переход на др. окно приложения ?

Dima: SergKis Смотрим пример проще C:\MiniGUI\SAMPLES\Advanced\Tsb_SetArrayTo\ Запускаем два окна вот так как на скрине Входим в режим редактирования колонки order display в записи где цифра 1 и не выходя из него мышкой щелкаем на втором окне такой же колонки , при чем если нажать на первой записи то вылет с ошибкой если на другой записи то бровс с которого ушли просто портится , вот скрин

Dima: Косяк 2 Есть два активных бровса в разных окнах Когда бровс в фокусе курсор выглядит как и положено Переключаюсь мышкой на другой бровс и после возврашаюсь назад щелкая на той же записи , в этом случае фон курсора остался фоном не активного курсора Если во время перехода щелкать на другой записи , не там где стоял курсор то все нормально. Я пробовал уже "фокус" c oBrw:bGotFocus:={|| obrw:Refresh()} , не помогло

SergKis: Dima пишет:Смотрим пример проще C:\MiniGUI\SAMPLES\Advanced\Tsb_SetArrayTo\ запустил 6 разных примеров к ним 3 exe Tsb_setArrayTo - переключаюсь\вкл. едит по разному и по всем - ничего описанного тобой нет Win 8.1, hmg последняя Я пробовал уже "фокус" c oBrw:bGotFocus:={|| obrw:Refresh()} , не помогло попробуй oBrw:DrawSelect() переменная oBrw - public или привате для обоих окон ?

Dima: SergKis пишет: попробуй oBrw:DrawSelect() Пробовал не пашет SergKis пишет: переменная oBrw - public Public

Dima: SergKis пишет: запустил 6 разных примеров к ним 3 exe Tsb_setArrayTo Не нужно запускать несколько примеров. Все в одном , там же есть кнопка TEST RUN ANOTHER WINDOW , нажми ее и будет 2 бровса , проделай как я выше описал и будет косяк. А вот если 2 разных EXE запустить с бровсами то между ними нет такой проблемы

Dima: Dima пишет: Переключаюсь мышкой на другой бровс и после возврашаюсь назад щелкая на той же записи , в этом случае фон курсора остался фоном не активного курсора А если щелкнуть на заголовке окна то все норм , если щелкать на бровсе то вот такая ерунда

SergKis: Dima пишет:Public тогда у тебя в ней объект tsb последнего запущенного окна, т.е. один объект на два окна и след. при повторном возврате цвета не в фокусе от др. тсв Для Public надо заводить имена уникальные для тсв, для Private к окну использования - может прокатить, но лучше в блоках кода исп. передаваемый параметр тсв в eval, как я показывал, надо один раз выписать параметры и потом использовать, тогда достаточно local oBrw

Dima: Сергей было так Public obrw Public obrw1 Public obrw2 Переделал Local obrw Local obrw1 Local obrw2 Проблема осталась

SergKis: Dima пишет:А если щелкнуть на заголовке окна то все норм , если щелкать на бровсе то вот такая ерунда Делал и по заголовкам и по строкам и с вкл едит и без и dblclic (в 2-х окнах) - нет описанного тобой. Когда кликаю на заголовок окна (в др.был едит) 1.закрывается едит, 2.фокус на др.окне, но на тсв нет выделенного курсора (нет фокуса), но стрека вниз и все ок или мышой. Словом не получаю описанного тобой

SergKis: Dima пишет:Проблема осталась Тогда по Якубовичу ... в студию

Dima: SergKis пишет: Делал и по заголовкам Да это я про свой пример писал. Cчас подробно опишу что сделать надо Запускаем пример из C:\MiniGUI\SAMPLES\Advanced\Tsb_SetArrayTo\ Жмем кнопку TEST RUN ANOTHER WINDOW , появилось второе окно Сдвигаем его левее прежнего окна , так что бы в обоих бровсах было видно колонку Order Display. На этом последнем окне в бровсе в колонке Order Display в записи где цифрь 1 жмем ВВОД и попадаем в режим редактирования. Ни чего более не клацаем. Наводим мышку на второй бровс (только не нужно тыкать на заголовке окна) и тоже в колонку Order Display на запись где цифра 1 , клацаем мышкой И стабильно падаем. Если и сейчас у тебя не получится , придется мне видео снимать Вот и видео https://cloud.mail.ru/public/9SNJ/3pp8to6DP

Dima: SergKis пишет: Тогда по Якубовичу ... в студию [pre2] #include "minigui.ch" #include "tsbrowse.ch" #define CLR_PINK RGB( 255, 128, 128) #define CLR_NBLUE RGB( 128, 128, 192) #define CLR_NBROWN RGB( 130, 99, 53) #define CLR_1 RGB( 190, 215, 190 ) #define CLR_2 RGB( 230, 230, 230 ) #define CLR_3 RGB( 217, 217, 255 ) #define CLR_ELLOW1 Rgb( 128, 255, 128 ) #define CLR_ELLOW2 Rgb( 0, 217, 0 ) #define CLR_ELLOW3 Rgb( 113, 113, 0 ) #define CLR_ELLOW Rgb( 255, 255, 193 ) #define LWA_ALPHA 0x02 #define CLR_WGRAY Rgb( 210, 210, 210 ) EXTERNAL ADSKEYCOUNT , ADSGetRelKeyPos ,AdsKeyNo Func Sirie() local hw local a local b local i local abmp local ngh local sea:="" local nsea:=0 local arw local aStates:={" ","Метр ","Шт. ","Кг. ","Лист ","М/П ","Литр "} local xr:=0 local xy:=0 local tmpbrw public obrw IF IswindowDefined("SPR_SIR") DoMethod("SPR_SIR", "Restore") DoMethod("SPR_SIR", "Setfocus") if _IsControlDefined("obrw","SPR_SIR") oBrw:SetFocus() endif return nil endif if !usebase("sr",{"sr"},"s_sirec") msgstop("Не могу открыть базу") return nil endif s_sirec->(ordsetfocus("naim")) hw:=GetProperty("Form_0", "Height")-GetProperty("FORM_0", "StatusBar", "Height"); -GetMenubarHeight()-GetTitleHeight()-2*GetBorderHeight() a:=GetProperty("Form_0", "Row")+GetBorderHeight()+GetTitleHeight()+GetMenubarHeight() b:=(GetProperty("Form_0", "Width") - (GetProperty("Form_0", "Width")*0.55))/2 arw:=GetRowColExceptMain() if !empty(arw) a:=arw[1]+GetTitleHeight() b:=arw[2]+GetTitleHeight() endif DEFINE WINDOW SPR_SIR AT a , b WIDTH WidthWindow_MyApl*0.55 HEIGHT hw TITLE "Справочник сырья" CHILD ; ICON "AMAINICON" ; NOMAXIMIZE ; NOSIZE ; ON RELEASE {||Closebase({"s_sirec"}) } ; ON INTERACTIVECLOSE {|| .t.} ; ON GOTFOCUS {|| oBrw:SetFocus(),obrw:Refresh(.f.) ,Mcargo:=_HMG_ThisFormName } DEFINE TBROWSE oBrw AT 40,0 ALIAS "s_sirec" ; OF SPR_SIR WIDTH SPR_SIR.WIDTH-2*GetBorderWidth() ; HEIGHT SPR_SIR.HEIGHT-GetTitleHeight()-2*GetBorderHeight()-50-40 ; FONT "Lucida Console" SIZE 10 LoadFields("obrw","SPR_SIR",.t.,{"id","naim","ed","cod"}) oBrw:SetColSize( 1, 50 ) oBrw:aColumns[1]:lEdit := FALSE oBrw:aColumns[ 1 ]:cHeading :="ID" oBrw:aColumns[ 1 ]:cPicture :="@Z 99999" oBrw:aColumns[ 2 ]:cHeading :="Наименование" oBrw:aColumns[ 2 ]:cPicture:=repl("x",60) oBrw:aColumns[ 3 ]:cHeading :="Ед.изм" oBrw:aColumns[ 3 ]:cPicture :=repl("x",5) oBrw:SetData( 3,NIL , astates ) oBrw:aColumns[3]:bEditing := { |uVar,oBr| oBr:aColumns[oBr:nCell]:oEdit:LButtonDown() } oBrw:aColumns[3]:bEditEnd := { |uVal,oBr,lSave| Save_ed(uVal,oBr,lSave) } oBrw:SetColSize( 3, 70 ) oBrw:bGotFocus:={|| obrw:Refresh(.t.),obrw:setfocus()} oBrw:aColumns[ 4 ]:cHeading :="Код"+CRLF+"склада" oBrw:aColumns[ 4 ]:cPicture :="@Z 99999" ADD COLUMN TO obrw HEADER "Остаток" SIZE 100 DATA {|| 0 } oBrw:aColumns[ 5 ]:cPicture :="@Z 99999.999" for i := 1 To oBrw:nColCount() oBrw:aColumns[ i ]:nEditMove := DT_DONT_MOVE oBrw:aColumns[ i ]:lFixLite := TRUE next obrw:GetColumn("naim"):bPrevEdit := { |a, b, lLock| If( lLock := (b:cAlias)->(RLock()), (b:cAlias)->(dbUnLock()), Msgstop("Запись заблокирована","Внимание")), lLock } obrw:GetColumn("cod"):bPrevEdit := { |a, b, lLock| If( lLock := (b:cAlias)->(RLock()), (b:cAlias)->(dbUnLock()), Msgstop("Запись заблокирована","Внимание") ), lLock } obrw:GetColumn("ed"):bPrevEdit := { |a, b, lLock| If( lLock := (b:cAlias)->(RLock()), (b:cAlias)->(dbUnLock()), Msgstop("Запись заблокирована","Внимание") ), lLock } obrw:nWheelLines := 2 obrw:nClrLine := COLOR_GRID obrw:SetAppendMode( .F. ) obrw:SetDeleteMode( .t.,.f.,{|| msgokCancel("Удалить "+alltrim((obrw:cAlias)->naim)+CRLF+"с ID "+ntoc((obrw:cAlias)->id)+" ?","Внимание")} ) obrw:lNoHScroll := .f. obrw:lCellBrw := .T. obrw:nfreeze:=1 obrw:lNoChangeOrd := .f. obrw:nHeightCell += 5 obrw:nHeightHead += 6 obrw:lLockFreeze := .t. obrw:lCellBrw := .t. obrw:nAdjColumn := 2 obrw:Set3DText( .T., .t.,, 2 ) obrw:lNoMoveCols:=.t. obrw:bOnEscape := {|| DoMethod(oBrw:cParentWnd, "Release") } oBrw:bUserKeys := {|nKey,nFlg,oBr| UserKeys(nKey, nFlg, oBr) } oBrw:SetColor( { 1 ,2}, { CLR_BLACK ,rgb(255,255,206) } ) oBrw:SetColor( { 2 }, { {|| if((obrw:cAlias)->lc,RGB(130,255,130),rgb(255,255,206)) } },1) oBrw:SetColor( { 5 }, { { || { Rgb( 66, 255, 236 ), Rgb( 11, 183, 155 )}}} ) oBrw:SetColor( { 6 }, { { |a,b,c| IF( c:nCell == b,; {RGB( 255, 255, 0 ), RGB( 210, 210, 0 )},; { Rgb( 198, 226, 255 ), Rgb( 159, 207, 255 ) } ) } } ) oBrw:SetColor( { 6 }, { { |a,b,c| -RGB(117,0,234) } },1) oBrw:cToolTip := {|oBr, nCol, nRow| if(obr:nrowpos==nrow,"Удаление записи , добавить новую запись , отметка ( правая кнопка мышки )","") } END TBROWSE tmpbrw:=TBrw_Obj( "obrw", ThisWindow.name ) xr:=ThisWindow.HEIGHT-GetTitleHeight()-2*GetBorderHeight()-40 xy:=4 DEFINE BUTTONeX Button_1 ROW xr COL xy WIDTH 120 HEIGHT 35 CAPTION "Добавить (Ins)" ACTION {|| if(msgokCancel("Добавить новую запись ?","Внимание"),addrecs(tmpbrw,"ID"),),tmpbrw:SetFocus() } FONTNAME "Arial" FONTSIZE 9 TOOLTIP "Добавить новую запись" FONTBOLD .t. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. ONGOTFOCUS Nil ONLOSTFOCUS Nil HELPID Nil FLAT .F. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. Picture "new" END BUTTONEX xy+=getproperty(ThisWindow.name,"Button_1","Width")+11 DEFINE BUTTONeX Button_2 ROW xr COL xy//135 WIDTH 120 HEIGHT 35 CAPTION "Удалить (Del)" ACTION {|| tmpbrw:deleterow(),tmpbrw:SetFocus() } FONTNAME "Arial" FONTSIZE 9 TOOLTIP "Удалить запись" FONTBOLD .t. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. ONGOTFOCUS Nil ONLOSTFOCUS Nil HELPID Nil FLAT .F. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. Picture "cancel" END BUTTONEX xy+=getproperty(ThisWindow.name,"Button_2","Width")+11 DEFINE BUTTONeX Button_3 ROW xr COL xy WIDTH 120 HEIGHT 35 CAPTION "Изменить (F4)" ACTION {|| tmpbrw:SetFocus() ,_PushKey(VK_SPACE)} FONTNAME "Arial" FONTSIZE 9 TOOLTIP "Изенить ячейку" FONTBOLD .t. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. ONGOTFOCUS Nil ONLOSTFOCUS Nil HELPID Nil FLAT .F. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. ICON "edit2" END BUTTONEX xy+=getproperty(ThisWindow.name,"Button_3","Width")+20 DEFINE BUTTONeX Button_4 ROW xr COL xy WIDTH 28 HEIGHT 28 ACTION {|| tmpbrw:GoDown(),tmpbrw:SetFocus() } TOOLTIP "На запись вперед" FLAT .t. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. icon "skipf" END BUTTONEX xy+=getproperty(ThisWindow.name,"Button_4","Width") DEFINE BUTTONeX Button_5 ROW xr COL xy WIDTH 28 HEIGHT 28 ACTION {|| tmpbrw:Refresh(),tmpbrw:SetFocus() } TOOLTIP "Освежить таблицу" FLAT .t. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. icon "ref" END BUTTONEX xy+=getproperty(ThisWindow.name,"Button_5","Width") DEFINE BUTTONeX Button_6 ROW xr COL xy WIDTH 28 HEIGHT 28 ACTION {|| tmpbrw:Goup(), tmpbrw:SetFocus() } TOOLTIP "На запись назад" FLAT .t. TABSTOP .T. VISIBLE .T. TRANSPARENT .t. icon "skipb" END BUTTONEX DEFINE LABEL Message ROW 1 COL 1 WIDTH obrw:aColumns[2]:nwidth*0.75 HEIGHT 16 VALUE 'Поиск по названию' FONTBOLD .T. CENTERALIGN .T. END LABEL DEFINE LABEL Message1 ROW 1 COL obrw:aColumns[2]:nwidth+obrw:aColumns[1]:nwidth+2 WIDTH obrw:aColumns[3]:nwidth+obrw:aColumns[4]:nwidth/2 HEIGHT 16 VALUE 'Поиск кода' FONTBOLD .T. CENTERALIGN .T. END LABEL @ 18, 1 BTNTEXTBOX Text_1 WIDTH obrw:aColumns[2]:nwidth*0.75 ; HEIGHT 20 VALUE sea FONT "Lucida Console" SIZE 10 ; ACTION {|| Nsea( SPR_SIR.Text_1.Value,obrw,"naim" ),obrw:setfocus() } ; ON ENTER {|| Nsea( SPR_SIR.Text_1.Value,obrw,"naim"), Domethod( "SPR_SIR", "Text_1", "Setfocus")} ; PICTURE "find" BUTTONWIDTH 20 TOOLTIP "Поиск вхождения строки в наименование"; BACKCOLOR {{255,255,255},{255,255,200},{200,255,255}} ; FONTCOLOR {{0,0,0},{255,255,200},{0,0,255}} @ 18, obrw:aColumns[2]:nwidth+obrw:aColumns[1]:nwidth+2 ; BTNTEXTBOX Text_2 WIDTH obrw:aColumns[3]:nwidth+obrw:aColumns[4]:nwidth/2 ; HEIGHT 20 VALUE sea FONT "Lucida Console" SIZE 10 ; ACTION {|| if(codsea( SPR_SIR.Text_2.Value,obrw,"cod" ) ,eval( {||_pushkey( VK_TAB ) ,setproperty( "SPR_SIR", "obrw", "Setfocus")}),)} ; NUMERIC ; ON ENTER {|| if(codsea( SPR_SIR.Text_2.Value,obrw,"cod" ) ,setproperty( "SPR_SIR", "obrw", "Setfocus"),Domethod( "SPR_SIR", "Text_2", "Setfocus") )};//, Domethod( "SPR_SIR", "Text_2", "Setfocus")} ; PICTURE "find" BUTTONWIDTH 20 TOOLTIP "Точный поиск по коду" ; BACKCOLOR {{255,255,255},{255,255,200},{200,255,255}} ; FONTCOLOR {{0,0,0},{255,255,200},{0,0,255}} DEFINE CONTEXT MENU CONTROL oBrw MENUITEM "Добавить новую запись" ACTION {|| if(msgokCancel("Добавить новую запись ?","Внимание"),addrecs(obrw,"ID"),),oBrw:SetFocus() } IMAGE "new" MENUITEM "Удалить текущую запись" ACTION {|| obrw:deleterow() } IMAGE "cancel" SEPARATOR MENUITEM "Пометка (снять/поставить)" ACTION { || Otmet(obrw) } END MENU END WINDOW DoMethod(oBrw:cParentWnd, oBrw:cControlName, "SetFocus") ACTIVATE WINDOW SPR_SIR SetfocusChild() return nil [/pre2] В другом справочнике все примерно так же так как поля те же Отличие только в имени базы , имени окна , да и имени бровса ( Public OBRW1) Где по твоему косяк ? PS Возможно не нужно было мне выкладывать описания кнопок , ну да ладно. Там по самому бровсу не так и много. Постом выше добавил видео

SergKis: Dima пишет:клацаем мышкой И стабильно падаем. нету такого, exe положил, знаешь где, глянь на нем.

Dima: SergKis пишет: нету такого, exe положил, знаешь где, глянь на нем. На твоем тоже самое , как в кино что я снял. Падает. PS Win7 PS2 Чудеса

Dima: Положил видео к тебе

SergKis: Dima пишет На этом последнем окне в бровсе в колонке Order Display в записи где цифрь 1 жмем ВВОД и попадаем в режим редактирования. Ни чего более не клацаем. Наводим мышку на второй бровс (только не нужно тыкать на заголовке окна) и тоже в колонку Order Display на запись где цифра 1 , клацаем мышкой И стабильно падаем. и по видео и по описанию и 5 мин. подряд - все ok

Dima: SergKis пишет: и по видео и по описанию и 5 мин. подряд - все ok блин мне грустно )) Якубовича не смотрел выше ( я выложил сырец )? Там примерно тоже возникает как и в C:\MiniGUI\SAMPLES\Advanced\Tsb_SetArrayTo\ Такое впечатление что оба бровса где то пересеклись по данным , но судя по сырцу правильно же все. ЗЫ Под BCC и MINGW одинаково глючит

SergKis: Dima пишет я выложил сырец взял, попробовал собрать, но ф-й не хватает и базы. точнее не глядел - тыкал пример и так и сяк

Dima: SergKis Он был дан не для сборки а просто посмотреть опытным глазом на описание бровса. Но я так подозреваю что если у тебя нет косяка в Tsb_SetArrayTo а у меня он есть тогда и сборка моего сырца ни чего не даст , у тебя все будет нормально. Проверил работу своей проги на win 2008 те же косяки как и в Tsb_SetArrayTo

SergKis: Dima посмотрел, вроде нормально, но Haz с Андреем обсуждали local в блоке кода и вопросы по содержимому были. В примерах от Андрея, были похожие штуки и вроде как от одной переменной oBrw, переведя на private (3 или 5 tsb одной ф-ей создавалось\обслуживалось) - вроде исправилось. Точнее он скажет, чем закончилось у него

Dima: Функции у меня разные на бровсы. Пробнул Private - до лампочки. Можно конечно пойти другим путем , но пока не придумал как реализовать правильно. Есть только сырая и не продуманная идея. Вызван один справочник , вызываю другой (окна у них CHILD) и тогда сворачиваю окно первого справочника. Как то так в первом приближении. А если их открыто более одного и при закрытии последнего вызванного какой из них восстанавливать я пока не придумал , думаю ... В консоли все проще

SergKis: Dima пишет какой из них восстанавливать я пока не придумал ...В консоли все проще Так делай похоже. В MDI у нас childmdi окна всегда в полное mdi main окно, новое закрывает предыдущее и не важно есть оно или уничтожено (предыдущее) про Ctrl+Tab клиент не помнит и снова к справочнику обращается через меню\кнопку, потому можно старые окна уничтожать (сохранив позиции фокуса recno, nCell, nRowpos, ...) и делать по новой. Та даже лишнх ресурсов не держишь. И для клиента путаницы из окон нет, очень похоже как в консоли

Dima: Идею понял Сергей. В ON INIT окна CHILD это уже сделал При закрытии окна тоже Борюсь пока с получением фокуса в ON GOTFOCUS , думаю справлюсь , прикольно получается :) Если что спрошу.

SergKis: Dima глянь пример, положил на тему edit в 2-х child окнах

Dima: Да не глючит и я понял почему. Если окна не наложены друг на друга то все нормально. Если наложить и пробовать редактировать и не заканчивая редакцию , мышкой перейти в другое окно то бах и глюк. Сниму "кино" если нужно.

SergKis: Dima пишет:Сниму "кино" если нужно кино не надо, но у меня все ok наложены окна или нет, без разницы. Win 7 сейчас под рукой нет, но позже пробну.

Dima: SergKis пишет: Win 7 сейчас под рукой нет, но позже пробну. Надеюсь это повторится как у меня. И это не единственный замеченный косяк , которых у тебя думаю нет.

Andrey: SergKis пишет: Win 7 сейчас под рукой нет, но позже пробну. У меня есть в виртуалке. Могу попробовать....

Dima: Andrey пишет: У меня есть в виртуалке. Могу попробовать.... https://cloud.mail.ru/public/KtS6/6GhHtz28A

Andrey: Dima пишет: Если окна не наложены друг на друга то все нормально. Если наложить и пробовать редактировать и не заканчивая редакцию , мышкой перейти в другое окно то бах и глюк. У меня также в 7-ке "вылет" ! Ошибки точно такие же. Под 8.1 нормально работает. Там при переходе на другое окно редактирование закрывается и спокойно переходит на другое окно. Под XP пришлось помучиться, но тоже добился вылета программы. Несколько раз мышкой туды-сюды при редактировании и вылет. Значит что-то в 7-ке и ХР не то...

Dima: Andrey пишет: У меня также в 7-ке "вылет" Слава богу а то все мне говорят что у меня семерка кривая Спасибо за тест. Кстати тестил на серваке 2008 тоже глючит.

Dima: Дело похоже не только в бровсе а в самом Минигуи в разрезе вынь 7/xp Например если CHILD окно свернуть а на главном окне живет статусбар с какими то надписями и своим фоном и затем окно снова развернуть то там где лежало свернутое окно это место статус бар очищается или портится. На 8.1 все норм

Dima: SergKis пишет: Win 7 сейчас под рукой нет, но позже пробну. Спасибо , уже не надо. Игорь подсказал что нужно поправить в том числе в сырце TS Вероятно глюк имеет место только на 7 и XP , выше все нормально.

SergKis: Dima пишет Игорь подсказал что нужно поправить в том числе в сырце TS Ok

Andrey: Dima пишет: Игорь подсказал что нужно поправить в том числе в сырце TS Вероятно глюк имеет место только на 7 и XP А Григорию скажешь что править ?

Dima: Andrey пишет: А Григорию скажешь что править ? да когда он появится

Vlad04: Копирование в Tsbrows Как то все не так. Часть строки (поля) нельзя выделить. Копируется , но все поле. Или я что-то не так делаю ? Но в textBox все нормально.

gfilatov2002: Vlad04 пишет: Как то все не так Согласен, ведь в качестве полей ввода используется самописный GETBOX Vlad04 пишет: Часть строки (поля) нельзя выделить Часть строки (поля) можно выделить с помощью мышки (но не клавиатуры)

Dima: gfilatov2002 METHOD TSBrowse:Edit() строка примерно 4003 в самом конце было oCol:oEdit:Show() надо [pre2] if oCol:oEdit != NIL oCol:oEdit:Show() endif [/pre2] Это вариант для XP и семерки , выше и так нормально

Dima: Dima пишет: Это вариант для XP и семерки И еще , после END TBROWSE указываем примерно так aEval( oBrw:aColumns, { |e| e:bLClicked := {|| oBrw:DrawSelect() } }) иначе ломается курсор , скрины я давал

Vlad04: gfilatov2002 Часть строки (поля) можно выделить с помощью мышкиДа, выделить можно , но не скопировать. Копируется все строка (поле)

Dima: Vlad04 пишет: Да, выделить можно , но не скопировать. Копируется все строка (поле) Да так и есть , возможно не допилили GET в бровсе. А вот в GETBOX такой фокус работает к примеру.

gfilatov2002: Dima пишет: Это вариант для XP и семерки Благодарю за сообщение Поправил для следующей сборки



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