Page 1 of 1

Comboboxex help...

Posted: Wed Jan 18, 2006 7:12 pm
by DoubleDutch
I've modified an example from the forum of comboboxex...

Code: Select all

;--> ComboBoxEx Constants 
#CBEIF_DI_SETITEM = $10000000 
#CBEIF_IMAGE = 2 
#CBEIF_INDENT = $10 
#CBEIF_LPARAM = $20 
#CBEIF_OVERLAY = 8 
#CBEIF_SELECTEDIMAGE = 4 
#CBEIF_TEXT = 1 
#CBEM_INSERTITEMA = #WM_USER + 1 
#CBEM_SETIMAGELIST = #WM_USER + 2 
;--> ComboBoxEx Structure for adding items 
cbi.COMBOBOXEXITEM 
cbi\mask = #CBEIF_TEXT | #CBEIF_IMAGE | #CBEIF_SELECTEDIMAGE 
;--> Create our 4 images 
sizex=96
sizey=128
Dim images(3) 
images(0) = CreateImage(0, sizex, sizey) 
StartDrawing(ImageOutput()) 
Box(0, 0, sizex, sizey, RGB(255, 0, 0)) 
StopDrawing() 
images(1) = CreateImage(1, sizex, sizey) 
StartDrawing(ImageOutput()) 
Box(0, 0, sizex, sizey, RGB(0, 255, 0)) 
StopDrawing() 
images(2) = CreateImage(2, sizex, sizey) 
StartDrawing(ImageOutput()) 
Box(0, 0, sizex, sizey, RGB(0, 0, 255)) 
StopDrawing() 
images(3) = CreateImage(3, sizex, sizey) 
StartDrawing(ImageOutput()) 
Box(0, 0, sizex, sizey, RGB(255, 255, 0)) 
StopDrawing() 
If OpenWindow(0, 0, 0, 390, 350, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "ComboBoxEx") And CreateGadgetList(WindowID(0)) 
  ;--> Create ComboBoxEx 
  hCombo = CreateWindowEx_(0, "ComboBoxEx32", "", #WS_BORDER | #WS_CHILD | #WS_VISIBLE | #CBS_DROPDOWN, 10, 10, 180, 300, WindowID(), 0, GetModuleHandle_(0), 0) 
  ;--> Create ImageList and add our 4 images 
  hComboIl= ImageList_Create_(sizex, sizey, #ILC_COLOR24, 0, 50) 
  For i = 0 To 3 
    ImageList_Add_(hComboIl, images(i), 0) 
    FreeImage(i) 
  Next i 
  ;--> Send ImageList to ComboBoxEx 
  SendMessage_(hCombo, #CBEM_SETIMAGELIST, 0, hComboIl) 
  ;--> Add our items to ComboBoxEx 
  For i = 0 To 3 
    cbi\iItem = -1 
    itemText$ = "" 
    ;cbi\pszText = @itemText$ 
    ;cbi\cchTextMax = Len(itemText$) 
    cbi\iImage = i 
    cbi\iSelectedImage = i 
    SendMessage_(hCombo, #CBEM_INSERTITEMA, 0, @cbi) 
  Next i 
  quit = #False 
  Repeat 
    event = WaitWindowEvent() 
    If event = #PB_Event_CloseWindow 
      ImageList_Destroy_(hComboIl) 
      quit = #True 
    EndIf 
  Until quit = #True 
EndIf 
The problem is how do I make it so the text field is NOT there, or at the very least is not editable?

Any ideas?

Posted: Wed Jan 18, 2006 7:30 pm
by Sparkie
Try replacing line 36 with this. The sizey-10 is optional as it only serves to cover up the excess whitespace where the text would normally appear. I also added the #CBS_SIMPLE flag. ;)

Code: Select all

hCombo = CreateWindowEx_(0, "ComboBoxEx32", "", #WS_BORDER | #WS_CHILD | #WS_VISIBLE | #CBS_DROPDOWN | #CBS_SIMPLE , 10, 10, sizey-10, 300, WindowID(), 0, GetModuleHandle_(0), 0) 

Posted: Wed Jan 18, 2006 7:57 pm
by DoubleDutch
That appear to fix it :)

While you here, any quick idea on how to change the selected version of the images? :?: :D

Posted: Wed Jan 18, 2006 8:21 pm
by Sparkie
I'll look into that when I get home tonight. :)

Posted: Thu Jan 19, 2006 1:00 am
by DoubleDutch
I hacked this together, its a different way of doing things:

Code: Select all

#DI_NORMAL = $0003 

Procedure WindowCallback(WindowID, Message, wParam, lParam) 
  Result = #PB_ProcessPureBasicEvents 
  Select Message 
    Case #WM_DRAWITEM 
      *DrawItem.DRAWITEMSTRUCT = lParam 
      If *DrawItem\CtlType = #ODT_COMBOBOX 
        SetBkMode_(*DrawItem\hDC, #TRANSPARENT) ; Text is rendered transparent 
        If *DrawItem\ItemState & #ODS_FOCUS 
          Brush = CreateSolidBrush_($FFEEFF) 
          FillRect_(*DrawItem\hDC, *DrawItem\rcItem, Brush) 
          DeleteObject_(Brush) 
          SetTextColor_(*DrawItem\hDC, $FF) 
        Else 
          FillRect_(*DrawItem\hDC, *DrawItem\rcItem, GetStockObject_(#WHITE_BRUSH)) 
        EndIf 
        If *DrawItem\itemID <> -1 
          Text$ = Space(512) 
          SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @Text$) 
          DrawIconEx_(*DrawItem\hDC, *DrawItem\rcItem\left+2   , *DrawItem\rcItem\top+1, LoadIcon_(0, #IDI_ASTERISK), 32, 32, 0, 0, #DI_NORMAL) 
          TextOut_   (*DrawItem\hDC, *DrawItem\rcItem\left+2+20, *DrawItem\rcItem\top+1, Text$, Len(Text$)) 
        EndIf 
      EndIf 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

If OpenWindow(0, 0, 0, 400, 100, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar , "window") 
	If CreateGadgetList(WindowID()) 
		x=ComboBoxGadget(0, 60, 40, 330, 200,  #CBS_OWNERDRAWFIXED) 
		SendMessage_(x,#CB_SETITEMHEIGHT,-1,40)
	EndIf 
EndIf 
SetWindowCallback(@WindowCallback()) 

  AddGadgetItem(0, 0, "Test1") 
  AddGadgetItem(0, 1, "Test2") 
  AddGadgetItem(0, 2, "Test3") 
  SendMessage_(x,#CB_SETITEMHEIGHT,0,40)
  SendMessage_(x,#CB_SETITEMHEIGHT,1,40)
  SendMessage_(x,#CB_SETITEMHEIGHT,2,40)
Repeat 
Until WaitWindowEvent() = #PB_EventCloseWindow 

End 

Posted: Thu Jan 19, 2006 3:10 am
by Sparkie
Nicely done DoubleDutch :)

Posted: Thu Jan 19, 2006 11:09 am
by DoubleDutch
It gets much better in the app i'm writing (once you stop bothering to draw the text)...

I use the text field now to tell me what image number to draw from a list.

If you use the #WM_MEASUREITEM message and change #CBS_OWNERDRAWFIXED to variable you can use variable sized images (pretty wierd).

If you use "*DrawItem\ItemState & #ODS_COMBOBOXEDIT" you can custom draw the main selected window - I use this to make the image look nice on the main window (normally it looks selected, when unselected looks much better).

You can use CtlId to find out what gadget to draw (so you can different custom comboboxes) , the number refers to the actual PB gadget number. eg "*DrawItem\CtlId=#OptionsPrintTableF"

I've made too many changes to my app to make a quick demo, but its all pretty easy stuff from the previous example.

-Anthony

Posted: Tue May 30, 2006 5:17 pm
by DoubleDutch
Does anyone else have this crash at the end of the callback when you exit the program on V4? It works fine on V3...

Code: Select all

#DI_NORMAL = $0003 

Procedure WindowCallback(WindowID, Message, wParam, lParam) 
  Result = #PB_ProcessPureBasicEvents 
  Select Message 
    Case #WM_DRAWITEM 
      *DrawItem.DRAWITEMSTRUCT = lParam 
      If *DrawItem\CtlType = #ODT_COMBOBOX 
        SetBkMode_(*DrawItem\hDC, #TRANSPARENT) ; Text is rendered transparent 
        If *DrawItem\ItemState & #ODS_FOCUS 
          Brush = CreateSolidBrush_($FFEEFF) 
          FillRect_(*DrawItem\hDC, *DrawItem\rcItem, Brush) 
          DeleteObject_(Brush) 
          SetTextColor_(*DrawItem\hDC, $FF) 
        Else 
          FillRect_(*DrawItem\hDC, *DrawItem\rcItem, GetStockObject_(#WHITE_BRUSH)) 
        EndIf 
        If *DrawItem\itemID <> -1 
          Text$ = Space(512) 
          SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @Text$) 
          DrawIconEx_(*DrawItem\hDC, *DrawItem\rcItem\left+2   , *DrawItem\rcItem\top+1, LoadIcon_(0, #IDI_ASTERISK), 32, 32, 0, 0, #DI_NORMAL) 
          TextOut_   (*DrawItem\hDC, *DrawItem\rcItem\left+2+20, *DrawItem\rcItem\top+1, Text$, Len(Text$)) 
        EndIf 
      EndIf 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

If OpenWindow(0, 0, 0, 400, 100 , "window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar) 
   If CreateGadgetList(WindowID(0)) 
      x=ComboBoxGadget(0, 60, 40, 330, 200,  #CBS_OWNERDRAWFIXED) 
      SendMessage_(x,#CB_SETITEMHEIGHT,-1,40) 
   EndIf 
EndIf 
SetWindowCallback(@WindowCallback()) 

  AddGadgetItem(0, 0, "Test1") 
  AddGadgetItem(0, 1, "Test2") 
  AddGadgetItem(0, 2, "Test3") 
  SendMessage_(x,#CB_SETITEMHEIGHT,0,40) 
  SendMessage_(x,#CB_SETITEMHEIGHT,1,40) 
  SendMessage_(x,#CB_SETITEMHEIGHT,2,40) 
Repeat 
Until WaitWindowEvent() = #PB_Event_CloseWindow 

End 

Is it a V4 bug or something I'm doing wrong that just "turns up" on V4?

-Anthony

Posted: Tue May 30, 2006 5:50 pm
by rsts
Yep. Crashes here too.

Only variable shown in debugger is x which has a value in to 700,000's.

cheers

Posted: Tue May 30, 2006 5:59 pm
by srod
Confirmed, finishes with an invalid memory access report.

Crap, I'm going to be needing owner-drawn combo's pretty soon.

Posted: Tue May 30, 2006 6:07 pm
by netmaestro
It's the #CBS_OWNERDRAWFIXED flag that's causing the trouble, it's possible that it isn't supported anymore in a PB ComboBox gadget. Not sure on that. But what you might have to do is switch to CreateWindowEx_() with the combobox class and go "all API" for that control.

Posted: Tue May 30, 2006 6:09 pm
by srod
Yes, but it worked okay in PB 3.93!

DoubleDutch, perhaps a bug report is warranted?

Posted: Tue May 30, 2006 6:38 pm
by DoubleDutch
Thanks everyone for testing it, I've just posted it in bugs.

Posted: Tue May 30, 2006 7:59 pm
by Trond
DoubleDutch wrote:Thanks everyone for testing it, I've just posted it in bugs.
I already did it: http://www.purebasic.fr/english/viewtop ... 524#147524

Posted: Tue May 30, 2006 8:08 pm
by DoubleDutch
I just noticed... See my last post. :)

http://www.purebasic.fr/english/viewtopic.php?t=22064