версия 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