Owner draw ComboBox

Owner draw ComboBox

Postby AntoninoP » Fri Oct 11, 2019 6:54 am

Hi everyone, I would like to share a my little experiment with owner draw ComboBox:

Image

Here my code:
Code: Select all  Expand view  RUN
#include <fivewin.ch>

function Main()
   local oWnd, oCombo, aItems, cCurr

    DEFINE WINDOW oWnd from 100,100 to 200,400  PIXEL
    aItems := GETFONTNAMES(oWnd:getDc())
    oWnd:ReleaseDC()
    //@ 10,10 COMBOBOX oCombo VAR cCurr ITEMS aItems SIZE 200,25 PIXEL STYLE CBS_DROPDOWNLIST+CBS_OWNERDRAWFIXED
    // precompile the code upper to get the code below
    oCombo := MyCombo():New( 10, 10, { | u | If( PCount()==0, cCurr, cCurr:= u ) }, aItems, ;
                200, 25,,,,,,, .T.,,, .F.,, .F.,{""},,CBS_DROPDOWNLIST+CBS_OWNERDRAWFIXED,,, "oCombo",,,,,,, )
    oCombo:lOwnerDraw := .T.
    ACTIVATE WINDOW oWnd
return 0

class MyCombo inherit TComboBox
    METHOD DrawItem( nIdCtl, nPStruct )
endclass

#define WHITE_BRUSH   0

METHOD DrawItem( nIdCtl, nPStruct ) CLASS MyCombo
    LOCAL aData := GetDrawItemStruct(nPStruct)
    LOCAL hDC := aData[7], aRect := {aData[8],aData[9],aData[10],aData[11]}
    LOCAL cFont, oFont
    if aData[3]>=0
        cFont := ::aItems[aData[3]+1]
    endif
    FillRect(hDC,aRect, GetStockObject( WHITE_BRUSH ) )
    if aData[5]=0
         // unselected item
        //MoveTo(hDC, aData[9], aData[8])
        //LineTo(hDC, aData[11], aData[10])
    else
        // Selected item
        MoveTo(hDC, aData[9], aData[10])
        LineTo(hDC, aData[11], aData[8])
    endif
    if !empty(cFont)
        DEFINE Font oFont NAME cFont
        oFont:Activate(hDC)
        DrawTextEx(hDC,cFont,aRect,1)
        oFont:End()
    endif
return 1


It would be great if FiveWin included a bDrawItem with hDC.

What do you think?
AntoninoP
 
Posts: 375
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy

Re: Owner draw ComboBox

Postby cnavarro » Fri Oct 11, 2019 7:37 am

I think this is a good idea, when lOwnerDraw := .T.
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Owner draw ComboBox

Postby AntoninoP » Wed Oct 16, 2019 11:16 am

Another better sample, that uses windows style selected marker :)

Image
Code: Select all  Expand view  RUN
#include <fivewin.ch>
#define CBS_OWNERDRAWVARIABLE 0x0020

function Main()
   local oWnd, oCombo, aItems, cCurr

    DEFINE WINDOW oWnd from 100,100 to 200,400  PIXEL
    aItems := GETFONTNAMES(oWnd:getDc())
    oWnd:ReleaseDC()
    oCombo := MyCombo():New( 10, 10, { | u | If( PCount()==0, cCurr, cCurr:= u ) }, aItems, ;
                200, 25,,,,,,, .T.,,, .F.,, .F.,{""},,CBS_DROPDOWNLIST+CBS_OWNERDRAWFIXED,,, "oCombo",,,,,,, )
    //@ 10,10 COMBOBOX oCombo VAR cCurr ITEMS aItems SIZE 200,25 PIXEL
    oCombo:lOwnerDraw := .T.
    //oCombo:WinStyle(CBS_OWNERDRAWFIXED,.T.)

    ACTIVATE WINDOW oWnd
return 0

//procedure InitDlg(oDlg)


class MyCombo inherit TComboBox
    METHOD DrawItem( nIdCtl, nPStruct )
endclass

#define WHITE_BRUSH   0
#define COLOR_HIGHLIGHT      13
#define COLOR_HIGHLIGHTTEXT  14
#define COLOR_WINDOW          5
#define COLOR_WINDOWTEXT      6

METHOD DrawItem( nIdCtl, nPStruct ) CLASS MyCombo
    LOCAL aData := GetDrawItemStruct(nPStruct)
    LOCAL hDC := aData[7], aRect := {aData[8],aData[9],aData[10],aData[11]}
    LOCAL cFont, oFont
    if aData[3]>=0
        cFont := ::aItems[aData[3]+1]
    endif
    FillRect(hDC,aRect, GetStockObject( WHITE_BRUSH ) )
    if hb_bitAnd(aData[5],1)>0
        SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT))
        SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT))
    else
        SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT))
        SetBkColor(hDC, GetSysColor(COLOR_WINDOW))
    endif
    if !empty(cFont)
        DEFINE Font oFont NAME cFont SIZE nil,aData[10]-aData[8]
        oFont:Activate(hDC)
        //DrawTextEx(hDC,cFont,aRect,1)
        //SetTextAlign(hDC, 6)
        //ExtTextOut(hDC, aData[8], (aData[9]+aData[11])/2, aRect, cFont, 6)
        ExtTextOut(hDC, aData[8], aData[9]+3, aRect, cFont,2)
        oFont:End()
    endif
    if hb_bitAnd(aData[5],1)>0
        DrawFocusRect(hDC,aData[8],aData[9],aData[10],aData[11])
        SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT))
        SetBkColor(hDC, GetSysColor(COLOR_WINDOW))
    endif
    //MsgInfo("Called")
return 1
AntoninoP
 
Posts: 375
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy

Re: Owner draw ComboBox

Postby nageswaragunupudi » Thu Nov 21, 2019 7:08 pm

Thanks for the suggestion.

There already exists bDrawItem. Now a new data bOwnerDraw is provided for this purpose in the new version.

This sample is an adaptation of the proposed code posted above.
Code: Select all  Expand view  RUN

#include "fivewin.ch"

#define WHITE_BRUSH           0
#define COLOR_HIGHLIGHT      13
#define COLOR_HIGHLIGHTTEXT  14
#define COLOR_WINDOW          5
#define COLOR_WINDOWTEXT      6

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

function Main()

   local oWnd, oCbx, aItems, cItem, oFont

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-24
   DEFINE WINDOW oWnd
   oWnd:SetFont( oFont )

   aItems   := GetFontNames( oWnd:GetDC() )
   oWnd:ReleaseDC()
   cItem    := aItems[ 1 ]

   @ 40,40 COMBOBOX oCbx VAR cItem ITEMS aItems SIZE 300,400 PIXEL OF oWnd ;
      OWNERDRAW OwnerDrawItem( Self, nIdCtl, oItemStruct )

   ACTIVATE WINDOW oWnd CENTERED
   RELEASE FONT oFont

return nil

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

function OwnerDrawItem( Self, nIdCtl, oItem )

   local cFont, oFont
   local hDC      := oItem:hDC

    if oItem:itemID >= 0
        cFont := oItem:itemData
    endif

    FillRect( hDC, oItem:aRect, GetStockObject( WHITE_BRUSH ) )

    if lAnd( oItem:itemState, 1 )
        SetTextColor( hDC, GetSysColor( COLOR_HIGHLIGHTTEXT ) )
        SetBkColor(   hDC, GetSysColor( COLOR_HIGHLIGHT ) )
    else
        SetTextColor( hDC, GetSysColor( COLOR_WINDOWTEXT ) )
        SetBkColor(   hDC, GetSysColor( COLOR_WINDOW ) )
    endif

    if !Empty( cFont )
        DEFINE Font oFont NAME cFont SIZE nil, oItem:nHeight
        oFont:Activate( hDC )
        ExtTextOut( hDC, oItem:nTop, oItem:nLeft + 3, oItem:aRect, cFont, 2 )
        oFont:End()
    endif

    if lAnd( oItem:itemState, 1 )
        DrawFocusRect( hDC, oItem:nTop, oItem:nLeft, oItem:nBottom, oItem:nRight )
        SetTextColor(  hDC, GetSysColor( COLOR_WINDOWTEXT ) )
        SetBkColor(    hDC, GetSysColor( COLOR_WINDOW ) )
    endif

return 1

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


Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10660
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Owner draw ComboBox

Postby AntoninoP » Fri Nov 22, 2019 9:21 am

I like it very much!
AntoninoP
 
Posts: 375
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: nageswaragunupudi and 32 guests