Combobox Ownerdraw with Icon from DLL Sample

Combobox Ownerdraw with Icon from DLL Sample

Postby Jimmy » Mon Feb 20, 2023 8:41 am

hi,

here a Demo how to use Ownerdraw with Comboxbox
it also show how to access System Icon "on-fly" so it will look same as Windows OS
Image

Code: Select all  Expand view  RUN
#include "Fivewin.ch"
#include "WCOLORS.CH"

* #DEFINE Use_Command       // PLEASE enable and make it work like OOP Result
#DEFINE use_IconEx

#define DRIVE_UNKNOWN         0
#define DRIVE_NO_ROOT_DIR     1
#define DRIVE_REMOVABLE       2
#define DRIVE_FIXED           3
#define DRIVE_REMOTE          4
#define DRIVE_CDROM           5
#define DRIVE_RAMDISK         6

#define DT_LEFT               0x00000000
#define DT_WORDBREAK          0x00000010
#define DT_NOPREFIX           0x00000800
#define DT_VCENTER            4
#define DT_SINGLELINE         32
#define DT_CENTER             1

#define DI_IMAGE              0x0002
#define DI_NORMAL             0x0003

#define ODA_DRAWENTIRE        0x0001
#define ODA_SELECT            0x0002
#define ODA_FOCUS             0x0004

#define ODT_LISTBOX           2
#define ODT_COMBOBOX          3

#define ODS_SELECTED          0x0001
#define ODS_FOCUS             0x0010
#define ODS_DEFAULT           0x0020

STATIC acItem, acType, acBitmaps, nFirstUSB
STATIC BFcolor
STATIC BGcolor

*+--------------------------------------------------------------------
*+
*+    Procedure Main()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE Main()

LOCAL oMain, oFontDefault, oCombo
LOCAL nFontSize := 20
LOCAL cPath     := ´C:\´

   BFcolor := nRGB(0,255,255) // CLR_BLACK
   BGcolor := nRGB(0,0,1)     // CLR_WHITE

   GetAllDrive()

   DEFINE FONT oFontDefault NAME "TAHOMA" SIZE 0, - nFontSize
      ACTIVATE FONT oFontDefault
#IFDEF __HMG__
   END FONT
#ENDIF

   DEFINE WINDOW oMain FROM 0, 0 TO 400, 300 PIXEL TITLE "FiveWin Combobox Ownerdraw Demo " COLOR BFcolor, BGcolor

#IFDEF Use_Command
      @ 10, 10 COMBOBOX oCombo ITEMS acItem SIZE 90, 300 COLOR BFcolor, BGcolor PIXEL FONT oFontDefault BITMAPS acBitmaps ;
              ON DRAWITEM { | a, b, c, d | DoMyComBo( a, b, c, d, @acItem, @acType, @acBitmaps, oCombo ) }
#ELSE
      oCombo := TComboBox() :new( 10, 10,, acItem, 90, 300, oMain,,,, BFcolor, BGcolor, .T., oFontDefault,,,, .F., acBitmaps )
      oCombo:nDropWidth( 200 )
      oCombo:nItemHeight( 32 )
      oCombo:nSelectionHeight( 32 )
      oCombo:Select( 1 )
      oCombo:lIncSearch := .T.
      oCombo:bKeyDown := NIL
      oCombo:bOwnerDraw := { | a, b, c, d | DoMyComBo( a, b, c, d, @acItem, @acType, @acBitmaps, oCombo ) }
      oCombo:GetKeyChar( ASC( SUBSTR( cPath, 1, 1 ) ) )
#ENDIF

#IFDEF __HMG__
   END WINDOW
#ENDIF

   ACTIVATE WINDOW oMain CENTER

RETURN

*+--------------------------------------------------------------------
*+
*+    Function DoMyComBo()
*+
*+    Called from ( cbowner.prg )   2 - procedure main()
*+                ( dualgrid.prg )   1 - class texplorer
*+
*+--------------------------------------------------------------------
*+
FUNCTION DoMyComBo()

LOCAL WinDir        := GETENV( "Windir" )
LOCAL cPara         := ""
LOCAL cAlign        := nOr( DT_LEFT, DT_NOPREFIX )
LOCAL nIcoHandle    := 0
LOCAL nSize         := 32
LOCAL ii, nCount, xPara
LOCAL oSelf
LOCAL nIdCtl
LOCAL oStruc
LOCAL nPointer
LOCAL acItem, acType, cItemText, oObj
LOCAL CtlType
LOCAL CtlID
LOCAL itemID
LOCAL itemAction
LOCAL itemState
LOCAL hwndItem
LOCAL hDC
LOCAL aRect
LOCAL nLeft
LOCAL nTop
LOCAL nRight
LOCAL nBottom
LOCAL itemData
LOCAL cDLL
LOCAL hModule
LOCAL nResID
LOCAL aBitmaps, hBitMap, acBitmaps
LOCAL OldAt         := - 1
LOCAL BrushHiBack   := CreateSolidBrush( BFcolor )
LOCAL BrushSysColor := CreateSolidBrush( BGcolor )
LOCAL aGrad         := { ;
                    { .5, BFcolor, BGcolor }, ;
                    { .6, BGcolor, BFcolor }, ;
                    { .1, BFcolor, BGcolor }, ;
                    }

   nCount := PCOUNT()
   FOR ii := 1 TO nCount
      xPara := PValue( ii )
      DO CASE
         CASE ii = 1
            oSelf := xPara
         CASE ii = 2
            nIdCtl := xPara
         CASE ii = 3
            oStruc := xPara
         CASE ii = 4
            nPointer := xPara
         CASE ii = 5
            acItem := xPara
         CASE ii = 6
            acType := xPara
         CASE ii = 7
            acBitmaps := xPara
         CASE ii = 8
            oObj := xPara
            IF !EMPTY( oObj )
               IF VALTYPE( oObj ) = "O"
                  OldAt := oObj:nAt
               ENDIF
            ENDIF
      ENDCASE
   NEXT

   CtlType     := oStruc:CtlType
   CtlID       := oStruc:CtlID
   itemID      := oStruc:itemID
   itemAction  := oStruc:itemAction
   itemState   := oStruc:itemState
   hwndItem    := oStruc:hwndItem
   hDC         := oStruc:hDC
   aRect       := oStruc:aRect
   itemData    := oStruc:itemData

   nTop        := aRect[ 1 ]
   nLeft       := aRect[ 2 ]
   nBottom     := aRect[ 3 ]
   nRight      := aRect[ 4 ]

   IF CtlType = ODT_COMBOBOX .OR. CtlType = ODT_LISTBOX               // .AND. CtlID =

      SetBkMode( hDC, 1 )                                             // TRANSPARENT =1 OPAQUE =2

      DO CASE
         CASE itemAction = ODA_SELECT                                
            FillRect( hDC, aRect, BrushSysColor )
            SetTextColor( hDC, BFcolor )

         CASE itemAction = ODA_DRAWENTIRE
            IF OldAt = itemID + 1 .AND. oObj:IsOpen()
               OldAt = - 1
               IF BGColor = 256 * 256 * 256 - 1                       // 16777215
                  //  Msginfo("white")
                  FillRect( hDC, aRect, COLOR_MENUHILIGHT + 1 )
                  SetTextColor( hDC, GetSysColor( COLOR_MENU ) )
               ELSE
                  GradientFill( hDC, aRect[ 1 ], aRect[ 2 ], aRect[ 3 ] - 1, aRect[ 4 ], aGrad, .t. )
                  SetTextColor( hDC, BFcolor )
               ENDIF
            ELSE
               FillRect( hDC, aRect, BrushSysColor )
               SetTextColor( hDC, BFcolor )
            ENDIF

         CASE itemAction = ODA_FOCUS
            IF BGColor = 256 * 256 * 256 - 1                          // 16777215
               FillRect( hDC, aRect, COLOR_MENUHILIGHT + 1 )
               SetTextColor( hDC, GetSysColor( COLOR_MENU ) )
            ELSE
               GradientFill( hDC, aRect[ 1 ], aRect[ 2 ], aRect[ 3 ] - 1, aRect[ 4 ], aGrad, .t. )
               SetTextColor( hDC, BFcolor )
            ENDIF

      ENDCASE

#IFDEF use_IconEx

      cDLL := WinDir + "\System32\imageres.dll"

      DO CASE
         CASE acType[ itemID + 1 ] = DRIVE_UNKNOWN
            nResID := 75
         CASE acType[ itemID + 1 ] = DRIVE_NO_ROOT_DIR
            nResID := 32

         CASE acType[ itemID + 1 ] = DRIVE_REMOVABLE
            IF SUBSTR( acItem[ itemID + 1 ], 1, 1 ) $ "AB"
               nResID := 23
            ELSE
               cDLL := WinDir + "\System32\DDORes.dll"
               nResID := 2389
            ENDIF

         CASE acType[ itemID + 1 ] = DRIVE_FIXED
            IF SUBSTR( acItem[ itemID + 1 ], 1, 2 ) = "C:"
               nResID := 36
            ELSE
               nResID := 32
            ENDIF
         CASE acType[ itemID + 1 ] = DRIVE_REMOTE
            nResID := 33
         CASE acType[ itemID + 1 ] = DRIVE_CDROM
            nResID := 30
         CASE acType[ itemID + 1 ] = DRIVE_RAMDISK
            nResID := 34

      ENDCASE

      hModule := GetModuleHandle( cDLL )
      IF hModule == 0
         hModule := LoadLibrary( cDLL )
      ENDIF
      nIcoHandle := LOADIMAGERESICON( hModule, nResID, 32 )

      DrawIconEx( hDC, ;
                  nTop - 4, ;
                  nLeft, ;
                  nIcoHandle, ;
                  nSize, ;
                  nSize, ;
                  0, ;                                                // _In_     UINT   istepIfAniCur,
                  0, ;                                                // _In_opt_ HBRUSH hbrFlickerFreeDraw,
                  nOr( DI_NORMAL ) )                                  // _In_     UINT   diFlags

      DestroyIcon( nIcoHandle )
      FreeLibrary( hModule )

#ELSE

      aBitmaps := FW_ReadImage( nil, acBitmaps[ itemID + 1 ], { nSize - 2, nSize - 2 }, .F. )
      hBitMap := aBitmaps[ 1 ]

      DrawBitmap( hDC, hBitMap, nTop + 3, nLeft, nSize - 3, nSize - 6 )

      PalBmpFree( aBitmaps )
      DeleteObject( hBitMap )

#ENDIF

      nLeft += 32 + 4

      cItemText := acItem[ itemID + 1 ]

      DrawText( hDC, ;
                cItemText, ;
                { nTop + 4, nLeft, nBottom, nRight }, ;
                cAlign )
   ENDIF

   DeleteObject( BrushHiBack )
   DeleteObject( BrushSysColor )

RETURN .T.

*+--------------------------------------------------------------------
*+
*+    Static Function GetAllDrive()
*+
*+    Called from ( cbowner.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION GetAllDrive()

LOCAL aDrives := aDrives()
LOCAL ii, cDrive, nType, cLabel, cBitmap

   acItem    := {}
   acBitmaps := {}
   acType    := {}
   nFirstUSB := 0

   FOR ii := 1 TO LEN( aDrives )
      cDrive := SUBSTR( aDrives[ ii ], 1, 1 )
      nType := GETDRIVETYPE( cDrive + ":" )
      cLabel := VOLUMENAME( cDrive + ":\" )
      DO CASE
         CASE nType = DRIVE_UNKNOWN
            cBitmap := "
MYUNKNOWN16"

         CASE nType = DRIVE_NO_ROOT_DIR
            cBitmap := "
MYFIXDRIVE16"

         CASE nType = DRIVE_REMOVABLE
            IF cDrive $ "
AB"
               cBitmap := "
MYFLOPPY16"                                // Floppy
            ELSE
               cBitmap := "
MYUSBSTICK16"                              // DRIVE_REMOVABLE
               IF EMPTY( nFirstUSB )
                  nFirstUSB := ii
               ENDIF
            ENDIF

         CASE nType = DRIVE_FIXED
            IF cDrive = "
C"
               cBitmap := "
MYSYSDRIVE16"
            ELSE
               cBitmap := "
MYFIXDRIVE16"
            ENDIF

         CASE nType = DRIVE_REMOTE
            cBitmap := "
MYNETDRIVE16"

         CASE nType = DRIVE_CDROM
            cBitmap := "
MYCDROM16"

         CASE nType = DRIVE_RAMDISK
            cBitmap := "
MYRAMDISK16"

         OTHERWISE
            cBitmap := "
MYUNKNOWN16"
      ENDCASE

      AADD( acItem, cDrive + "
:" + SPACE( 3 ) + cLabel )
      AADD( acBitmaps, cBitmap )
      AADD( acType, nType )
   NEXT

RETURN aDrives

*+ EOF: CBOWNER.PRG

i have try to use Command Syntax but fail :(
can someone please revise my Command Syntax to get same Result like OOP
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 89 guests