Page 1 of 2

LISTBOX HEADERS special characters

Posted: Tue Oct 17, 2006 6:35 am
by MarcoBoschi
To put in evidence if order type is descending or not I need to write in headers of my listboxs a character like down arrow or up arrow (in outlook there are triangles )
I use "MS Sans Serif" font and the only two characters approximately seem an arrow are "<" and ">" but they are horizontal. I need vertical
character.
Any ideas?
Thanks
Marco

Posted: Tue Oct 17, 2006 10:39 pm
by Gale FORd
How about \/ and /\ which are the left and right slashes

Posted: Wed Oct 18, 2006 6:46 am
by MarcoBoschi
You are in right!
Yesterday I analized my keyboard and thinked up the same idea

In my opinion all developer would appreciate this feature of twbrowse class:

two (up&down) 3d triangle in every index column header.
Like outlook and all other popular software.

Posted: Wed Oct 18, 2006 7:04 pm
by James Bott
Marco,

You can also use a bitmap graphic that contains both the symbol and the text.

James

Posted: Wed Oct 18, 2006 9:27 pm
by Enrico Maria Giordano
And where would you put those bitmaps? Please note that Marco needs to put them on the TWBrowse headers.

Anyway, I solved the problem using DIALOG's ON PAINT clause.

If Marco doesn't mind I can put the sample here. Marco?

EMG

Posted: Thu Oct 19, 2006 12:04 am
by James Bott
Enrico,

You can use bitmaps as headers just like you can use them as data.

hBMP1:=loadbitmap( getresources(),"cust")

@ 0,0 listbox...headers hBMP1, "Address"...

James

Posted: Thu Oct 19, 2006 7:06 am
by Enrico Maria Giordano
Wow! I absolutely wasn't aware of that feature!

Thank you!

EMG

Posted: Thu Oct 19, 2006 7:12 am
by Enrico Maria Giordano
Anyway, my solution can still be useful as it doesn't require to put the text inside the bitmap (text in bitmap will not get the font of the browse).

EMG

Posted: Thu Oct 19, 2006 10:13 am
by Biel EA6DD
Anyway, I solved the problem using DIALOG's ON PAINT clause.

If Marco doesn't mind I can put the sample here. Marco?
Hi Enrico, will be nice to see your solution.

Posted: Fri Oct 20, 2006 8:43 am
by Enrico Maria Giordano
Here it is:

Code: Select all

#include "Fivewin.ch"


#define MO_NONE 0
#define MO_ASC  1
#define MO_DESC 2


FUNCTION MAIN()

    LOCAL oDlg, oBrw, oFnt

    LOCAL hBmp1 := READBITMAP( 0, "\fwharbour\bitmaps\checkon.bmp" )
    LOCAL hBmp2 := READBITMAP( 0, "\fwharbour\bitmaps\checkoff.bmp" )

    LOCAL aOrd := { MO_ASC, MO_DESC, MO_NONE, MO_NONE }

    OVERRIDE METHOD SetPos CLASS TScrollbar WITH MySetPos

    USE TEST

    DEFINE DIALOG oDlg SIZE 400, 300

    DEFINE FONT oFnt NAME "Arial" SIZE 0, -12

    @ 0, 0 LISTBOX oBrw FIELDS TEST -> last,;
                               TEST -> first,;
                               IF( TEST -> last = "S", hBmp1, hBmp2 ),;
                               "";
           HEADER "LAST", "FIRST", " S", hBmp1;
           SIZES 100, 100, 16, 0;
           FONT oFnt

    oBrw:lCellStyle = .T.

    oBrw:bLClicked = { | nRow, nCol | If( oBrw:nAtCol( nCol ) = 3, Cambia( oDlg, oBrw, nRow ), ) }

    oBrw:bLButtonUp = { || oDlg:Refresh( .F. ) }

    oDlg:bStart = { || oBrw:oHScroll:bGoUp := { || oDlg:Refresh( .F. ) },;
                       oBrw:oHScroll:bGoDown := { || oDlg:Refresh( .F. ) },;
                       oBrw:bChange := { || oDlg:Refresh( .F. ) } }

    ACTIVATE DIALOG oDlg;
             ON INIT oDlg:SetControl( oBrw );
             ON PAINT MARCAORDINE( oDlg, hDC, oBrw, aOrd );
             CENTER

    CLOSE

    DELETEOBJECT( hBmp1 )
    DELETEOBJECT( hBmp2 )

    RELEASE FONT oFnt

    RETURN NIL


STATIC FUNCTION CAMBIA( oDlg, oBrw, nRow )

    IF NWROW( oBrw:hWnd, oBrw:hDC, nRow, IF( oBrw:oFont != nil, oBrw:oFont:hFont, 0 ) ) = 0
        RETURN NIL
    ENDIF

    ? "Qui cambi il valore che determina la spunta"

    oBrw:Refresh( .F. )

    oDlg:Refresh( .F. )

    RETURN NIL


#define SM_CYHSCROLL 3


STATIC FUNCTION MARCAORDINE( oDlg, hDC, oBrw, aOrd )

    LOCAL aValues   := oBrw:aHeaders
    LOCAL aColSizes := oBrw:GetColSizes()

    LOCAL nWidth := WNDWIDTH( oBrw:hWnd ) - IF( oBrw:oVScroll != nil .AND. EVAL( oBrw:bLogicLen ) > 1, GETSYSMETRICS( SM_CYHSCROLL ) + 3, 0 )

    LOCAL nColStart := -1

    LOCAL nTop, nLeft, nRight

    LOCAL hGPen, hWPen

    LOCAL i

    SYSREFRESH()

    hGPen = CREATEPEN( 0, 1, CLR_GRAY )
    hWPen = CREATEPEN( 0, 1, CLR_WHITE )

    nTop = oBrw:nTop + 6

    FOR i = oBrw:nColPos TO LEN( aValues )
        nLeft  = nColStart + 1
        nRight = MIN( nColStart := ( nLeft + aColSizes[ i ] - 1 ), nWidth )

        IF nLeft > nWidth
            EXIT
        ENDIF

        IF i == LEN( aValues )
           nRight = nWidth
        ENDIF

        nRight -= 12

        IF aOrd[ i ] = MO_ASC
            MOVETO( hDC, nRight, nTop )

            LINETO( hDC, nRight + 6, nTop, hGPen )
            LINETO( hDC, nRight + 3, nTop + 6, hWPen )
            LINETO( hDC, nRight, nTop, hGPen )
        ENDIF

        IF aOrd[ i ] = MO_DESC
            MOVETO( hDC, nRight, nTop + 6 )

            LINETO( hDC, nRight + 6, nTop + 6, hGPen )
            LINETO( hDC, nRight + 3, nTop, hWPen )
            LINETO( hDC, nRight, nTop + 6, hGPen )
        ENDIF
    NEXT

    DELETEOBJECT( hWPen )
    DELETEOBJECT( hGPen )

    RETURN NIL


#define SB_HORZ         0
#define SB_VERT         1
#define SB_CTL          2


STATIC FUNCTION MYSETPOS( nPos )

    LOCAL Self := HB_QSELF()

    ::oWnd:oWnd:Refresh( .F. )

    RETURN SETSCROLLPOS( IF( ::lIsChild, ::oWnd:hWnd, ::hWnd ), IF( ::lIsChild, IF( ::lVertical, SB_VERT, SB_HORZ ), SB_CTL ), nPos, ::lReDraw )
EMG

Posted: Fri Oct 20, 2006 12:42 pm
by Taiwan
Hello EMG,

Looks nice job.
Could you show me this sample screen shot?

Thank you.

Richard

Posted: Fri Oct 20, 2006 1:53 pm
by Enrico Maria Giordano
Sent to your private email.

EMG

Posted: Sun Oct 22, 2006 2:20 pm
by Enrico Maria Giordano
This is a much better version using inheritance:

Code: Select all

#include "Fivewin.ch"


#define MO_NONE 0
#define MO_ASC  1
#define MO_DESC 2


FUNCTION MAIN()

    LOCAL oDlg, oBrw

    USE TEST

    DEFINE DIALOG oDlg SIZE 400, 300

    oBrw = TMyWBrowse():New( 0, 0, , ,;
                             { || { TEST -> last, TEST -> first, "" } },;
                             { "LAST", "FIRST", "" },;
                             { 150, 150, 0 } )

    oBrw:lCellStyle = .T.

    oBrw:aOrd = { { || MO_ASC }, { || MO_DESC }, { || MO_NONE }, { || MO_NONE } }

    ACTIVATE DIALOG oDlg;
             ON INIT oDlg:SetControl( oBrw );
             CENTER

    CLOSE

    RETURN NIL


CLASS TMyWBrowse FROM TWBrowse

    DATA aOrd

    METHOD Paint()

ENDCLASS


METHOD Paint() CLASS TMyWBrowse

    Super:Paint()

    MARCAORDINE( ::oWnd, ::hDC, Self, ::aOrd )

    RETURN 0


#define SM_CYHSCROLL 3


STATIC FUNCTION MARCAORDINE( oDlg, hDC, oBrw, abOrd )

    LOCAL aValues   := oBrw:aHeaders
    LOCAL aColSizes := oBrw:GetColSizes()

    LOCAL nWidth := WNDWIDTH( oBrw:hWnd ) - IF( oBrw:oVScroll != nil .AND. EVAL( oBrw:bLogicLen ) > 1, GETSYSMETRICS( SM_CYHSCROLL ) + 3, 0 )

    LOCAL nColStart := -1

    LOCAL nTop, nLeft, nRight

    LOCAL hGPen, hWPen

    LOCAL i

    hGPen = CREATEPEN( 0, 1, CLR_GRAY )
    hWPen = CREATEPEN( 0, 1, CLR_WHITE )

    nTop = oBrw:nTop + 5

    FOR i = oBrw:nColPos TO LEN( aValues )
        nLeft  = nColStart + 1
        nRight = MIN( nColStart := ( nLeft + aColSizes[ i ] - 1 ), nWidth )

        IF nLeft > nWidth
            EXIT
        ENDIF

        IF i == LEN( aValues )
           nRight = nWidth
        ENDIF

        nRight -= 10

        IF EVAL( abOrd[ i ] ) = MO_ASC
            MOVETO( hDC, nRight, nTop )

            LINETO( hDC, nRight + 6, nTop, hGPen )
            LINETO( hDC, nRight + 3, nTop + 6, hWPen )
            LINETO( hDC, nRight, nTop, hGPen )
        ENDIF

        IF EVAL( abOrd[ i ] ) = MO_DESC
            MOVETO( hDC, nRight, nTop + 6 )

            LINETO( hDC, nRight + 6, nTop + 6, hGPen )
            LINETO( hDC, nRight + 3, nTop, hWPen )
            LINETO( hDC, nRight, nTop + 6, hGPen )
        ENDIF
    NEXT

    DELETEOBJECT( hWPen )
    DELETEOBJECT( hGPen )

    RETURN NIL
EMG

Posted: Sun Oct 22, 2006 10:03 pm
by James Bott
Enrico,

May I ask why did you subclass then put all the code in a static function?

Wouldn't it be better to put all the code in the new Paint method?

James

Posted: Sun Oct 22, 2006 10:42 pm
by Enrico Maria Giordano
Yes, it was just an experiment.

EMG