TGet / TMGet

Text input controls with PICTURE formatting, validation, and multi-line editing

TGet Overview

Fuente: source/classes/tget.prg  |  Parent: TControl

TGet is the FiveWin equivalent of the classic Clipper GET command -- a single-line text input control that supports PICTURE masks, validation blocks, and data binding via bSetGet. It is the workhorse of data-entry forms.

TMGet Overview

Fuente: source/classes/mget.prg  |  Parent: TControl

TMGet (also known as a memo GET) provides multi-line text editing. It is used for free-form text fields such as notes, comments, and descriptions. It wraps the Windows EDIT control with the ES_MULTILINE style.

Architecture

graph TD subgraph "GET Family" TGet["TGet
Single-line input"] TMGet["TMGet
Multi-line memo"] end TControl --> TGet TControl --> TMGet subgraph "Data Binding" VAR["Harbour Variable"] FIELD["DBF Field"] BLOCK["bSetGet Block"] end VAR --> BLOCK FIELD --> BLOCK BLOCK --> TGet BLOCK --> TMGet subgraph "Validation Pipeline" PICTURE["cPicture
Input mask"] WHEN["bWhen
Enable condition"] VALID["bValid
Exit validation"] end PICTURE --> TGet WHEN --> TGet VALID --> TGet style TGet fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3 style TMGet fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3

TGet Key Properties

PropertyTypeDescription
bSetGetBlockData-binding block. Eval( bSetGet ) reads the value; Eval( bSetGet, x ) writes it.
cPictureStringPICTURE mask controlling input formatting (e.g. "@E 999,999.99", "@!", "99/99/9999")
bValidBlockValidation block evaluated when the user leaves the GET. Must return .T. to allow exit.
bWhenBlockCondition block evaluated when focus approaches. If .F., the GET is skipped (read-only).
lReadOnlyLogicalWhen .T., the field is not editable.
lPasswordLogicalWhen .T., input is masked with bullet characters.
cCueTextStringPlaceholder text shown when the GET is empty and unfocused (watermark).
lSpinnerLogicalWhen .T., adds up/down spinner arrows for numeric input.
nMinNumericMinimum value for spinner.
nMaxNumericMaximum value for spinner.
bChangeBlockBlock evaluated each time the text changes (live update).
lRightLogicalRight-align the text (useful for numeric fields).

TMGet Key Properties

PropertyTypeDescription
bSetGetBlockData-binding block, same as TGet.
lReadOnlyLogicalWhen .T., the memo is not editable.
lWordWrapLogicalWhen .T., text wraps at the right edge instead of scrolling horizontally.
nMaxCharsNumericMaximum number of characters allowed.

Common PICTURE Masks

MaskEffectExample Input/Output
"@!"Force uppercasehelloHELLO
"999,999.99"Numeric with comma separators1234.50 1,234.50
"@E 999,999.99"European numeric (dot=thousands, comma=decimal)1234.50 1.234,50
"99/99/9999"Date mask0324202603/24/2026
"(999)999-9999"US phone number5551234567(555)123-4567
"@K"Clear field when first key is pressedSelects all text on entry
"@S15"Scroll within 15-char display widthLong text scrolls horizontally

Validation Flow

sequenceDiagram participant User participant GET as TGet participant bWhen participant bValid participant NextCtrl as Next Control User->>GET: Tab / Click to enter GET->>bWhen: Eval( bWhen ) alt bWhen returns .T. bWhen-->>GET: .T. (enabled) GET->>GET: Receive focus, allow editing User->>GET: Type data, then Tab to leave GET->>bValid: Eval( bValid ) alt bValid returns .T. bValid-->>GET: .T. (valid) GET->>NextCtrl: Move focus forward else bValid returns .F. bValid-->>GET: .F. (invalid) GET->>GET: Keep focus, show error end else bWhen returns .F. bWhen-->>GET: .F. (disabled) GET->>NextCtrl: Skip this GET end

Command Syntax

Single-line GET

@ nRow, nCol GET oGet VAR cVar ;
   [ OF oWnd ] ;
   [ SIZE nWidth, nHeight ] ;
   [ PICTURE cMask ] ;
   [ VALID bValid ] ;
   [ WHEN bWhen ] ;
   [ READONLY ] ;
   [ PASSWORD ] ;
   [ SPINNER [ MIN nMin ] [ MAX nMax ] ] ;
   [ CUETEXT cPlaceholder ] ;
   [ ON CHANGE bChange ] ;
   [ FONT oFont ] ;
   [ RIGHT ]

Multi-line Memo GET

@ nRow, nCol GET oMGet VAR cMemo MEMO ;
   [ OF oWnd ] ;
   [ SIZE nWidth, nHeight ] ;
   [ READONLY ] ;
   [ FONT oFont ] ;
   [ HSCROLL ] ;
   [ NO WORDWRAP ]

Code Examples

Example 1: Data Entry Form with Various GET Types

#include "FiveWin.ch"

FUNCTION CustomerForm()
   LOCAL oDlg, oFont
   LOCAL cName   := Space( 30 )
   LOCAL cPhone  := Space( 14 )
   LOCAL nAge    := 0
   LOCAL dBirth  := CToD( "" )
   LOCAL cPass   := Space( 12 )
   LOCAL nSalary := 0
   LOCAL cNotes  := Space( 500 )

   DEFINE FONT oFont NAME "Segoe UI" SIZE 0, -14
   DEFINE DIALOG oDlg TITLE "Customer Entry" SIZE 480, 520 FONT oFont

   // Text input with uppercase mask
   @ 1.0, 1 SAY "Name:" OF oDlg
   @ 1.0, 6 GET cName OF oDlg SIZE 200, 22 ;
      PICTURE "@!" ;
      VALID ( !Empty( cName ) ) ;
      CUETEXT "Enter full name"

   // Phone with template mask
   @ 2.5, 1 SAY "Phone:" OF oDlg
   @ 2.5, 6 GET cPhone OF oDlg SIZE 140, 22 ;
      PICTURE "(999)999-9999"

   // Numeric with spinner
   @ 4.0, 1 SAY "Age:" OF oDlg
   @ 4.0, 6 GET nAge OF oDlg SIZE 80, 22 ;
      PICTURE "999" ;
      SPINNER MIN 0 MAX 120

   // Date field
   @ 5.5, 1 SAY "Birth Date:" OF oDlg
   @ 5.5, 6 GET dBirth OF oDlg SIZE 100, 22 ;
      PICTURE "99/99/9999"

   // Password field
   @ 7.0, 1 SAY "Password:" OF oDlg
   @ 7.0, 6 GET cPass OF oDlg SIZE 160, 22 ;
      PASSWORD

   // Numeric with European formatting
   @ 8.5, 1 SAY "Salary:" OF oDlg
   @ 8.5, 6 GET nSalary OF oDlg SIZE 140, 22 ;
      PICTURE "@E 9,999,999.99" ;
      RIGHT

   // Multi-line memo
   @ 10.0, 1 SAY "Notes:" OF oDlg
   @ 10.5, 1 GET cNotes MEMO OF oDlg SIZE 400, 100

   // Buttons
   @ 17, 6  BUTTON "&Save"   OF oDlg SIZE 80, 25 ACTION oDlg:End() DEFAULT
   @ 17, 16 BUTTON "&Cancel" OF oDlg SIZE 80, 25 ACTION oDlg:End() CANCEL

   ACTIVATE DIALOG oDlg CENTERED

   RELEASE FONT oFont
RETURN NIL

Example 2: Validated GET with Dynamic WHEN

#include "FiveWin.ch"

FUNCTION ValidatedForm()
   LOCAL oDlg
   LOCAL cCode    := Space( 5 )
   LOCAL cDesc    := Space( 40 )
   LOCAL nQty     := 0
   LOCAL nPrice   := 0
   LOCAL lApprove := .F.

   DEFINE DIALOG oDlg TITLE "Order Entry" SIZE 400, 300

   @ 1, 1 SAY "Code:" OF oDlg
   @ 1, 5 GET cCode OF oDlg SIZE 80, 22 ;
      PICTURE "@!" ;
      VALID ( ValidateCode( cCode, @cDesc ) )  // look up code, fill description

   @ 2.5, 1 SAY "Description:" OF oDlg
   @ 2.5, 5 GET cDesc OF oDlg SIZE 200, 22 READONLY

   @ 4.0, 1 SAY "Quantity:" OF oDlg
   @ 4.0, 5 GET nQty OF oDlg SIZE 80, 22 ;
      PICTURE "9999" ;
      SPINNER MIN 1 MAX 9999 ;
      VALID ( nQty > 0 )

   @ 5.5, 1 SAY "Price:" OF oDlg
   @ 5.5, 5 GET nPrice OF oDlg SIZE 100, 22 ;
      PICTURE "@E 99,999.99" ;
      WHEN ( !Empty( cCode ) )          // only enabled after valid code

   @ 7.5, 5 BUTTON "&OK" OF oDlg SIZE 80, 25 ;
      ACTION ( lApprove := .T., oDlg:End() ) DEFAULT

   @ 7.5, 14 BUTTON "&Cancel" OF oDlg SIZE 80, 25 ;
      ACTION oDlg:End() CANCEL

   ACTIVATE DIALOG oDlg CENTERED

   IF lApprove
      // process the order...
   ENDIF
RETURN NIL

STATIC FUNCTION ValidateCode( cCode, cDesc )
   IF Empty( cCode )
      MsgStop( "Code is required." )
      RETURN .F.
   ENDIF
   // Look up in database
   cDesc := GetDescForCode( AllTrim( cCode ) )
   IF Empty( cDesc )
      MsgStop( "Code not found." )
      RETURN .F.
   ENDIF
RETURN .T.

Tips and Best Practices

Ver También