FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Owner draw ComboBox
Posts: 375
Joined: Tue Feb 10, 2015 09:48 AM
Owner draw ComboBox
Posted: Fri Oct 11, 2019 06:54 AM
Hi everyone, I would like to share a my little experiment with owner draw ComboBox:



Here my code:
Code (fw): Select all Collapse
#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?
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Owner draw ComboBox
Posted: Fri Oct 11, 2019 07: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
Posts: 375
Joined: Tue Feb 10, 2015 09:48 AM
Re: Owner draw ComboBox
Posted: Wed Oct 16, 2019 11:16 AM
Another better sample, that uses windows style selected marker :-)


Code (fw): Select all Collapse
#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
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Owner draw ComboBox
Posted: Thu Nov 21, 2019 07: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 (fw): Select all Collapse
#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

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


Regards



G. N. Rao.

Hyderabad, India
Posts: 375
Joined: Tue Feb 10, 2015 09:48 AM
Re: Owner draw ComboBox
Posted: Fri Nov 22, 2019 09:21 AM

I like it very much!

Continue the discussion