Página 2 de 2

Pendências no browse

Enviado: 10 Fev 2023 17:53
por JoséQuintas
Dei uma simplificada básica.
Notem que é genérico, pra qualquer coisa.
Não coloquei tudo que tenho no meu browse atual, apenas um básico.

Código: Selecionar todos

#include "hwgui.ch"
#include "inkey.ch"
#include "hbgtinfo.ch"

PROCEDURE PTESHWGUIBrowse( cModule, cTitle, ... )

   LOCAL cnSQL := ADOLocal(), oTBrowse, cCampoKeyboard := "CODIGO", xValue

   hb_Default( @cTitle, "PESQUISA DE CIDADES" )
   WITH OBJECT cnSQL
      :Execute( "SELECT CINOME, CIUF, CIIBGE, IDCIDADE" + ;
         " FROM JPCIDADE" + ;
         " ORDER BY CINOME" )
      oTBrowse := { ;
         { "NOME", { || :String( "CINOME", 40 ) } }, ;
         { "UF",   { || :String( "CIUF", 2 ) } }, ;
         { "IBGE", { || :String( "CIIBGE", 7 ) } }, ;
         { "ID",   { || Str( :Number( "IDCIDADE" ), 6 ) } } }
      xValue := HWGUIBrowse( cTitle, cnSQL, oTBrowse, "CINOME", ;
         iif( cCampoKeyboard == "CODIGO", { || Str( :Number( "IDCIDADE" ), 6 ) }, { || :String( "CINOME", Len( GetActive():VarGet ) ) } ) )
      IF xValue != Nil
         MsgExclamation( Transform( xValue, "" ) )
      ENDIF
      :CloseRecordset()
   ENDWITH
   ( cModule )

   RETURN

FUNCTION HwguiBrowse( cTitle, cnSQL, oBrowseList, cFilterList, bCode )

   LOCAL oDlg, oBrowse, cFilter := "", lSelected := .F., xValue := Nil, oBtnList := {}

   hb_Default( @cFilter, "" )

   INIT DIALOG oDlg ;
      AT AppWindowRect( 1 ), AppWindowRect( 2 ) SIZE AppWindowRect( 3 ), AppWindowRect( 4 ) ;
      TITLE cTitle

   @ 11, 101 BROWSE ARRAY oBrowse ;
      SIZE AppWindowRect( 3 ) - 10 - 10, AppWindowRect( 4 ) - 10 - 100 STYLE WS_BORDER + WS_VSCROLL + WS_HSCROLL + DS_CENTER ;
      ON CLICK { || lSelected := .T., oDlg:Close() } ;
      ON KEYDOWN { | oBrw, nkey | oBrowseKey( oDlg, oBrw, nkey, @cFilter, lSelected, cFilterList ) }
   oBrowse:aArray := cnSQL
   BrowseSet( oBrowse, oBrowseList )
   CreateButtons( oDlg, oBrowse, @oBtnList )

   ACTIVATE DIALOG oDlg CENTER

   IF lSelected .AND. bCode != Nil
      xValue := Eval( bCode )
   ENDIF

   RETURN xValue

FUNCTION BrowseSet( oBrowse, oBrowseList )

   LOCAL oElement

   oBrowse:bSkip  := { | o, nSkip | ADOSkipper( o:aArray, nSkip ) }
   oBrowse:bGotop := { | o | o:aArray:MoveFirst() }
   oBrowse:bGobot := { | o | o:aArray:MoveLast() }
   oBrowse:bEof   := { | o | o:nCurrent > o:aArray:RecordCount() }
   oBrowse:bBof   := { | o | o:nCurrent == 0 }
   oBrowse:bRcou  := { | o | o:aArray:RecordCount() }
   oBrowse:bRecno := { | o | o:aArray:AbsolutePosition() }
   oBrowse:bRecnoLog := oBrowse:bRecno
   oBrowse:bGOTO  := { | o, n | (o), o:aArray:Move( n - 1, 1 ) }

   FOR EACH oElement IN oBrowseList
      ADD COLUMN oElement[ 2 ] TO oBrowse HEADER oElement[ 1 ] LENGTH Int( Len( Transform( Eval( oElement[ 2 ] ), "" ) ) * 1.2 ) + 1
   NEXT

   RETURN Nil

FUNCTION ADOSkipper( cnSQL, nSkip )

   LOCAL nRec := cnSQL:AbsolutePosition()

   IF ! cnSQL:Eof()
      cnSQL:Move( nSkip )
      IF cnSQL:Eof()
         cnSQL:MoveLast()
      ENDIF
      IF cnSQL:Bof()
         cnSQL:MoveFirst()
      ENDIF
   ENDIF

   RETURN cnSQL:AbsolutePosition() - nRec

STATIC FUNCTION oBrowseKey( oDlg, oBrowse, nKey, cFilter, lSelected, cFilterList )

   nKey := hb_KeyStd( nKey )
   DO CASE
   CASE nKey == K_ENTER .OR. nKey == K_ESC
      IF nKey == K_ENTER
         lSelected := .T.
      ENDIF
      oDlg:Close()
      RETURN .F.
   CASE IsAscChar( nKey )
      IF nKey == K_BS
         IF Len( cFilter ) > 0
            cFilter := Left( cFilter, Len( cFilter ) - 1 )
         ENDIF
      ELSE
         cFilter += Upper( Chr( nKey ) )
      ENDIF
      oBrowse:aArray:Filter( iif( Empty( cFilter ), "", cFilterList + " LIKE '%" + cFilter + "%'" ) )
      IF oBrowse:aArray:Eof() .AND. Len( cFilter ) > 0
         cFilter := Substr( cFilter, 1, Len( cFilter ) - 1 )
         oBrowse:aArray:Filter( iif( Empty( cFilter ), "", cFilterList + " LIKE '%" + cFilter + "%'" ) )
      ENDIF
      oBrowse:Refresh()
   ENDCASE

   RETURN .T.

STATIC FUNCTION IsAscChar( nKey )

   DO CASE
   CASE nKey == VK_BACK
   CASE nKey >= Asc( "A" ) .AND. nKey <= Asc( "Z" )
   CASE nKey >= Asc( "a" ) .AND. nKey <= Asc( "z" )
   CASE nKey >= Asc( "0" ) .AND. nKey <= Asc( "9" )
   CASE hb_AScan( { " " }, { | e | nKey == Asc( e ) } ) != 0
   OTHERWISE
      RETURN .F.
   ENDCASE

   RETURN .T.

STATIC FUNCTION CreateButtons( oDlg, oBrowse, oBtnList )

   LOCAL nRow, nCol, cCaption, bCode, oBtn, cIcon
   LOCAL acOptions := { ;
      "Primeiro", "Pág.Ant", "Anterior", "Seguinte", "Pág.Seg", "Último", "Filtro", "Sair" }

   oBtnList := Array( Len( acOptions ) ) 
   nCol := 10
   nRow := 10
   FOR EACH oBtn IN oBtnList
      cCaption := acOptions[ oBtn:__EnumIndex() ]
      DO CASE
      CASE cCaption == "Primeiro"; cIcon := "icoTop" ;    bCode := { || oBrowse:Top() }
      CASE cCaption == "Último";   cIcon := "icoBottom" ; bCode := { || oBrowse:Bottom() }
      CASE cCaption == "Pág.Ant";  cIcon := "IcoPgUp";    bCode := { || oBrowse:PageUp() }
      CASE cCaption == "Pág.Seg";  cIcon := "IcoPgDn";    bCode := { || oBrowse:PageDown() }
      CASE cCaption == "Seguinte"; cIcon := "icoDown" ;   bCode := { || oBrowse:LineDown() }
      CASE cCaption == "Anterior"; cIcon := "icoUp" ;     bCode := { || oBrowse:LineUp() }
      CASE cCaption == "Filtro" ;  cIcon := "icoFilter" ; bCode := { || Nil }
      CASE cCaption == "Sair";     cIcon := "icoDoor" ;   bCode := { || oDlg:Close() }
      ENDCASE
      @ nCol, nRow OWNERBUTTON oBtn OF oDlg SIZE 80,80 ;
         ON CLICK bCode ;
         BITMAP ;
         /* AppLoadImage( cIcon, WIN_IMAGE_ICON, 70, 70 ) */ ;
         HICON():AddResource( cIcon, 60, 60 ) COORDINATES 5, 5, 60, 60 ;
         TEXT cCaption COORDINATES 5, 61, 75, 5 ;
         Tooltip cCaption
      oBtn:aStyle := ze_Set_StyleOBtn()
      nCol += 85
      IF nCol > 740
         nCol := 1
         nRow += 85
      ENDIF
   NEXT

   RETURN Nil

Pendências no browse

Enviado: 10 Fev 2023 18:03
por JoséQuintas
Funções que não fazem parte do normal da hwgui/Harbour:

AppWindowRect() - retorna o tamanho de minhas outras janelas
ADOLocal() - minha classe pra ADO, parece muito com o uso normal do ADO, mas facilita o uso.
ze_Set_StyleBtn() - só criei uma função com os estilos, assim vai ficar tudo igual, sem ter que mexer em cada fonte