anyione help me out with Ownerdraw listbox's?

Everything else that doesn't fall into one of the other PB categories.
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

anyione help me out with Ownerdraw listbox's?

Post by localmotion34 »

i am trying to make an ownerdrawn listbox like the examble in win32.hlp available to the PB community via a PB lib with some subclassing involved. instead of using callback for the MAIN window, i create a borderless window EXACTLY the same size and location of the listviewgadget. then i subclass the borderless window procedure to process the #wm_drawitem ect messages. the subclass proc doesnt mork at all:

Code: Select all

Global OriginProc.l ,lb

#ODS_SELECTED=1 
#ODS_GRAYED=2 
#ODS_DISABLED=4 
#ODS_CHECKED=8 
#ODS_FOCUS=16 
#ODS_DEFAULT= 32 
#ODS_COMBOBOXEDIT= 4096 

#ODT_STATIC  = 5 
#SS_OWNERDRAW=13 
Structure lvwMsgInfo 
  x.l 
  y.l 
  Flgs.l 
  Itm.l 
  SubItm.l 
EndStructure 
Structure PBDrawingStruct 
  Type.l 
  WindowHandle.l 
  DC.l 
  ReleaseProcedure.l 
EndStructure 
mydraw.PBDrawingStruct 
mydraw\Type=1 

Procedure ListboxProc( hwnd, msg,  wParam, lParam)
  Select msg 
    Case #WM_RBUTTONDOWN 
      DisplayPopupMenu(0, WindowID(0)) 
      ProcedureReturn 0 
    Case #WM_DRAWITEM
      *lpdis.DRAWITEMSTRUCT=lParam 
      x=*lpdis\rcItem\left 
      y=*lpdis\rcItem\top 
      w=*lpdis\rcItem\right-*lpdis\rcItem\left 
      h=*lpdis\rcItem\bottom-*lpdis\rcItem\top 
      Select *lpdis\CtlType 
        Case #ODT_LISTBOX 
          Debug 44444444
          Buffer.s=Space(255):SendMessage_(GadgetID(lb),#LB_GETTEXT,*lpdis\itemID,@Buffer):Col=Val(Buffer) 
          ;StartDrawing(WindowOutput()) 
          Select *lpdis\itemAction 
            Case #ODA_SELECT 
              Debug 68888888
              ;StartDrawing(WindowOutput())
              ;Box(x,y,w,h,Col|#Black) 
              ;StopDrawing()
            Case #ODA_FOCUS 
              Debug 5656
             ;DrawingMode(2 | 4):Box(x+1,y+1,w-1,h-1,0):DrawingMode(0) 
              ProcedureReturn #True 
            Case #ODA_DRAWENTIRE 
              hbmpPicture = SendMessage_(*lpdis\hwndItem,#LB_GETITEMDATA, *lpdis\itemID,0)
              hdcMem = CreateCompatibleDC_(*lpdis\hdc)
              hbmpOld = SelectObject_(hdcMem, hbmpPicture) 
              BitBlt_(*lpdis\hdc, *lpdis\rcItem\left, *lpdis\rcItem\top, *lpdis\rcItem\right - *lpdis\rcItem\left,*lpdis\rcItem\bottom - *lpdis\rcItem\top, hdcMem, 0, 0, #SRCCOPY)
              *buffer.s=Space(255)
              SendMessage_(*lpdis\hwndItem, #LB_GETTEXT, *lpdis\itemID, @*buffer)
              *tm.TEXTMETRIC
              GetTextMetrics_(*lpdis\hdc,@*tm)
              y = (*lpdis\rcItem\bottom + *lpdis\rcItem\top -*tm\tmHeight) / 2
              TextOut_(*lpdis\hdc,XBITMAP + 6, y, @*tm,MemoryStringLength(*buffer))
              SelectObject_(hdcMem, hbmpOld); 
              DeleteDC_(hdcMem)
              ProcedureReturn #True 
              EndSelect
          
      EndSelect 
  EndSelect
  ProcedureReturn CallWindowProc_(OriginProc,hwnd,msg,wParam,lParam) 
EndProcedure    

icontouse=CreateImage(10,16,16)
StartDrawing(ImageOutput())
Box(0,0,16,16,#Red)
StopDrawing()

Procedure listbox(parent,number,x,y,width,height)
  window=OpenWindow(#PB_Any,x,y,width,height,#PB_Window_BorderLess|#PB_Window_Invisible,"")
  SetWindowLong_(WindowID(window),#GWL_STYLE, #WS_CHILD|#WS_DLGFRAME|#WS_EX_CLIENTEDGE|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS )
  SetParent_(WindowID(window),parent)
  ShowWindow_(WindowID(window),#SW_SHOW)
  CreateGadgetList(WindowID(window))
  lb=ListViewGadget(#PB_Any,0,0,width,height,#LBS_OWNERDRAWFIXED|#LBS_HASSTRINGS)
  nItem = SendMessage_(GadgetID(lb), #LB_ADDSTRING, 0, "test")
  OriginProc= SetWindowLong_(WindowID(window), #GWL_WNDPROC, @ListboxProc())
  SendMessage_(GadgetID(lb), #LB_SETITEMDATA, nItem, icontouse)
  EndProcedure



UseJPEGImageDecoder()
Dim org.l(100)  
If OpenWindow(0,0,0,322,275,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"StringGadget Flags") And CreateGadgetList(WindowID(0)) 
  CreateGadgetList(WindowID())
  listbox(WindowID(0),0,8,10,100,200)
  If CreatePopupMenu(0) 
    MenuItem(1, "Cut") 
    MenuItem(2, "Copy") 
    MenuItem(3, "Paste") 
    MenuBar() 
    OpenSubMenu("Options") 
    MenuItem(4, "Window...") 
    MenuItem(5, "Gadget...") 
    CloseSubMenu() 
    MenuBar() 
    MenuItem( 6, "Quit") 
  EndIf 
  
  Repeat 
    EventID.l=WaitWindowEvent() 
    Select EventID 
      Case #PB_EventMenu 
        Select EventMenuID() 
          Case 0 
  
          Case 2 
                       
        EndSelect 
        
      Case #WM_CLOSE 
        Quit=1 
        
    EndSelect  
  Until Quit=1 
EndIf  
can anyone help me out?

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Maybe you'll find some help in this.

Code: Select all

hbrushDefault.l = CreateSolidBrush_(RGB(100, 255, 100))
hbrushSelected.l = CreateSolidBrush_(RGB(200, 255, 200))
hbrushSelectedFocus.l = CreateSolidBrush_(RGB(0, 200, 0))

Global hbrushDefault, hbrushSelected, hbrushSelectedFocus

#ODS_SELECTED = 1 
#ODS_GRAYED = 2 
#ODS_DISABLED = 4 
#ODS_CHECKED = 8 
#ODS_FOCUS = $10 
#ODS_DEFAULT = $20 
#ODT_LISTBOX = 2
#ListView = 0
#Button = 1

Procedure myWindowCallback(hWnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg 
    Case #WM_DRAWITEM 
      *lpdis.DRAWITEMSTRUCT=lParam 
      Select *lpdis\CtlType 
        Case #ODT_LISTBOX 
          lbText$ = GetGadgetItemText(#ListView, *lpdis\itemID, 0) 
          Debug "ID: " + Str(*lpdis\itemID) +  "   State: " + Str(*lpdis\itemState)
          Select *lpdis\itemState 
            Case #ODS_SELECTED 
              DisableGadget(#Button, 1)
              dtFlags = #DT_LEFT | #DT_VCENTER
              currentBrush = hbrushSelected
              currentTextColor = RGB(100, 200, 100)
              ; --> Draw a focus rect to remove the default focus rect
              drawFocus = #True
            Case #ODS_SELECTED | #ODS_FOCUS
              DisableGadget(#Button, 0)
              dtFlags = #DT_LEFT | #DT_VCENTER
              currentBrush = hbrushSelectedFocus
              currentTextColor = RGB(0, 0, 0)
            Case 0
              dtFlags = #DT_LEFT | #DT_VCENTER
              currentBrush = hbrushDefault
              currentTextColor = RGB(0, 0, 0)
          EndSelect 
          FillRect_(*lpdis\hDC, *lpdis\rcItem, currentBrush)
          SetBkMode_(*lpdis\hDC, #TRANSPARENT)
          SetTextColor_(*lpdis\hDC, currentTextColor)
          ; --> Move the text over 3 pixels
          *lpdis\rcItem\left + 3
          DrawText_(*lpdis\hDC, lbText$, Len(lbText$), *lpdis\rcItem, dtFlags)
          ; --> Move *lpdis\rcItem\left back to original pos for focus rect
          If drawFocus
            *lpdis\rcItem\left - 3
            DrawFocusRect_(*lpdis\hDC, *lpdis\rcItem)
          EndIf
      EndSelect 
  EndSelect 
  ProcedureReturn result
EndProcedure    

If OpenWindow(0, 0, 0, 270, 170, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Ownerdrawn ListViewGadget") And CreateGadgetList(WindowID(0))
  SetWindowCallback(@myWindowCallback())
  ButtonGadget(#Button, 10, 10, 250, 20, "Click me for focus change")
  ListViewGadget(#ListView, 10, 40, 250, 100, #LBS_OWNERDRAWFIXED)
  For i = 0 To 12
    AddGadgetItem (0, -1, "Item " + Str(i) + " of the Listview")
  Next
  SetGadgetState(0, 9)
  ActivateGadget(#ListView)
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow
  DeleteObject_(hbrushDefault)
  DeleteObject_(hbrushSelected)
  DeleteObject_(hbrushSelectedFocus)
EndIf
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Post Reply