версия 5.30
Код:
Enumeration
#cbc
EndEnumeration
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
rect.RECT
Result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_COMMAND
If (wParam>>16)&$FFFF=#CBN_SELCHANGE And lParam=GadgetID(#cbc)
indexClick=SendMessage_(GadgetID(#cbc),#CB_GETCURSEL,0,0)
;Debug indexClick
v.l=1-SendMessage_(GadgetID(#cbc),#CB_GETITEMDATA,indexClick,0)
SendMessage_(GadgetID(#cbc),#CB_SETITEMDATA,indexClick,v)
InvalidateRect_(GadgetID(#cbc),0,1)
EndIf
Case #WM_DRAWITEM
*DrawItem.DRAWITEMSTRUCT = lParam
If *DrawItem\CtlType = #ODT_COMBOBOX
SetBkMode_(*DrawItem\hDC, #TRANSPARENT) ; Text is rendered transparent
If *DrawItem\itemState&#ODS_FOCUS;#ODS_SELECTED
SetTextColor_(*DrawItem\hdc,GetSysColor_(#COLOR_HIGHLIGHTTEXT))
SetBkColor_(*DrawItem\hdc,GetSysColor_(#COLOR_HIGHLIGHT))
Else
SetTextColor_(*DrawItem\hdc,GetSysColor_(#COLOR_WINDOWTEXT))
SetBkColor_(*DrawItem\hdc,GetSysColor_(#COLOR_WINDOW))
EndIf
; Draw selected / unselected back color
ExtTextOut_(*DrawItem\hdc,0,0,#ETO_OPAQUE,*DrawItem\rcItem,0,0,0)
; Draw the checkbox
rect\left=*DrawItem\rcItem\left+1
rect\right=*DrawItem\rcItem\left+14
rect\top=*DrawItem\rcItem\top+1
rect\bottom=*DrawItem\rcItem\top+14
st.l=#DFCS_BUTTONCHECK|#DFCS_FLAT
If *DrawItem\itemData
st|#DFCS_CHECKED
EndIf
If *DrawItem\itemID <> -1
DrawFrameControl_(*DrawItem\hdc,rect,#DFC_BUTTON,st)
Text$ = Space(512)
SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @Text$)
TextOut_ (*DrawItem\hDC, *DrawItem\rcItem\left+17, *DrawItem\rcItem\top+1, Text$, Len(Text$))
EndIf
EndIf
EndSelect
ProcedureReturn Result
EndProcedure
If OpenWindow(0, 0, 0, 270, 180, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(#cbc, 10, 10, 250, 21,#CBS_OWNERDRAWFIXED|#CBS_HASSTRINGS)
For a = 0 To 3
AddGadgetItem(#cbc, -1,"ComboBox item " + Str(a))
Next
SendMessage_(GadgetID(#cbc),#CB_SETITEMDATA,0,1)
SendMessage_(GadgetID(#cbc),#CB_SETITEMDATA,2,1)
SetWindowCallback(@WindowCallback())
SetGadgetState(#cbc,3)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
для ListBox. Недостатки очевидны: галки ставятся при двойном клике на элемент, и процедура определения не совсем корректна
Код:
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
rect.RECT
pp.POINT
Select uMsg
Case #WM_COMMAND
If lParam=GadgetID(0) And wParam>>16=#LBN_DBLCLK
it.l=SendMessage_(GadgetID(0),#LB_GETCURSEL,0,0)
If it<>#LB_ERR
GetWindowRect_(GadgetID(0),rect)
GetCursorPos_(pp)
;If PtInRect_(rect,pp)
If (pp\x>=rect\left) And (pp\x<=rect\right) And (pp\y>=rect\top) And(pp\y<=rect\bottom)
; Get current checkbox value
v.l=1!SendMessage_(GadgetID(0),#LB_GETITEMDATA,it,0)
; Update checkbox value
SendMessage_(GadgetID(0),#LB_SETITEMDATA,it,v)
; Force a repaint of the item
SendMessage_(GadgetID(0),#LB_GETITEMRECT,it,rect)
; Get listbox handle
InvalidateRect_(GadgetID(0),rect,1)
EndIf
EndIf
EndIf
Case #WM_DRAWITEM
*lp.DRAWITEMSTRUCT = lParam
If *lp\itemState & #ODS_SELECTED
SetTextColor_(*lp\hdc,GetSysColor_(#COLOR_HIGHLIGHTTEXT))
SetBkColor_(*lp\hdc,GetSysColor_(#COLOR_HIGHLIGHT))
Else
SetTextColor_(*lp\hdc,GetSysColor_(#COLOR_WINDOWTEXT))
SetBkColor_(*lp\hdc,GetSysColor_(#COLOR_WINDOW))
EndIf
; Draw selected / unselected back color
ExtTextOut_(*lp\hdc,0,0,#ETO_OPAQUE,*lp\rcItem,0,0,0)
; Draw the checkbox
rect\left=*lp\rcItem\left+1
rect\right=*lp\rcItem\left+14
rect\top=*lp\rcItem\top+1
rect\bottom=*lp\rcItem\top+14
ll.l=#DFCS_BUTTONCHECK | #DFCS_FLAT
If *lp\itemData
; Checkbox is checked
ll|#DFCS_CHECKED
EndIf;
DrawFrameControl_(*lp\hdc,rect,#DFC_BUTTON,ll)
; Draw the text
szitem.s=Space(1024)
len.l=SendMessage_(*lp\hwndItem,#LB_GETTEXT,*lp\itemID,szItem)
ll=18+*lp\rcItem\left
TextOut_(*lp\hdc,ll,*lp\rcItem\top,szItem,len)
ProcedureReturn #True
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0,0,0,320,240,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(0,10,10,300,200,#LBS_OWNERDRAWFIXED)
For i=1 To 10 : AddGadgetItem(0,-1,"Gadget Item #" + Str(i)) : Next
; Set the checkbox for first item in the list
SendMessage_(GadgetID(0),#LB_SETITEMDATA,0,1)
SendMessage_(GadgetID(0),#LB_SETITEMDATA,2,1)
SetWindowCallback(@WindowCallback())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend