Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- The Guide to Clip-4-Win version 3.0 - Norton Guide http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]

  The next example shows data entry.  The application is
  designed to allow records in the USERS.DBF file to be edited.
  It was designed, as with most Windows applications, by
  deciding what the user interface should be: the menus were
  chosen, and the approximate layout of the input screens
  (forms) was decided.  The program code came last.
  
  Note that this example is deliberately simple so that the
  important issues can be seen easily.  In particular, it only
  edits records, although adding/deleting them is equally easy.
  The example does show stepping through the file whilst viewing
  the form, to demonstrate how to update the display as the
  record changes.
  
  This is the menu, after several extra frills were added (see
  SOURCE\USERSRES\USERSCMD.PRG):
  
       static function MenuSetup()
       local     hWnd := SelectWindow(), hMenu
  
       //----- Ampersand (&) indicates the trigger letter (accelerator key).
       //----- You don't need to use ID <x>, unless you later want to refer
       //      to the menu item, e.g. to enable/disable/gray/check/uncheck it.
  
       MENU hMenu IN hWnd
           POPUP "&File"  // ID "file"
               MENUITEM "&Open..."     ACTION DoOpen()    // ID "f_open"
               MENUITEM SEPARATOR
               MENUITEM "E&xit"        ACTION DoExit()    // ID "f_exit"
           ENDPOPUP
           POPUP "&View"  // ID "view"
               MENUITEM "&User details" ACTION DoUsers()  // ID "v_users"
           ENDPOPUP
           POPUP "&Options"  // ID "options"
               MENUITEM "&Font"        ACTION DoFont()    // ID "o_font"
               MENUITEM "3&d Effects"  ACTION {|c| DoMenu3d(c)} ;
                      ID "o_3d"
           ENDPOPUP
           POPUP "&Help"  // ID "help"
               MENUITEM "&About"       ACTION DoAbout()   // ID "h_about"
           ENDPOPUP
       ENDMENU
  
       Menu3dUpdate()
       return hMenu
  
  Input forms are usually implemented using dialogs - a
  particular kind of window with pre-defined behaviour.  The
  dialog we're concerned with is reached by choosing View | User
  details, resulting in the DoUsers() function being called.
  
  Dialogs can either be designed in a GUI screen editor or built
  dynamically.  It's certainly easier to use a GUI screen
  designer, such as Microsoft's AppStudio (from VC++) or
  Borland's Resource Workshop (from BC++ or the Clip-4-Win
  Toolkit).  However, dynamic dialogs have their good points,
  too - for example, in data-driven applications (or if you
  don't have a GUI screen designer).
  
  Dialog resources, produced by a GUI screen designer, are just
  one kind of resource.  Others include bitmaps, cursors, icons
  and menus (though the Clip-4-Win syntax above is very
  convenient)  The output from a resource editor can include one
  or more include files, defining the resource ID's, and a
  resource file in ASCII (.RC) and/or binary (.RES).  Here's the
  ASCII version used by the next example.  The file is
  USERSRES.RC in your CLIP4WIN\SOURCE\USERSRES directory:
  
       #include "windows.ch"
       #include "usersres.ch"
  
       dlguser DIALOG 20, 20, 183, 127
       STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
       CAPTION "User Details"
       FONT 10, "MS Sans Serif"
       BEGIN
           PUSHBUTTON   "&Ok", IDOK, 132, 13, 37, 12
           PUSHBUTTON   "&Cancel", IDCANCEL, 132, 37, 37, 12
           PUSHBUTTON   "&Next", IDD_NEXT, 132, 61, 37, 12
           PUSHBUTTON   "&Previous", IDD_PREV, 132, 85, 37, 12
           PUSHBUTTON   "&Save", IDD_SAVE, 132, 109, 37, 12
           LTEXT        "User &ID:", IDD_TUSERID, 7, 2, 50, 8
           EDITTEXT     IDD_USERID, 7, 13, 115, 13, ES_AUTOHSCROLL
           LTEXT        "&User Name:", IDD_TUSERNAME, 7, 28, 50, 8
           EDITTEXT     IDD_USERNAME,7,37,115,13,ES_AUTOHSCROLL
           LTEXT        "&Department:", IDD_TDEPT, 7, 52, 50, 8
           EDITTEXT     IDD_DEPT, 7, 61, 115, 13, ES_AUTOHSCROLL
           LTEXT        "P&hone:", IDD_TPHONE, 7, 76, 50, 8
           EDITTEXT     IDD_PHONE, 7, 85, 115, 13, ES_AUTOHSCROLL
           LTEXT        "&Extension:", IDD_T_EXT, 7, 100, 50, 8
           EDITTEXT     IDD_EXT, 7, 109, 115, 13, ES_AUTOHSCROLL
       END
  
  Bearing in mind that you don't usually edit these by hand
  (although sometimes that's the easiest way to achieve what you
  want), this is quite readable - especially if you know that
  LTEXT means left-aligned text, and EDITTEXT means an edit
  control, i.e. an input field.
  
  
  USERS.DBF has fields for USERID, USERNAME, DEPARTMENT, PHONE
  and EXTENSION, so the dialog has similar fields.  The fields
  are reflected in the resource file above, and also in the code
  below.  To avoid immediate, possibly erroneus, updates to
  USERS.DBF, the actual input is buffered in Clipper variables
  until the user presses the Save button.
  
  The main code in DoUsers() arranges to tie Clipper variables
  and functions to the GUI items (controls) in the dialog:
  
       function DoUsers()
       local     GetList
       local     cUserID, cUserName, cDept, cPhone, cExt
       local     oUserID, oUserName, oDept, oPhone, oExt
       local     i, aDlg
  
       CREATE DIALOG aDlg  RESOURCE "dlguser"
  
       @ ID IDOK       BUTTON UserDone
       @ ID IDCANCEL   BUTTON UserDone
       @ ID IDD_NEXT   BUTTON UserNext(bUpdate)
       @ ID IDD_PREV   BUTTON UserPrev(bUpdate)
       @ ID IDD_SAVE   BUTTON UserSave(bGather)
  
       // with just the clauses shown, these aren't needed (the 
       // resource is enough):
       @ ID IDD_USERID       EDIT
       @ ID IDD_USERNAME     EDIT
       @ ID IDD_DEPT         EDIT
       @ ID IDD_PHONE   EDIT
       @ ID IDD_EXT          EDIT
  
       SHOW DIALOG aDlg  RESULT i                                      ;
           ON INIT {|hWndDlg| UserOnInit(hWndDlg, bScatter, @GetList,  ;
                         @cUserID, @cUserName, @cDept, @cPhone, @cExt, ;
                         @oUserID, @oUserName, @oDept, @oPhone, @oExt)}
       return nil
  
  The code above has a function for each button, which is called
  if the user presses the button, and performs initialisation in
  the UserOnInit() function:
  
       static function UserOnInit(hWndDlg, bScatter, GetList,         ;
                            cUserID, cUserName, cDept, cPhone, cExt,  ;
                            oUserID, oUserName, oDept, oPhone, oExt)
       use users new shared
       users->( dbGoTop() )
  
       eval(bScatter)      // fetch fields to static vars
  
       /////////////
       //
       //  The code below does validation using GET objects.
       //
       //  The objects need to be saved because we want to change
       //  them as we move from record to record.
       //
       /////////////
  
       GetList = {}
       @ dialog hWndDlg id IDD_USERID     get cUserID
       oUserID = ATail(GetList)
       @ dialog hWndDlg id IDD_USERNAME get cUserName                  ;
                WHEN iif(len(ltrim(cUserID)) != 0, .t.,                ;
                     (PostMessage(hWndDlg, WM_NEXTDLGCTL, 0, 0), .t.))
       oUserName = ATail(GetList)
       @ dialog hWndDlg id IDD_DEPT  get cDept
       oDept = ATail(GetList)
       @ dialog hWndDlg id IDD_PHONE get cPhone
       oPhone = ATail(GetList)
       @ dialog hWndDlg id IDD_EXT   get cExt  picture "9999"
       oExt = ATail(GetList)
       return nil
  
  As before, this code arranges to tie Clipper variables to the
  controls in the dialog.
  
  The actual code to handle buttons is very short.  For example,
  the Ok button uses:
  
       static function UserDone(hWndDlg, hCtrl, nCode, nId)
       // don't change record (only if SAVE button pressed, i.e. IDD_SAVE)
       CANCEL DIALOG hWndDlg         // cancel any GETs
       close users
       return nil
  
  The Next button is also simple:
  
       static function UserNext(bUpdate, hWndDlg, hCtrl, nCode, nId)
  
       // need to skip, then update GETs
  
       users->( dbSkip(1) )
       if users->( Eof() )
            users->( dbGoBottom() )
       endif
  
       eval(bUpdate, hWndDlg)   // update the GETs and vars
  
       return nil
  
  For the remaining details, please consult the USERSCMD.PRG
  file in the SOURCE\USERSRES directory.
  
  A dynamic (non-resource) dialog version is also called
  USERSCMD.PRG, but is in the SOURCE\USERS directory.  The main
  changes are to specify position and size for the dialog and
  each control, together with any styles needed to specify
  optional characteristics.  Naturally, any descriptive text has
  to be specified, too:
  
       CREATE DIALOG aDlg  TITLE "User Details"               ;
           STYLE DS_MODALFRAME + WS_POPUP + WS_VISIBLE        ;
                 + WS_CAPTION + WS_SYSMENU                    ;
           AT 20,20  SIZE 183, 127  FONT cFontName  POINTSIZE nPointSize
  
       @ ID IDOK      BUTTON UserDone          TEXT "&Ok"     ;
            AT 132,13  SIZE 37,12
       @ ID IDCANCEL  BUTTON UserDone          TEXT "&Cancel" ;
            AT 132,37  SIZE 37,12
       @ ID IDD_NEXT  BUTTON UserNext(bUpdate) TEXT "&Next"   ;
            AT 132,61  SIZE 37,12
       @ ID IDD_PREV  BUTTON UserPrev(bUpdate) TEXT "&Previous"
            AT 132,85  SIZE 37,12
       @ ID IDD_SAVE  BUTTON UserSave(bGather) TEXT "&Save"   ;
            AT 132,109 SIZE 37,12
  
       @ ID IDD_TUSERID    SAY  "User &ID:"     AT 7,2   SIZE 50,8
       @ ID IDD_USERID     EDIT                 AT 7,13  SIZE 115,13
  
       @ ID IDD_TUSERNAME  SAY  "&User Name:"   AT 7,28  SIZE 50,8
       @ ID IDD_USERNAME   EDIT                 AT 7,37  SIZE 115,13
  
       @ ID IDD_TDEPT      SAY  "&Department:"  AT 7,52  SIZE 50,8
       @ ID IDD_DEPT       EDIT                 AT 7,61  SIZE 115,13
  
       @ ID IDD_TPHONE     SAY  "P&hone:"       AT 7,76  SIZE 50,8
       @ ID IDD_PHONE      EDIT                 AT 7,85  SIZE 115,13
  
       @ ID IDD_T_EXT      SAY  "&Extension:"   AT 7,100 SIZE 50,8
       @ ID IDD_EXT        EDIT                 AT 7,109 SIZE 115,13
  
       SHOW DIALOG aDlg  RESULT i                                     ;
           ON INIT {|hWndDlg| UserOnInit(hWndDlg, bScatter, @GetList, ;
                        @cUserID, @cUserName, @cDept, @cPhone, @cExt, ;
                        @oUserID, @oUserName, @oDept, @oPhone, @oExt)}
       return nil
  
  This example was deliberately made the same as the resource
  version, but in practice you can make life without a resource
  editor easier.  You can use AT CHAR clauses to provide dialogs
  with pseudo character positions.  This is an easier version of
  the above:
  
       CREATE DIALOG aDlg  TITLE "User Details"               ;
           STYLE DS_MODALFRAME + WS_POPUP + WS_VISIBLE        ;
                 + WS_CAPTION + WS_SYSMENU                    ;
           AT CHAR 4,4 SIZE 37, 15  FONT cFontName POINTSIZE nPointSize
  
       @ ID IDOK      BUTTON UserDone          TEXT "&Ok"     ;
            AT CHAR 27,1  SIZE 7,1
       @ ID IDCANCEL  BUTTON UserDone          TEXT "&Cancel" ;
            AT CHAR 27,4  SIZE 7,1
       @ ID IDD_NEXT  BUTTON UserNext(bUpdate) TEXT "&Next"   ;
            AT CHAR 27,7  SIZE 7,1
       @ ID IDD_PREV  BUTTON UserPrev(bUpdate) TEXT "&Previous" ;
            AT CHAR 27,10 SIZE 7,1
       @ ID IDD_SAVE  BUTTON UserSave(bGather) TEXT "&Save"   ;
            AT CHAR 27,13 SIZE 7,1
  
       @ ID IDD_TUSERID    SAY  "User &ID:"     AT CHAR 1,0  SIZE 10,1
       @ ID IDD_USERID     EDIT                 AT CHAR 1,1  SIZE 23,1
  
       @ ID IDD_TUSERNAME  SAY  "&User Name:"   AT CHAR 1,3  SIZE 10,1
       @ ID IDD_USERNAME   EDIT                 AT CHAR 1,4  SIZE 23,1
  
       @ ID IDD_TDEPT      SAY  "&Department:"  AT CHAR 1,6  SIZE 10,1
       @ ID IDD_DEPT       EDIT                 AT CHAR 1,7  SIZE 23,1
  
       @ ID IDD_TPHONE     SAY  "P&hone:"       AT CHAR 1,9  SIZE 10,1
       @ ID IDD_PHONE      EDIT                 AT CHAR 1,10 SIZE 23,1
  
       @ ID IDD_T_EXT      SAY  "&Extension:"   AT CHAR 1,12 SIZE 10,1
       @ ID IDD_EXT        EDIT                 AT CHAR 1,13 SIZE 23,1


  
  

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson