Page 1 of 1

ComboBox and detecting index change

Posted: Fri Mar 25, 2005 11:32 pm
by TimmyTom
I have a single combobox that i need to detect just a change in index for (ie: the user selects a new entry in the combobox).

I tried with EventType() and #PB_EventType_Change but that doesn't seem to work.

Any ideas?

Tim

Posted: Fri Mar 25, 2005 11:47 pm
by HeX0R

Code: Select all

If OpenWindow(0,0,0,270,140,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"ComboBoxGadget") And CreateGadgetList(WindowID(0))
  ComboBoxGadget(0,10,40,250,100)
  For a=1 To 5
    AddGadgetItem(0,-1,"ComboBox item "+Str(a))
  Next
  SetGadgetState(0,2)
  
  Active_Item.l = GetGadgetState(0)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        Select EventGadgetID()
          Case 0
            If Active_Item <> GetGadgetState(0)
              Active_Item = GetGadgetState(0)
              Debug "Changed"
              ;Do whatever you like...
            EndIf
        EndSelect
    EndSelect
  ForEver
EndIf
End

Posted: Thu Nov 29, 2007 10:01 am
by Blue
Thank you very much, HeX0R.
You may never come around to read this reply, but just the same, I wanted to let you know that your so simple code is just perfect.
I've modified it for PB 4.xx and added a textBox so we can see right away the results of your efforts:

Code: Select all


If 0 = OpenWindow(0,0,0,270,140,"ComboBoxGadget",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    End
EndIf 

;ComboBoxGadget(0,10,10,250,100) ;; before 4.40
ComboBoxGadget(0,10,10,250,22)  ;; for 4.40 and above 
   For a=1 To 5 
      AddGadgetItem(0,-1,"ComboBox item "+Str(a)) 
   Next 
   SetGadgetState(0,2) 

TextGadget(1,10,40,230,20,"99 - selected ComboBox item")

active_Item.l = GetGadgetState(0)
Repeat 
  Select WaitWindowEvent()
 
    Case #PB_Event_CloseWindow : Break 

    Case #PB_Event_Gadget : Select EventGadget() 
           Case 0 
              If active_Item <> GetGadgetState(0) 
                 active_Item = GetGadgetState(0)
                 SetGadgetText(1,Str(active_Item) + ": " + GetGadgetText(0))
                 ; Debug "Changed = " + Str(Active_Item)
                 ; Do whatever you like... 
              EndIf 
           EndSelect
  EndSelect

ForEver 


Posted: Thu Nov 29, 2007 12:00 pm
by gnozal
Other possibility [Windows only (#CBN_SELCHANGE)] :

Code: Select all

Enumeration
  #Window_0
EndEnumeration
Enumeration
  #ComboBox_0
  #Text_1
EndEnumeration
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 265, 112, "#CBN_SELCHANGE", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    If CreateGadgetList(WindowID(#Window_0))
      ComboBoxGadget(#ComboBox_0, 15, 15, 240, 100)
      AddGadgetItem(#ComboBox_0, -1, "Item 1")
      AddGadgetItem(#ComboBox_0, -1, "Item 2")
      AddGadgetItem(#ComboBox_0, -1, "Item 3")
      SetGadgetState(#ComboBox_0, 0)
      TextGadget(#Text_1, 15, 55, 240, 20, "")
      SetGadgetText(#Text_1, GetGadgetText(#ComboBox_0))
    EndIf
  EndIf
EndProcedure
OpenWindow_Window_0()
Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      If EventGadget = #ComboBox_0 And EventType = #CBN_SELCHANGE
        SetGadgetText(#Text_1, GetGadgetText(#ComboBox_0))
      EndIf
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect
ForEver

Posted: Thu Nov 29, 2007 5:37 pm
by DoubleDutch

Code: Select all

Enumeration 
  #Window_0 
EndEnumeration 
Enumeration 
  #ComboBox_0 
  #Text_1 
EndEnumeration 
Procedure OpenWindow_Window_0() 
  If OpenWindow(#Window_0, 450, 200, 265, 112, "#PB_EventType_RightClick", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar) 
    If CreateGadgetList(WindowID(#Window_0)) 
      ComboBoxGadget(#ComboBox_0, 15, 15, 240, 100) 
      AddGadgetItem(#ComboBox_0, -1, "Item 1") 
      AddGadgetItem(#ComboBox_0, -1, "Item 2") 
      AddGadgetItem(#ComboBox_0, -1, "Item 3") 
      SetGadgetState(#ComboBox_0, 0) 
      TextGadget(#Text_1, 15, 55, 240, 20, "") 
      SetGadgetText(#Text_1, GetGadgetText(#ComboBox_0)) 
    EndIf 
  EndIf 
EndProcedure 
OpenWindow_Window_0() 
Repeat 
  Event = WaitWindowEvent() 
  Select Event 
    Case #PB_Event_Gadget 
      EventGadget = EventGadget() 
      EventType = EventType() 
      If EventGadget = #ComboBox_0 And EventType = #PB_EventType_RightClick
        SetGadgetText(#Text_1, GetGadgetText(#ComboBox_0)) 
      EndIf 
    Case #PB_Event_CloseWindow 
      EventWindow = EventWindow() 
      If EventWindow = #Window_0 
        CloseWindow(#Window_0) 
        Break 
      EndIf 
  EndSelect 
ForEver
Try #PB_EventType_RightClick instead, I haven't tried this on Linux/Mac - but it works on windows...

Posted: Thu Nov 29, 2007 7:12 pm
by ABBKlaus
1=1 :lol:

Code: Select all

Debug #CBN_SELCHANGE
Debug #PB_EventType_RightClick

Posted: Thu Nov 29, 2007 8:39 pm
by Foz
Nope, only Blue's solution will work in Linux

Posted: Fri Nov 30, 2007 1:01 am
by Blue
gnozal wrote:Other possibility [Windows only (#CBN_SELCHANGE)] :

Code: Select all

  [...]
      If EventGadget = #ComboBox_0 And EventType = #CBN_SELCHANGE
        SetGadgetText(#Text_1, GetGadgetText(#ComboBox_0))
      EndIf
  [...]
Merci Gnozal...

Your well-structures solution works really well, and is also even simpler (plus lots more elegant!) than HeXOR's,
if the programmer knows (or remembers)...
(a) that the constant #CBN_SELCHANGE exists somewhere in the Windows Universe
(b) the context in which to make proper use of that mysterious constant.

Personally, I prefer code that relies strictly on documented features, functions and constants available in PB's Help file.

That's what I love so much about heXOR's code. It uses a standard feature in a clever way that was not apparent to the PB newbie that I am.

Knowing your demonstrated ability in Windows programming, your solution is probably more in conformity with the good and recommended practices of Windows programming. But it relies, with its use of #CBN_SELCHANGE, on insider knowledge.

A PB newbie like me wouldn't even have known where to begin looking for this constant and what to do with it. Plus, 5 weeks or 5 months from now, it still won't be documented in PB's material ! Whereas GetGadgetState() is a permanent fixture of PB.

---------------------
2 days later:
PS: That being said, I ended up using your solution because it makes for neater code :oops: :oops:

Posted: Mon Feb 18, 2008 10:49 pm
by Andre
I found no answer to my question here in the forum yet.
But this topic is a good start for code examples, and to explain my wanted behaviour:

I would like to know not every index change in the combobox.
Instead I want to know the choosen* combobox item, if its different than before.

* So the "new item - event" should be fired, not already if the user is browsing through the combobox items. Instead the event should be fired, if user finish the browsing by
a) pressing left mouse button (if browsing listed combobox items with mouse)
b) pressing Return key (if browsing the combobox list with the cursor keys)

Hope you understand my problem/wish. :wink:

Any working code example showing this behaviour would be fine.
Code without API is prefered, because it should be cross-plattform (Windows & MacOS).

Many thanks in advance!

Posted: Mon Feb 18, 2008 11:17 pm
by srod
I'm not sure if the following suits your needs? I don't know of a way of achieving what you're after without using API I'm afraid.

Code: Select all

Procedure callback(hWnd, uMsg, wParam, lParam)
  Static selItem
  Result = #PB_ProcessPureBasicEvents

  Select uMsg
    Case #WM_COMMAND
      Select wParam>>16&$ffff
        Case #CBN_DROPDOWN
          If lParam = GadgetID(0)
            selItem = GetGadgetState(0)
          EndIf
      
        Case #CBN_CLOSEUP
          If lParam = GadgetID(0) And SelItem <> GetGadgetState(0)
            Debug "Selected item " + Str(GetGadgetState(0))
          EndIf

        Case #CBN_SELENDOK	
          If lParam = GadgetID(0)
            If SendMessage_(lParam, #CB_GETDROPPEDSTATE, 0, 0) = 0
              selItem = GetGadgetState(0)
              Debug "Selected item " + Str(selItem)
            EndIf
          EndIf

      EndSelect
  EndSelect
  ProcedureReturn Result
EndProcedure

If OpenWindow(0, 0, 0, 270, 140, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  ComboBoxGadget(0, 10, 10, 250, 100)
  For a = 0 To 9 : AddGadgetItem(0, -1,"ComboBox item " + Str(a)) : Next a
  SetWindowCallback(@callback())

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Posted: Mon Feb 25, 2008 8:26 pm
by Andre
srod wrote:I'm not sure if the following suits your needs? I don't know of a way of achieving what you're after without using API I'm afraid.
Thank you very much, srod! :D

After a short text it looks like it works how I wanted it to work. Must include it my main program to have a final test :wink:

The API isn't the problem itself. It's just a problem for cross-compiling then - but the same example adapted to the API of MacOS would solve this problem (using CompilerIf with OS constants) . Does anyone know how to get the same behaviour on MacOS?