Yo por ejemplo lo hago con el bRclicked(), pero bueno, eso ya es cueti贸n de gustos...
aqu铆 te dejo algo de c贸digo por si te puede servir para coger ideas, est谩 hecho para TSbrowse.
#include "FiveWin.ch"
#include "TSBrowse.ch"
#define CLR_PINK 聽 nRGB( 255, 128, 128)
#define CLR_NBLUE 聽nRGB( 128, 128, 192)
#define CLR_1 nRGB( 190, 215, 190 )聽// Azul Clarito
#define CLR_2 nRGB( 230, 230, 230 )聽// Gris muy Clarito
#define CLR_3 nRGB( 217, 217, 255 )聽// Morado Clarito
//----------------------------------------------------------------------------//
// Nueva implementaci贸n con la clase TSBrowse de Manuel Mercado.
FUNCTION Browse3( cTitle, cListName, bNew, bModify, bDelete, bSearch, bList, oParWnd, oDbf )
聽 聽LOCAL oDlg, oLbx, oFont, nOrden
聽 聽LOCAL btnList, btnEnd, i, aFields:={}
聽 聽//Guardamos el orden de entrada.
聽 聽nOrden:= IndexOrd()
聽 聽
聽 聽DEFAULT cTitle 聽:= "Ver fichas ", cListName := "",;
聽 聽 聽 聽 聽 聽bList 聽 := { || Reporte( oLbx ) }
聽 聽DEFINE FONT oFont NAME "Arial" SIZE 0, -12 //BOLD
聽 聽DEFINE DIALOG oDlg FROM 3, 3 TO 26, 79 TITLE cTitle FONT oFont
聽 聽@ 0, 1 SAY cListName 聽OF oDlg
聽 聽@ 1, 1 BROWSE oLbx SIZE 284, 137 OF oDlg FONT oFont;
聽 聽 聽 聽 聽 ON CHANGE ( IF(oDbf!=NIL,oDbf:Gather(),), IF( oParWnd!=NIL,oParWnd:Update(),) );
聽 聽 聽 聽 聽 ON dblClick ( oDlg:End() )
聽 聽oLbx:LoadFields( .F. )
聽 聽oLbx:nLineStyle := LINES_DOTTED
聽 聽oLbx:nHeightHead += 4
聽 聽oLbx:lMoveCols := .T.
聽 聽oLbx:nAdjColumn := 0
聽 聽aFields:= DbStruct()
聽 聽FOR i:=1 TO LEN( oLbx:aColumns )
聽 聽 聽 聽oLbx:aColumns[ i ]:cHeading:= UPPER( oLbx:aColumns[ i ]:cHeading )
聽 聽 聽 聽oLbx:aColumns[ i ]:l3DLookHead:=.T.
聽 聽 聽 聽oLbx:SetColSize( i, oLbx:aColumns[ i ]:nWidth + 42 )
聽 聽 聽 聽IF aFields[i][2] = "N"聽 聽// Num茅rico
聽 聽 聽 聽 聽oLbx:aColumns[ i ]:nAlign:= 2
聽 聽 聽oLbx:aColumns[ i ]:nHAlign:= 0
聽 聽 聽 聽ENDIF
聽 聽 聽 聽//oLbx:Set3DText( , , 聽i , 2 聽)
聽 聽NEXT
聽 聽// Seteo de colores del Browse.
聽 聽oLbx:SetColor( { 2, 3, 4, 5, 6, 15 },{ { | Pos | If( Pos % 2 = 0, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 CLR_3, CLR_2 ) }, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 CLR_WHITE,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 { CLR_WHITE, CLR_BLUE },;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 CLR_WHITE,;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 { CLR_WHITE, CLR_BLACK },;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 CLR_BLUE })
聽 聽
聽 聽//Botones del dialogo
聽 聽@ 10.4, 33.6 BUTTON btnList 聽 PROMPT "&Imprimir" OF oDlg SIZE 40, 12
聽 聽@ 10.4, 41.7 BUTTON btnEnd 聽 聽PROMPT "&Salir" 聽 聽OF oDlg SIZE 40, 12
聽 聽btnList:bAction 聽 = { || Eval( bList ), oLbx:Refresh() }
聽 聽btnEnd:bAction 聽 聽= { || oDlg:End() }
聽 聽// Para ejecutar la funci贸n de ordenar por la columna.
聽 聽oLbx:bRClicked := {|nRowPix, nColPix| CreaIndice( oLbx, oDbf, aFields, oLbx:nATCol(nColPix)) }
聽 聽ACTIVATE DIALOG oDlg Centered;
聽 聽 聽 聽 聽 聽 ON PAINT FillWnd( oDlg, nRGB( 13, 147, 185 ),, 10 );
聽 聽 聽 聽 聽 聽 ON INIT CampoIndice( oLbx, aFields );
聽 聽 聽 聽 VALID ( DBSETORDER(nOrden), .T. )
// En el ON INIT estamos colocando como primera columna al campo clave del 铆ndice activo
RELEASE FONT oFont
return nil
//----------------------------------------------------------------------------//
// Colocaci贸n del campo 铆ndice activo como primera columna en el browse
//----------------------------------------------------------------------------//
STATIC FUNCTION CreaIndice( oLbx, oDbf, aFields, nCol )
LOCAL aIndices:={}, aIndices2:={}, n, j
//Averiguamos si el campo ya tiene un 铆ndice activo, en caso de tenerlo lo activamos
//En caso contrario generamos un 铆ndice temporal y lo a帽adimos a los 铆ndices activos.
//Cambiamos la columna a la 1陋 posici贸n en el browse.
//Indices en uso del fichero:
FOR j := 1 TO 15
聽 聽IF !Empty( cExpKey:= IndexKey( j ) )
聽 聽 聽 AADD( aIndices2, 聽ORDBAGNAME(j) 聽)
聽 聽 聽 聽 聽IF (n := AT("(", cExpKey)) > 0//n > 0 聽 //Quitamos los caracteres STR(
聽 聽 聽 聽 聽 聽 cExpKey:= LEFT(cExpKey, n-4) + RIGHT(cExpKey, LEN(ALLTRIM(cExpKey))-n )
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽IF (n := AT(")", cExpKey) ) > 0聽 聽 //n > 0 聽 //Quitamos los caracteres ,n,y)
聽 聽 聽 聽 聽 聽 cExpKey:= LEFT(cExpKey, n-5) + RIGHT(cExpKey, LEN(ALLTRIM(cExpKey))-n )
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 聽 聽IF (n := AT("+", cExpKey) ) >0聽//n > 0 //Quitamos todo lo que est谩 por detr谩s del caracter +
聽 聽 聽 聽 聽 聽 cExpKey:=LEFT(cExpKey, n-1)
聽 聽 聽 聽 聽ENDIF
聽 聽 聽 AADD( aIndices, 聽UPPER(cExpKey) 聽)
聽 聽 ENDIF
NEXT
IF ( n:=ASCAN( aIndices, oLbx:aColumns[ nCol ]:cHeading 聽) ) > 0
聽 聽//Ya existe ese 铆ndice
聽 聽//Ponemos el orden como activo.
聽 聽DBSETORDER(n)
ELSE
聽 聽//Creamos un 铆ndice si no existe.
聽 聽CreaIndex( oLbx:aColumns[ nCol ]:cHeading, aIndices2 )
聽 聽SET INDEX TO
聽 聽FOR j := 1 TO LEN( aIndices2 )
聽 聽 聽oDbf:AddIndex(aIndices2[j],aIndices2[j])
聽 聽NEXT
聽 聽SELECT( oDbf:cAlias )
聽 聽DBSETORDER( LEN(aIndices2) )
ENDIF
//Cambiamos el campo 铆ndice como 1陋 columna
oLbx:MoveColumn( nCol, 1 )
oDbf:GoFirst()
oLbx:GoTop()
oLbx:Reset()
RETURN NIL
//----------------------------------------------------------------------------//
// Colocaci贸n del campo 铆ndice activo como primera columna en el browse
//----------------------------------------------------------------------------//
STATIC FUNCTION CreaIndex( cHeading, aIndices2 )
LOCAL tempind1, passind, pasfor
tempind1 = "CC" + SUBSTR(TIME(),1,2) + SUBSTR(TIME(),4,2) + SUBSTR(TIME(),7,2) + ".ntx"
passind 聽= cHeading聽//"Recno()"
passfor 聽= "Recno() > 0"
MsgMeter( { | ometer, otext, odlg, lend | genindex( ometer, otext, odlg, @lend, tempind1, passind, passfor ) }, ;
聽 聽 聽 聽 聽 聽 "Ordenando fichero ...", "Ordenando fichero ...." )
AADD( aIndices2, 聽tempind1 聽)
RETURN NIL
//----------------------------------------------------------------------------//
// Creaci贸n del fichero 铆ndice temporal.
//----------------------------------------------------------------------------//
STATIC FUNCTION genindex( ometer, otext, odlg, lend, tempind1, passind, passfor )
LOCAL cDbf
cDbf:=ALIAS()
ometer:ntotal := LASTREC()
INDEX ON &passind TO &tempind1 聽FOR &passfor ;
聽 聽EVAL ( ometer:SET( RECNO() ), otext:settext("Ordenando ficha " + ALLTRIM(STR(RECNO()))), ;
聽 聽sysrefresh(), !lend )
RETURN( nil )
//----------------------------------------------------------------------------//
// Colocaci贸n del campo 铆ndice activo como primera columna en el browse
//----------------------------------------------------------------------------//
STATIC FUNCTION CampoIndice( oLbx, aFields )
LOCAL nOrden, cExpKey
聽 聽//Posicionamiento de campo 铆ndice activo en primer lugar.
聽 聽nOrden:= IndexOrd()
聽 聽cExpKey:= IndexKey( nOrden )
聽 聽IF LEN(ALLTRIM(cExpKey)) > 0
聽 聽 聽 n := AT("(", cExpKey)聽//Quitamos los caracteres STR(
聽 聽 聽 IF n > 0
聽 聽 聽 聽 聽cExpKey:= LEFT(cExpKey, n-4) + RIGHT(cExpKey, LEN(ALLTRIM(cExpKey))-n )
聽 聽 聽 ENDIF
聽 聽 聽 n := AT(")", cExpKey)聽//Quitamos los caracteres ,n,y)
聽 聽 聽 IF n > 0
聽 聽 聽 聽 聽cExpKey:= LEFT(cExpKey, n-5) + RIGHT(cExpKey, LEN(ALLTRIM(cExpKey))-n )
聽 聽 聽 ENDIF
聽 聽 聽 n := AT("+", cExpKey)聽//Quitamos todo lo que est谩 por detr谩s del caracter +
聽 聽 聽 IF n > 0
聽 聽 聽 聽 聽cExpKey:=LEFT(cExpKey, n-1)
聽 聽 聽 ENDIF
聽 聽 聽 //La movemos a la primera columna
聽 聽 聽 IF (nPos:=ASCAN( aFields, {|x| x[1] = UPPER(cExpKey) } ) ) > 0
聽 聽 聽 聽 聽oLbx:MoveColumn( nPos, 1 )
聽 聽 聽 ENDIF
聽 聽ENDIF
RETURN NIL