Focus on Buttons

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
horst
Enthusiast
Enthusiast
Posts: 197
Joined: Wed May 28, 2003 6:57 am
Location: Munich
Contact:

Focus on Buttons

Post by horst »

A button can have the flag #PB_Button_Default to mark it with a dark frame. When the Enter key is pressed, the #PB_EventType_LeftClick EventType() is triggered for this button.

However, when you move the focus by TAB key, the default button remains, and the Enter key will NOT work on the button that actually has the focus.

When you look at some other Windows programs (for example the StartMenu/RUN box) the default button marker (not only the focus marker) moves around with the TAB key, so that ENTER always works for the button that has the focus. If anything other than a button has the focus, the initially defined default button will have the dark frame again.

Since many users expect this behaviour, it would be nice if PureBasic supported this.
Horst.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Focus on Buttons

Post by PB »

Fred is aware of this (I e-mailed him about it a few months back).
I'm currently using this workaround (a bit messy, but does the job):

Code: Select all

If OpenWindow(1,300,250,400,200,#PB_Window_SystemMenu,"Buttons")
  CreateGadgetList(WindowID())
  ButtonGadget(1,50,50,60,25,"Button1",#PB_Button_Default)
  ButtonGadget(2,150,50,60,25,"Button2")
  ButtonGadget(3,250,50,60,25,"Button3")
  StringGadget(4,50,100,260,21,"test")
  ActivateGadget(1)
  Repeat
    ev=WaitWindowEvent()
    newbut=GetFocus_()
    If newbut<>oldbut
      SendMessage_(oldbut,#BM_SETSTYLE,0,0) : oldbut=newbut
      SendMessage_(newbut,#BM_SETSTYLE,#BS_DEFPUSHBUTTON,#TRUE)
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
horst
Enthusiast
Enthusiast
Posts: 197
Joined: Wed May 28, 2003 6:57 am
Location: Munich
Contact:

Re: Focus on Buttons

Post by horst »

Yes, #BM_SETSTYLE does the job. I made an array of the buttons which is handled by a generic procedure, but it will get a lot more complicated if I have several Windows.

Another thing that would be useful: I had to make my own TAB handling to include a date input gadget. I suggest something like AddTab(GadgetHandle) to insert a non-PB gadget into the TAB chain.
Horst.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Focus on Buttons

Post by PB »

> Another thing that would be useful: I had to make my own TAB handling to
> include a date input gadget. I suggest something like AddTab(GadgetHandle)
> to insert a non-PB gadget into the TAB chain

You can give any gadget a TabStop property with a simple API call:

Code: Select all

; ------- Calendar Setup ------
#MCM_GETCURSEL=$1001
Structure INITCOMMONCONTROLSEX 
  dwSize.l
  dwICC.l
EndStructure
MyCal.INITCOMMONCONTROLSEX
MyCal\dwSize=8
MyCal\dwICC=$100
InitCommonControlsEx_(@MyCal)
; -----------------------------
OpenWindow(0,100,200,400,200,#PB_Window_SystemMenu,"test")
CreateGadgetList(WindowID())
ButtonGadget(1,10,10,50,21,"button1")
ButtonGadget(2,10,40,50,21,"button2")
datepick=CreateWindowEx_(0,"SysDateTimePick32","DateTime",#WS_CHILD|#WS_VISIBLE|4,10,70,200,22,WindowID(),0,GetModuleHandle_(0),0)
SetWindowLong_(datepick,#GWL_STYLE,GetWindowLong_(datepick,#GWL_STYLE)|#WS_TABSTOP) ; Thanks, PolyVector!
ActivateGadget(1)
Repeat : Until WaitWindowEvent()=#PB_EventCloseWindow
And here's a version using a procedure that allows enable/disable on the fly:

Code: Select all

; ------- Calendar Setup ------
#MCM_GETCURSEL=$1001
Structure INITCOMMONCONTROLSEX
  dwSize.l
  dwICC.l
EndStructure
MyCal.INITCOMMONCONTROLSEX
MyCal\dwSize=8
MyCal\dwICC=$100
InitCommonControlsEx_(@MyCal)
; -----------------------------
; This proc inspired by PolyVector.
Procedure TabStop(hWnd,status)
  If status=#TRUE
    SetWindowLong_(hWnd,#GWL_STYLE,GetWindowLong_(hWnd,#GWL_STYLE)|#WS_TABSTOP)
  Else
    SetWindowLong_(hWnd,#GWL_STYLE,GetWindowLong_(hWnd,#GWL_STYLE)!#WS_TABSTOP)
  EndIf
EndProcedure
OpenWindow(0,100,200,400,200,#PB_Window_SystemMenu,"test")
CreateGadgetList(WindowID())
ButtonGadget(1,10,10,50,21,"button1")
ButtonGadget(2,10,40,50,21,"button2")
datepick=CreateWindowEx_(0,"SysDateTimePick32","DateTime",#WS_CHILD|#WS_VISIBLE|4,10,70,200,22,WindowID(),0,GetModuleHandle_(0),0)
TabStop(GadgetID(2),#FALSE) : TabStop(datepick,#TRUE) ; Experiment with these.  :)
ActivateGadget(1)
Repeat : Until WaitWindowEvent()=#PB_EventCloseWindow
Last edited by PB on Fri Sep 24, 2004 11:39 pm, edited 3 times in total.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
horst
Enthusiast
Enthusiast
Posts: 197
Joined: Wed May 28, 2003 6:57 am
Location: Munich
Contact:

Re: Focus on Buttons

Post by horst »

> You can give any gadget a TabStop property with a simple API call ..

Wow, thanks!
I had thought that this was handled by PureBasic.
Guess I have to find out more about SetWindowLong_()
Horst.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Focus on Buttons

Post by PB »

> Guess I have to find out more about SetWindowLong_()

Credit: This TabStop tip was originally posted by PolyVector, as seen here:

viewtopic.php?t=12388

(I did a search for "tabstop" and didn't find PV's tip, which is why I couldn't
originally credit him in my above post. But a search now for "ws_tabstop"
revealed his post, which led me to find his tip and thus give credit).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply