Adding some refinements to the ADDRESSBOOK.

..adding a flag to allow edits.
..adding a flag for the save function, along with a message-box, to save both edits and additions on exit.

At the present time, we can change any field in a database item, and add that item to the database, giving us a modified copy of the original, as well as the original. Wouldn't it be nice to have the original deleted automatically?

To do this we can simply add a flag to our NEW menu-item function, which would tell us if we have a new item. We can then check this flag in the SAVE function to determine if it is just an edit, and not actually a new item.
Adding a function to delete the old item from the list-box before adding the new one would complete this feature.

Since our database only changes if we add or delete an item, we can set a flag whenever we do this, and check this flag on exit, to ask the user if the changes should be saved.

-- address5.exw

-- a simple addressbook example, part five. ( shows additions only )

-- first add two new variables and initialize them.
object line, line2, entry
integer isnew, haschanged
isnew=0  haschanged=0

----

-- isnew will be set here to indicate this is NOT simply an edit.
procedure onClick_btnNew( integer self, integer event, sequence params )
  setFocus(Sle1)
  clear_all()
  isnew=1  -- set since we have new item
end procedure

----

procedure onClick_btnAdd( integer self, integer event, sequence params )
  integer junk
  haschanged=1 -- our database has changed.
  junk=getIndex(List1)
  if isnew=0 then  -- is this an edit only?
     -- this deletes an old item so the newly edited item can be added.
     junk = deleteItem(List1, junk)
  end if 
  isnew=0  -- reset the 'isnew' flag IF it was set.
  entry = getText(Sle1) & ", " & getText(Sle2) & ", " & getText(Sle3)

----

procedure onClick_btnSave( integer self, integer event, sequence params )
  -- save our database to a file.
  haschanged=0 -- if we save a new entry, or an edited item.
  listlen = getCount(List1)           -- first, how many lines are in it ?

----

procedure onClick_btnDel( integer self, integer event, sequence params )
  -- modified delete routine originally by Rev. Ferlin Scarborough
  integer junk
   haschanged=1 -- our database has changed.
   itemnum = getIndex(List1)

----

procedure onMenu_Exit( integer self, integer event, sequence params )
  integer junk
  if haschanged=1 then
     junk = message_box("You have made changes.\n" &
                        "Would you like to save them?",
                         "Confirm Saving CHANGES!",
                         MB_ICONQUESTION + MB_YESNO + MB_TASKMODAL)
     if junk = IDYES then
        onClick_btnSave( self, event, params )
     end if
   end if
   closeWindow(MyWin)
end procedure

----

..finally, adding the following four procedures will allow us to use the ENTER key to 'activate' the four buttons, as well as the default SPACE key.

----
procedure onKey_btnNew( integer self, integer event, sequence params )
   integer key  key = params[1]
   if key=13 then onClick_btnNew( self, event, params ) else end if
end procedure
setHandler( btnNew, w32HKeyDown, routine_id("onKey_btnNew") )

----
procedure onKey_btnAdd( integer self, integer event, sequence params )
   integer key  key = params[1]
   if key=13 then onClick_btnAdd( self, event, params ) else end if
end procedure
setHandler( btnAdd, w32HKeyDown, routine_id("onKey_btnAdd") )

----
procedure onKey_btnSave( integer self, integer event, sequence params )
   integer key  key = params[1]
   if key=13 then onClick_btnSave( self, event, params ) else end if
end procedure
setHandler( btnSave, w32HKeyDown, routine_id("onKey_btnSave") )

----
procedure onKey_btnDel(integer key, integer shift)
   integer key  key = params[1]
   if key=13 then onClick_btnDel( self, event, params ) else end if
end procedure
setHandler( btnDel, w32HKeyDown, routine_id("onKey_btnDel") )

----

I've also included a slightly different version of address5.exw, called address6.exw, which also has a few new features and a 'new' look ;-) You'll have to select this program manually in the OPEN dialog window to run it !

You'll have to search for any new code changes in the source of address6.exw yourself, but I hope you like the new 'look' .

There are however, two new features worth mentioning. By adding a whole new group of onKeyPress[] event handlers to the program, one can now enter a series of new entries using nothing but the ENTER key !

This is done by adding:

-- 'speedy' entry section
procedure onKey_Sle1( integer self, integer event, sequence params )
 integer key   key = params[1]
 if key=13 then setFocus(Sle2) else end if
end procedure
setHandler( Sle1, w32HKeyDown, routine_id("onKey_Sle1") )

procedure onKey_Sle2( integer self, integer event, sequence params )
 integer key   key = params[1]
 if key=13 then setFocus(Sle3) else end if
end procedure
setHandler( Sle2, w32HKeyDown, routine_id("onKey_Sle2") )

procedure onKey_Sle3( integer self, integer event, sequence params )
 integer key   key = params[1]
 if key=13 then setFocus(Sle4) else end if
end procedure
setHandler( Sle3, w32HKeyDown, routine_id("onKey_Sle3") )

-- ** and so on to:

procedure onKey_Sle8( integer self, integer event, sequence params )
  integer key   key = params[1]
  if key=13 then setFocus(btnAdd) else end if
end procedure
setHandler( Sle8, w32HKeyDown, routine_id("onKey_Sle8") )

-- ** with a little change to:

procedure onKey_btnAdd( integer self, integer event, sequence params )
    integer key  key = params[1]
   if key=13 then
       onClick_btnAdd( self, event params )
       setFocus(btnNew) -- added this line
    else end if
end procedure
setHandler( btnAdd, w32HKeyDown, routine_id("onKey_btnAdd") )

--

I have also added an onDestroy[] event handler to the program so that if you made any changes to the database, and try to [X] out of the program, it will STILL ask you if you want to save those changes.

procedure onDestroy_MyWin( integer self, integer event, sequence params )
  if haschanged = 1 then
     junk = message_box("You have made changes.\n" &
                             "Would you like to save them?",
                             "ADDRESSBOOK6 data CHANGED !",
                              MB_ICONWARNING + MB_YESNO + MB_TASKMODAL)
     if junk = IDYES then
          onClick_btnSave( self, event, params )
     end if
  end if
end procedure
setHandler( MyWin, w32HDestroy, routine_id("onDestroy_MyWin") )

This, of course, required adding one line to onMenu_Exit() so we don't run this procedure if we exit the program normally.

  end if
  haschanged=0
  closeWindow(MyWin)
end procedure

One final note:
In the actual program example, I have removed the reference to
integer junk in three procedures, declaring it at the top of the program only once, and re-used it in onChange_List1(), getting rid of the integer what declaration.

..and thanks to Mike Fowler, here are some 'secret' codes for the last
parameter in sle's.

-- Mikes WIN32LIB additions

   ( ...now included in win32lib.ew as global constants )

    ES_LOWERCASE    = 16     -- convert text to lowercase
    ES_UPPERCASE    = 8      -- convert text to uppercase
    ES_NOHISESEL    = 256    -- show selection, even when not active
    ES_NUMBER       = #2000  -- only allow numbers
    ES_OEMCONVERT   = #400   -- something... ;)
    ES_PASSWORD     = 32     -- displays * instead of chars
    ES_READONLY     = #800   -- user can't type into here...
    ES_WANTRETURN   = 4096   -- adds a \n to the returned text

So, if you wanted the ZIP code entry sle to be filled with only upper-case
characters, for example, you would code:

  Sle7    = create(EditText, "", MyWin, 80, 240, 80, 20, 8 )
-- or just:
  Sle7    = create(EditText, "", MyWin, 80, 240, 80, 20, ES_UPPERCASE )

..end of lesson.

CONTENTS