Page 1 of 1
Enter key in Listview
Posted: Tue Nov 27, 2007 6:18 pm
by WoodLark
I am just getting started with PureBasic and have written a small windows program. After correcting some errors, the program compiles and runs fine with one small "niggle".
I am using a ListviewGadget and two ButtonGadgets. I can use the mouse or keyboard to move up and down the list and can use the mouse to activate the buttons. Using the TAB key, I can set focus to either of the buttons. I would like to be able to press the ENTER key when one of the buttons has focus and have it activate that button, but that does not work.
This is probably a dumb question, but is there some flag or setting that I am missing?
Posted: Tue Nov 27, 2007 6:42 pm
by netmaestro
Code: Select all
OpenWindow(0,0,0,320,240,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ListViewGadget(0,0,0,320,200)
ButtonGadget(1,0,210,160,20,"Button 1")
ButtonGadget(2,161,210,160,20,"Button 2")
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #WM_KEYDOWN
If EventwParam() = #VK_RETURN
If IsGadget(GetActiveGadget())
If GadgetType(GetActiveGadget()) = #PB_GadgetType_Button
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONDOWN, 0,0)
Delay(200)
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONUP, 0,0)
EndIf
EndIf
EndIf
Case #PB_Event_Gadget
Debug EventGadget()
EndSelect
Until EventID = #PB_Event_CloseWindow
You can send a #BM_CLICK message instead of the down-wait-up, but it won't provide the visual feedback you get with this version.
Posted: Tue Nov 27, 2007 6:47 pm
by milan1612
@netmaestro: Your code crashes if no button is active, but I don't see any error

Posted: Tue Nov 27, 2007 6:50 pm
by netmaestro
Oh thanks I forgot a line, should be ok now.
Posted: Tue Nov 27, 2007 8:25 pm
by WoodLark
@netmaestro: Thanks, your code worked great, but it left me with another issue .Here is my code:
Code: Select all
window_nr = OpenWindow(#PB_Any,0,0,250,180,"Calendar Year",#PB_Window_ScreenCentered)
If window_nr > 0
window_id = WindowID(window_nr)
CreateGadgetList(window_id)
ListViewGadget(0,10,10,250,120)
ButtonGadget(1,10,140,40,20,"Year")
ButtonGadget(2,200,140,40,20,"Quit")
defaultItem.l = FillListView(0,"G:BCAS.ini")
SetGadgetState(0,defaultItem)
SetActiveGadget(0)
Repeat
event = WaitWindowEvent()
Select event
Case #WM_KEYDOWN
If EventwParam() = #VK_RETURN
activeGadgetID = (GetActiveGadget())
If IsGadget(activeGadgetID)
If GadgetType(GetActiveGadget()) = #PB_GadgetType_Button
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONDOWN, 0,0)
Delay(200)
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONUP, 0,0)
EndIf
EndIf
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case 1 ;the "Year" button
dbToOpen.s = "G:" + GetGadgetText(0) + "_AnimalServices.mdb"
db = RunProgram(dbToOpen,"","",#PB_Program_Wait)
Case 2 ;the "Quit" button
End
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
Else
MessageRequester("Information","Unable to open the window!")
EndIf
End
After returning from the external program none of my gadgets has focus. I thought inserting the line:
just aove the Case 2 statement would solve it, but it does nothing. If I press the TAB key once, then the ListView has focus and everything works normally again. Any ideas?
Posted: Tue Nov 27, 2007 11:23 pm
by Baldrick
Here is another simple way of doing this Woodlark.
Probably a bit more native PB than Netmaestro's snippet but wont give you the visual feedback on the buttons being pressed, which I generally don't really care too much about anyways.
Code: Select all
Procedure Btn1press()
Debug "button 1"
SetActiveGadget(0)
EndProcedure
Procedure Btn2press()
Debug "button 2"
SetActiveGadget(0)
EndProcedure
OpenWindow(0,0,0,320,240,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateMenu(0,WindowID(0))
AddKeyboardShortcut(0,#PB_Shortcut_Return,1) ;< keyboard shortcut
CreateGadgetList(WindowID(0))
ListViewGadget(0,0,0,320,200)
ButtonGadget(1,0,210,160,20,"Button 1")
ButtonGadget(2,161,210,160,20,"Button 2")
Repeat
Event.l=WaitWindowEvent()
If event=#PB_Event_Menu
Select EventMenu() ; < for keyboard shortcut
Case 1
Select GetActiveGadget()
Case 1
Btn1press()
Case 2
Btn2press()
EndSelect
EndSelect
EndIf
If Event=#PB_Event_Gadget
Select EventGadget()
Case 1
Btn1press()
Case 2
Btn2press()
EndSelect
EndIf
Until Event=#PB_Event_CloseWindow
Posted: Tue Nov 27, 2007 11:26 pm
by netmaestro
I've come across this issue in the past, there are difficulties associated with using #PB_Program_Wait when you have a window open that needs to be processing messages. The thing is, while it's waiting for the ran program (-runned?) to finish, the message loop is suspended. You can see firsthand the effect of this if you move the window around while it's waiting. Repaints don't happen. What I've done in previous programs is set a timer for 200 ms from now and do the focus in response to the timer:
Code: Select all
window_nr = OpenWindow(#PB_Any,0,0,250,180,"Calendar Year",#PB_Window_ScreenCentered)
If window_nr > 0
window_id = WindowID(window_nr)
CreateGadgetList(window_id)
ListViewGadget(0,10,10,250,120)
ButtonGadget(1,10,140,40,20,"Year")
ButtonGadget(2,200,140,40,20,"Quit")
defaultItem.l = FillListView(0,"G:BCAS.ini")
SetGadgetState(0,defaultItem)
SetActiveGadget(0)
Repeat
event = WaitWindowEvent()
Select event
Case #WM_KEYDOWN
If EventwParam() = #VK_RETURN
activeGadgetID = (GetActiveGadget())
If IsGadget(activeGadgetID)
If GadgetType(GetActiveGadget()) = #PB_GadgetType_Button
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONDOWN, 0,0)
Delay(200)
SendMessage_(GadgetID(GetActiveGadget()), #WM_LBUTTONUP, 0,0)
EndIf
EndIf
EndIf
Case #WM_TIMER
SetActiveGadget(0)
KillTimer_(WindowID(window_nr), 1)
Case #PB_Event_Gadget
Select EventGadget()
Case 1 ;the "Year" button
dbToOpen.s = "G:" + GetGadgetText(0) + "_AnimalServices.mdb"
db = RunProgram(dbToOpen,"","",#PB_Program_Wait)
SetTimer_(WindowID(window_nr),1,200,#Null)
Case 2 ;the "Quit" button
End
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
Else
MessageRequester("Information","Unable to open the window!")
EndIf
End
Posted: Wed Nov 28, 2007 2:22 am
by WoodLark
Thanks for the help everybody!
netmaestro: The SetTimer solution was just what I needed.
