Enter Key moves focus

Just starting out? Need help? Post your questions and find answers here.
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Enter Key moves focus

Post by TerryHough »

I am trying to duplicate the features shown on the image.

Image

The Enter key moves the focus and focused entry field is outlined.

This example was done in PowerBasic code and I would like to
duplicate it using PureBasic. It uses a Windows Callback and I just
don't understand how to convert it.

Anybody care to try it?

Here is the PowerBasic code as an example.

Code: Select all

'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' Small sample of data input form. Textbox in focus is framed.
' Enter-key moves focus to next textbox, and closes dialog if
' Exit button has focus. Just to show some useful API tricks..
' Public Domain by Borje Hagsten, May 2003.
'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' Declares
'--------------------------------------------------------------------
#COMPILE EXE
#INCLUDE "WIN32API.INC"
'--------------------------------------------------------------------
%IDC_LABEL1   = 140
%IDC_TEXT1    = 141
%IDC_LABEL2   = 142
%IDC_TEXT2    = 143
%IDC_LABEL3   = 144
%IDC_TEXT3    = 145
'--------------------------------------------------------------------
DECLARE CALLBACK FUNCTION DlgProc() AS LONG
DECLARE SUB FrameControlInFocus (BYVAL hDlg AS DWORD, BYVAL hWnd AS DWORD, _
                                 BYVAL clr AS DWORD)

'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' Program entrance
'--------------------------------------------------------------------
FUNCTION WINMAIN (BYVAL hInst AS DWORD, BYVAL hPrevInstance AS DWORD, _
                  BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

  LOCAL hDlg AS DWORD

  DIALOG NEW 0, "Data Input",,, 220, 120, _
                %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg

  CONTROL ADD LABEL, hDlg, %IDC_LABEL1, "&Name",  6,  7,  50,  9
  CONTROL ADD TEXTBOX, hDlg, %IDC_TEXT1, "",      5, 17, 100, 13

  CONTROL ADD LABEL, hDlg, %IDC_LABEL2, "&City",  6, 34,  50,  9
  CONTROL ADD TEXTBOX, hDlg, %IDC_TEXT2, "",      5, 44, 100, 13

  CONTROL ADD LABEL, hDlg, %IDC_LABEL3, "&Phone", 6, 61,  50,  9
  CONTROL ADD TEXTBOX, hDlg, %IDC_TEXT3, "",      5, 71, 100, 13

  CONTROL ADD BUTTON, hDlg, %IDCANCEL, "E&xit", 164, 101, 50, 14

  DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION

'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' Main Dialog procedure
'--------------------------------------------------------------------
CALLBACK FUNCTION DlgProc() AS LONG

  SELECT CASE CBMSG
     CASE %WM_INITDIALOG
        STATIC sthText AS DWORD, stCol AS LONG 'to store handle and color for %WM_PAINT

     CASE %WM_PAINT       'must be able to repaint if dialog has
        IF sthText THEN   'been covered/uncovered by something else.
           FrameControlInFocus CBHNDL, sthText, stCol
        END IF

     CASE %WM_COMMAND
        SELECT CASE CBCTL
           CASE %IDC_TEXT1 TO %IDC_TEXT3   'textboxes only
              SELECT CASE CBCTLMSG
                 CASE %EN_SETFOCUS         'a textbox has got focus, draw frame
                    stCol   = RGB(255,0,0) 'store color and handle for eventual %WM_PAINT
                    sthText = CBLPARAM
                    FrameControlInFocus CBHNDL, sthText, stCol

                 CASE %EN_KILLFOCUS        'we are leaving a textbox, so wipe out drawn rect
                    FrameControlInFocus CBHNDL, CBLPARAM, GetSysColor(%COLOR_3DFACE)
                    sthText = 0  'reset handle, we don't need to repeat this under WM_PAINT
               END SELECT

           CASE %IDOK 'Enter key triggers IDOK in dialogs - let's use that fact..
              IF GetDlgCtrlId(GetFocus) = %IDCANCEL THEN 'if exit button
                 DIALOG END CBHNDL, 0 'whatever..
              ELSE 'else textbox - move to next
                 SetFocus GetNextDlgTabItem(CBHNDL, GetFocus, 0)
              END IF

           CASE %IDCANCEL
              IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                 DIALOG END CBHNDL, 0
              END IF
        END SELECT

  END SELECT

END FUNCTION

'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
' Draw a rectangle around any given control
'--------------------------------------------------------------------
SUB FrameControlInFocus (BYVAL hDlg AS DWORD, BYVAL hWnd AS DWORD, _
                         BYVAL clr AS DWORD)
  LOCAL hDC AS DWORD, hBrush AS DWORD, hPen AS DWORD, rc AS RECT

  GetWindowRect hWnd, rc            'get control's pos and size on screen
    MapWindowPoints 0, hDlg, rc, 2  'map rect to dialog
    InflateRect rc, 2, 2            'increase slightly to draw around control

  hDC = GetDc(hDlg)                      'use dialog's DC since we want to paint on dialog
     hPen = CreatePen(%PS_SOLID, 1, clr) 'create a pen for given color
     hPen = SelectObject(hDC, hPen)      'select the new pen into the DC
     hBrush = SelectObject(hDC, GetStockObject(%NULL_BRUSH)) 'use stock null brush for hollow rect

     Rectangle hDC, rc.nLeft, rc.nTop, rc.nRight, rc.nBottom 'draw the rectangle

     SelectObject hDC, hBrush 'return original pen and brush, then release DC
     DeleteObject SelectObject(hDC, hPen)
  ReleaseDc hDlg, hDC

END SUB
TIA
Terry
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1285
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Post by Paul »

You may find this as an interesting way to do it...

Code: Select all

;-Init Includes
#WindowIndex    =0
#GadgetIndex    =0

#Window_Main            = #WindowIndex:#WindowIndex=#WindowIndex+1

#Gadget_Main_Text2      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Text4      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Text6      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Name       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_City       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Phone      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Exit       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1


Procedure.l Window_Main()
  If OpenWindow(#Window_Main,175,0,290,207,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"Data Input")
    If CreateGadgetList(WindowID())
      TextGadget(#Gadget_Main_Text2,10,10,60,15,"Name:")
      StringGadget(#Gadget_Main_Name,10,25,165,20,"")
      TextGadget(#Gadget_Main_Text4,10,60,60,15,"City:")
      StringGadget(#Gadget_Main_City,10,75,165,20,"")
      TextGadget(#Gadget_Main_Text6,10,110,60,15,"Phone:")
      StringGadget(#Gadget_Main_Phone,10,125,165,20,"")
      ButtonGadget(#Gadget_Main_Exit,220,175,60,20,"Exit")
      ProcedureReturn WindowID()
    EndIf
  EndIf
EndProcedure


Procedure FocusMe(id.l)
  RedrawWindow_(WindowID(#Window_Main),0,0,#RDW_UPDATENOW|#RDW_ERASE|#RDW_INVALIDATE)
  StartDrawing(WindowOutput())
    DrawingMode(4)
    Box(GadgetX(id),GadgetY(id),GadgetWidth(id),GadgetHeight(id),RGB(255,0,0))
  StopDrawing()
  ActivateGadget(id)
EndProcedure



;-Main Loop
If Window_Main()
  AddKeyboardShortcut(#Window_Main,#PB_Shortcut_Return,99)
  pos=#Gadget_Main_Name
  FocusMe(pos)

  
  quitMain=0
  Repeat    
    EventID=WaitWindowEvent()
    Select EventID
      Case #PB_Event_CloseWindow
        If EventWindowID()=#Window_Main
          quitMain=1
        EndIf
      
      Case #PB_Event_Menu
        If EventMenuID()=99
          pos+1
          If pos>#Gadget_Main_Exit
            pos=#Gadget_Main_Name
          EndIf
          FocusMe(pos)
        EndIf


      Case #PB_Event_Gadget
        eID=EventGadgetID()
        If eID<>oldid
          oldid=eID
          pos=eID
          FocusMe(pos)
        EndIf
        
        Select eID
          Case #Gadget_Main_Exit
            quitMain=1
        EndSelect

    EndSelect
  Until quitMain
  CloseWindow(#Window_Main)
EndIf
End
:)
Image Image
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Is it me or does the PureBasic code look way more elegant than PowerBasic! :D
--Kale

Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Post by sec »

add this code before EndSelect (in Paul's code)

Code: Select all

      Case #PB_Event_Repaint
        FocusMe(pos)
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Paul wrote:You may find this as an interesting way to do it...
Thanks, Paul! As usual your code is clean, informative, and a good
example. And certainly more understandable than using a callback
(which still confuses me, someone ought to do a good tutorial).

I had to add a couple of changes to your code to duplicate the
functionality.
1) Capture the Tab key to maintain the typical Windows feel.
2) Avoid "boxing" the Exit button
This created an almost identically performing sample and is 3.5Kb
smaller than the equivalent PowerBasic program (no attempt made
to compress either).

Code: Select all

; Allow Enter to respond like Tab and to Outline every entry box
;   This code from the PB forum by Paul responding to query at
;   http://jconserv.net/purebasic/viewtopic.php?t=7584
;   Additional Case #PB_Event_Repaint code added by Sec
;   Additional condition added by TerryHough to exclude Exit button from outline

;-Init Includes
#WindowIndex    =0
#GadgetIndex    =0

#Window_Main            = #WindowIndex:#WindowIndex=#WindowIndex+1

#Gadget_Main_Text2      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Text4      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Text6      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Name       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_City       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Phone      = #GadgetIndex:#GadgetIndex=#GadgetIndex+1
#Gadget_Main_Exit       = #GadgetIndex:#GadgetIndex=#GadgetIndex+1

Procedure.l Window_Main()
  If OpenWindow(#Window_Main,175,0,290,207,#PB_Window_SystemMenu|#PB_Window_WindowCentered,"Data Input")
    If CreateGadgetList(WindowID())
      TextGadget  (#Gadget_Main_Text2, 10, 10, 60,15,"Name:")
      StringGadget(#Gadget_Main_Name , 10, 25,165,20,"")
      TextGadget  (#Gadget_Main_Text4, 10, 60, 60,15,"City:")
      StringGadget(#Gadget_Main_City , 10, 75,165,20,"")
      TextGadget  (#Gadget_Main_Text6, 10,110, 60,15,"Phone:")
      StringGadget(#Gadget_Main_Phone, 10,125,165,20,"")
      ButtonGadget(#Gadget_Main_Exit ,220,175, 60,20,"Exit")
      ProcedureReturn WindowID()
    EndIf
  EndIf
EndProcedure

Procedure FocusMe(id.l)
  RedrawWindow_(WindowID(#Window_Main),0,0,#RDW_UPDATENOW|#RDW_ERASE|#RDW_INVALIDATE)
  If id <> #Gadget_Main_Exit   ; condition added to not box the Exit button
    StartDrawing(WindowOutput())
    DrawingMode(4)
    Box(GadgetX(id),GadgetY(id),GadgetWidth(id),GadgetHeight(id),RGB(255,0,0))
    StopDrawing()
  EndIf   
  ActivateGadget(id)
EndProcedure

;-Main Loop
If Window_Main()
  AddKeyboardShortcut(#Window_Main,#PB_Shortcut_Return,99)
  AddKeyboardShortcut(#Window_Main,#PB_Shortcut_Tab   ,99) ; added to maintain Tab compatibility
  pos=#Gadget_Main_Name
  FocusMe(pos)
  
  quitMain=0
  
  Repeat
    EventID=WaitWindowEvent()
    Select EventID
      Case #PB_Event_CloseWindow
        If EventWindowID()=#Window_Main
          quitMain=1
        EndIf
      
      Case #PB_Event_Menu
        If EventMenuID()=99
          pos+1
          If pos>#Gadget_Main_Exit
            pos=#Gadget_Main_Name
          EndIf
          FocusMe(pos)
        EndIf
        
      Case #PB_Event_Gadget
        eID=EventGadgetID()
        If eID<>oldid
          oldid=eID
          pos=eID
          FocusMe(pos)
        EndIf
      
        Select eID
          Case #Gadget_Main_Exit
          quitMain=1
        EndSelect
      
      Case #PB_Event_Repaint    ; this case added by Sec
        FocusMe(pos)
      
    EndSelect
  Until quitMain
  CloseWindow(#Window_Main)
EndIf
End
There is one small glitch that I didn't figure out. If you run this code
and then upon the progam start immediately leftclick on the Exit button
nothing happens. A second leftclick works as expected. And if you
Enter or Tab to the second string gadget, whether or not you make any
entry, a leftclick works as expected.

?? Some type of event isn't getting processed ??

Thanks for your help, and you too Sec. For those of us who deal
primarily with accountants who hate Windows Tab method, this idea
should be a big help.

Regards,
Terry
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

For those of us who deal
primarily with accountants who hate Windows Tab method, this idea
should be a big help.
Stand behind them with a stun gun and every time they go to hit Enter to change the field shock the hell out of them..

You'd think after 10 years of windows they would have gotten used to it! :-)
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Karbon wrote: Stand behind them with a stun gun and every time they go to hit Enter to change the field shock the hell out of them..
:lol:
Nope... I have that reserved for the "idiots" at Microsoft who decided
that the Tab key should be used to move from input field to input field
when common practice (and keyboard design) had been to use the
"Return" or "Enter" key for 20 years before they ever wrote a program.

:twisted: Maybe I should write a program to send to them that shocks
them every time they use the tab key...

[Vent]
Actually, haven't you ever wondered why that decision was made?
Keyboards don't have a Tab key anywhere near the Numeric Keypad
do they? And the Arrow Keys, PgDn, PgUp, Home, End, etc. were all
put there for good reason. Many Windows based programs don't know
they exist or how to use them.

I frequently see programs that even require "mousing" from field to
field or to scroll a page. Those problems were overcome many years
before Billy stole the mouse idea from Steve who had stolen it from HP a
couple of years before.

Tabbing and "mousing" are unacceptable ideas for most high volume
data entry activities in accounting and other financial related actvities.
[/Vent]

Image And I promise not to buy your Inventory X application unless it can
be controlled properly with the appropriate keys on the keyboard,
preferrably without me ever having to touch the mouse once the
program is launched.

Regards,
Terry
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

The tab key does have a purpose, it is a standard for blind people to navigate in windows. All windows controls respond to tab and space.

(try to open an internet page and navigate with them :) )
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

You won't ever have to touch the mouse once IX is launched in! The screenshots for IX aren't at all up to date - I need to post some new ones! If you're really interested I can always use some more beta testers too (once I get to beta!)..

I feel your pain about the whole tab/enter key thing.. I've done a lot of custom work for companies that got very used to using Enter for what tab is used for these days in Windows apps.. I moved one to a web based solution -- man you should have been there for the switch over. I've never been yelled at so much in my life!!
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Karbon wrote: ... that got very used to using Enter for what tab is used for these days in Windows apps.
:) Yep! and that is my gripe. The Tab key was never intended to be used
for such a purpose. I'm sure everyone knows it actual purpose (not the
Windows one). But we've allowed M$ to push a new use on to us.
Karbon wrote:If you're really interested I can always use some more beta testers too (once I get to beta!)..
I was kidding about buying but deadly serious about the key usage. I
have my own inventory system directed at a vertical market that has
sadly been allowed to languish for a while and I don't spend time in that
market place anymore.

But if you want me to take a critical/suggestion look at it when the time
comes, feel free to ask.
Num3 wrote:The tab key does have a purpose, it is a standard for blind people to navigate in windows. All windows controls respond to tab and space.
Certainly, it does. It was just not intended to become a navigational key.
But, it has and we have to live and deal with it.

Thanks for your reply.

Terry
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

Hey Terry, I'll gladly take you up on that offer pretty soon! Thanks!
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
Post Reply