Page 1 of 1

Abrir combobox con tecla Enter

PostPosted: Sat Apr 05, 2014 1:12 pm
by checo176
Hola Foro:

No se si alguien me puede dar una ayuda a un problema doméstico. Necesito saber como puedo abrir un combobox o DbCombo, presionando la tecla Enter y luego de seleccionar un elemento de la lista volver a presionar enter y que se cierre dejando el elemento seleccionado en el combo y a la vez que pase el enfoque a otro control (por ejemplo un textbox).

Será posible hacer esto, he buscado en el foro casos similares y no aparece nada

Se agradece sugerencias

Gracias. :)

Re: Abrir combobox con tecla Enter

PostPosted: Sat Apr 05, 2014 9:06 pm
by cnavarro
Sergio, para conseguir lo que pretendes necesitas o modificar la clase TCombobox, o utilizar una clase que herede de ella ya que el problema está, según creo, en el método Keychar de la clase
Te adjunto una clase que tenía hecha hace tiempo para ello, y solo la usaba en los Combobox de la aplicación en los que necesitaba esta funcionalidad.
Es muy sencilla de implementar incluso en la propia clase TCombobox, aunque yo prefiero siempre no modificar las clases iniciales (cuestion de gustos)

Code: Select all  Expand view

// El comando ha de ser modificado
#xcommand @ <nRow>, <nCol> MCOMBOBOX [ <oCbx> VAR ] <cVar> ;
             [ <it: PROMPTS, ITEMS> <aItems> ] ;
             [ SIZE <nWidth>, <nHeight> ] ;
             [ <dlg:OF,WINDOW,DIALOG> <oWnd> ] ;
             [ <help:HELPID, HELP ID> <nHelpId> ] ;
             [ ON CHANGE <uChange> ] ;
             [ VALID <uValid> ] ;
             [ <color: COLOR,COLORS> <nClrText> [,<nClrBack>] ] ;
             [ <pixel: PIXEL> ] ;
             [ FONT <oFont> ] ;
             [ <update: UPDATE> ] ;
             [ MESSAGE <cMsg> ] ;
             [ WHEN <uWhen> ] ;
             [ <design: DESIGN> ] ;
             [ BITMAPS <acBitmaps> ] ;
             [ ON DRAWITEM <uBmpSelect> ] ;
             [ STYLE <nStyle> ] ;
             [ <pict: PICT, PICTURE> <cPicture> ];
             [ ON EDIT CHANGE <uEChange> ] ;
       => ;
          [ <oCbx> := ] TMComboBox():New( <nRow>, <nCol>, bSETGET(<cVar>),;
             <aItems>, <nWidth>, <nHeight>, <oWnd>, <nHelpId>,;
             [{|Self|<uChange>}], <{uValid}>, <nClrText>, <nClrBack>,;
             <.pixel.>, <oFont>, <cMsg>, <.update.>, <{uWhen}>,;
             <.design.>, <acBitmaps>, [{|nItem|<uBmpSelect>}], <nStyle>,;
             <cPicture>, [<{uEChange}>], [<(oCbx)>] )

//---------------------------------------------------------------------------//

CLASS TMComboBox FROM TComboBox
     DATA lOpen
     METHOD New( nRow, nCol, bSetGet, aItems, nWidth, nHeight, oWnd, nHelpId,;
               bChange, bValid, nClrText, nClrBack, lPixel, oFont,;
               cMsg, lUpdate, bWhen, lDesign, acBitmaps, bDrawItem, nStyle,;
               cPict, bEChange ) CONSTRUCTOR
               
   
    METHOD KeyChar( nKey, nFlags )
   
ENDCLASS

//---------------------------------------------------------------------------//

METHOD New( nRow, nCol, bSetGet, aItems, nWidth, nHeight, oWnd, nHelpId,;
               bChange, bValid, nClrText, nClrBack, lPixel, oFont,;
               cMsg, lUpdate, bWhen, lDesign, acBitmaps, bDrawItem, nStyle,;
               cPict, bEChange ) CLASS TMComboBox
  ::lOpen  := .F.
  ::Super:New( nRow, nCol, bSetGet, aItems, nWidth, nHeight, oWnd, nHelpId,;
               bChange, bValid, nClrText, nClrBack, lPixel, oFont,;
               cMsg, lUpdate, bWhen, lDesign, acBitmaps, bDrawItem, nStyle,;
               cPict, bEChange )
               
Return Self

//---------------------------------------------------------------------------//

METHOD KeyChar( nKey, nFlags ) CLASS TMComboBox

   local nNewAT := 0, nOldAT := ::nAT, uItem

   if Len( ::aItems ) == 0
      return 0
   endif

   if ::lIncSearch
      do case
         case nKey = 32   // VK_DELETE (DO NOT WORK!)
              if Empty( ::oGet:hWnd )
                 ::cSearchKey = ""
                 nNewAt = 1
                 uItem  = ::aItems[ nNewAt ]
              else    
                 ::cSearchKey += " "
              endif  
           
         case nKey = VK_BACK
              ::cSearchKey = Left( ::cSearchKey, Len( ::cSearchKey ) - 1 )
           
         case nKey = 190
              nKey = 0
              ::cSearchKey += "."
             
         case ! Empty( ::oGet:hWnd ) .and. nKey = VK_TAB
              if ! GetKeyState( VK_SHIFT )
                 ::oWnd:GoNextCtrl( ::hWnd )
              else  
                 ::oWnd:GoPrevCtrl( ::hWnd )
              endif
              return 0  
           
         otherwise
            if nKey <> VK_RETURN          
              if ::lCaseSensitive
                 ::cSearchKey += Chr( nKey )
              else
                ::cSearchKey += Upper( Chr( nKey ) )
              endif
            endif
      endcase
      if nKey <> VK_RETURN
      if Empty( uItem )
         if nNewAt == 0
            if ::lCaseSensitive
               nNewAt = AScan( ::aItems, { | x | SubStr( x, 1, Len( ::cSearchKey ) ) == ::cSearchKey } )
            else
               nNewAt = AScan( ::aItems, { | x | SubStr( Upper( x ), 1, Len( ::cSearchKey ) ) == ::cSearchKey } )
            endif
            if Empty( ::oGet:hWnd )
               uItem = ::aItems[ If( nNewAt > 0, nNewAt, Max( ::nAT, 1 ) ) ]
            else  
               uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
               MsgInfo( uItem )
            endif  
         else
            uItem = ::aItems[ Max( nNewAt, 1) ]
         endif  
      endif
      ::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) )
      if ! Empty( ::oGet:hWnd )
         ::oGet:SetPos( Len( ::cSearchKey ) + 1 )
      endif
      endif  
   endif  

   if ::bChange != nil
      if ! Empty( ::oGet:hWnd ) .or. ( nNewAT != nOldAt .and. nNewAt != 0 )
         Eval( ::bChange, Self, ::VarGet() )
      endif  
   endif

   if nKey == VK_RETURN
      if ::IsOpen()
         //return ::oWnd:GoNextCtrl( ::hWnd )
      else
         if ::lOpen
            ::lOpen := .F.
            return ::oWnd:GoNextCtrl( ::hWnd )
         else
            ::Open()
            ::lOpen := .T.
         endif
      endif  
   endif
   
return If( ::lIncSearch, 0, nil )

//----------------------------------------------------------------------------//

 


Como ves, sólo he añadido una DATA (aunque de igual manera podrías utilizar la DATA cargo en su lugar) y modificado el METODO KEYCHAR
Espero te sirva
Aqui un ejemplo, aunque es lo mismo que tenías

Code: Select all  Expand view

   @ 22, 10 MCOMBOBOX oCbx VAR cTit1 ITEMS aItems ;
            OF oDlgR SIZE 140, 200 FONT oFont ;
            PIXEL COLOR CLR_BLACK, CLR_WHITE
            oCbx:lIncSearch  := .T.
 

Re: Abrir combobox con tecla Enter

PostPosted: Sat Apr 05, 2014 9:52 pm
by checo176
Cristobal:

Muchas gracias por tu ayuda y aporte, lo voy a probar y te comento. Sólo un pregunta, este cambio también se podria aplicar a un DbCombo??

Un abrazo desde Chile

Re: Abrir combobox con tecla Enter

PostPosted: Sat Apr 05, 2014 10:09 pm
by cnavarro
Tengo que mirarlo
No he usado prácticamente nada el DBCombo
Dime si te funciona y lo miro, porque el DbCombo tiene su propio método KeyChar, aunque la clase herede de TComboBox
Sería más fácil si me proporcionas un pequeño ejemplo con DBCombo

Re: Abrir combobox con tecla Enter

PostPosted: Sat Apr 05, 2014 11:23 pm
by checo176
Gracias Cristobal, lo revisare y te comento como resulta.

Un abrazo

Re: Abrir combobox con tecla Enter

PostPosted: Mon Apr 07, 2014 3:11 pm
by checo176
Crsitobal:

Efectué el cambio el Método KeyChar en la misma Clase TDbCombo, con el código que me enviaste, respaldando obviamente la librería FiveHx.lib antes de recomplilar la librería, pero no se ve ningún efecto en el sistema y no funciona como debiera, es decir al presionar Enter sobre el DBcombo, solo hace el cambio de foco, sin abrirse.

Crees tu que se debiera hacer otro cambio o que sugieres en este caso??

Te adjunto un ejemplo del código:

REDEFINE DBCOMBO oDesc_Emp VAR cDesc_Emp ID 4005 OF oDlg ;
ALIAS "Empresa" ;
ITEMFIELD "Codigo_Fem" ;
LISTFIELD "Nombre_Fem" ;
ON CHANGE Select_Emp(cDesc_Emp, oDesc_Emp, oBtn1);
VALID Get_Emp(cDesc_Emp, oDesc_Emp)

Re: Abrir combobox con tecla Enter

PostPosted: Mon Apr 07, 2014 4:42 pm
by cnavarro
La modificacion era solo para Combobox

Re: Abrir combobox con tecla Enter

PostPosted: Mon Apr 07, 2014 7:08 pm
by checo176
Cristobal:

Gracias por tu ayuda. Lo tendré presente, que sólo es para la Clase TCombobox. Que lastima, ya que en mis sistemas en la gran mayoría uso DBCombo.

Bueno seguiré buscando cómo puedo resolverlo. Aunque sólo es un tema de estética y una exigencia del Cliente.

Un abrazo :D

Saludos desde Chile