home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c163 / 3.ddi / SCRE_SOU.EXE / G4EDIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-29  |  46.7 KB  |  1,723 lines

  1. /* g4edit.c  Edit Area Routines  (c)Copyright Sequiter Software Inc., 1991.  All rights reserved. */
  2.  
  3. #include "c4window.h"
  4. #include "e4error.h"
  5.  
  6. #ifdef __TURBOC__
  7.    #pragma hdrstop
  8. #endif
  9.  
  10. void edit4_make( W4ENTRY *ew, G4EDIT *ea )
  11. {
  12.    control4_construct( &ea->ca, ew ) ;
  13.  
  14.    ea->ca.gw.OldWindowProc = 0 ;
  15.    ea->ca.gw.Id = 0 ;
  16.    ea->ca.hParent = 0 ;
  17.    ea->ca.area_type = c4edit ;
  18.    ea->ca.area = (void *) ea ;
  19.  
  20.    ea->Pict = 0 ;
  21.    ea->PictLen = -1 ;
  22.    ea->Decimals = 0 ;
  23.    ea->nChars = -1 ;
  24.    ea->SelectAnchor = -1 ;
  25.    ea->Margin = ea->MarginTotal = 0 ;
  26.    ea->MaxLen = -1 ;
  27.    ea->EntryType = t4str ;
  28.    ea->Offset = 0 ;
  29.    ea->Pos = 0 ;
  30.    ea->pResult = 0 ;
  31.    ea->pResultLen = 0 ;
  32.  
  33.    ea->isModify = 1 ;
  34.  
  35.    ea->width = 0 ;
  36.    ea->x = -1 ;
  37.    ea->y = -1 ;
  38.  
  39.    ea->data_field = 0 ;
  40.    ea->edit_changed = 0 ;
  41.    ea->is_valid = 1 ;
  42. }
  43.  
  44. int edit4_make2( W4ENTRY *ew, G4EDIT *ea, int x, int y, char *str,
  45.                                int type_get, int width, int dec, int id )
  46. {
  47.    ea->ca.gw.Style = WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP ;
  48.    if ( type_get == t4num_str )
  49.       ea->ca.gw.Style |= ES_RIGHT ;
  50.  
  51.    ea->ca.gw.Id = ( id < 0 ) ? entry4_nextid( ew ) : id ;
  52.    ea->ca.gw.cw = ew->gw.cw ;
  53.    ea->ca.hParent = ew->gw.hWindow ;
  54.    ea->ca.ew = ew ;
  55.  
  56.    general4_init( &ea->ca.gw, ea->ca.gw.cw, "G4EDIT", 0, ea->ca.gw.Style,
  57.                   0,0,0,0, ea->ca.hParent, ea->ca.gw.Id ) ;
  58.  
  59.    return edit4_init( ea, x, y, str, type_get, width, dec ) ;
  60. }
  61.  
  62. G4EDIT *edit4_construct( W4ENTRY *ew )
  63. {
  64.    G4EDIT *ea = (G4EDIT *) u4alloc( sizeof( G4EDIT )) ;
  65.    if ( ea == 0 )
  66.       e4error( w4cb( ew ), e4memory, (char *) 0 ) ;
  67.    else
  68.       edit4_make( ew, ea ) ;
  69.    return ea ;
  70. }
  71.  
  72. int edit4_calcpos( G4EDIT *ea, int pixels )
  73. {
  74.    int text_pixels, len, i ;
  75.  
  76.    HDC hDC = w4get_dc( g4cb( ea ), ea->ca.gw.hWindow ) ;
  77.    if ( hDC == 0 )  return -1 ;
  78.  
  79.    pixels -= ea->MarginTotal ;
  80.    len = lstrlen(ea->Buffer) - ea->Offset ;
  81.  
  82.    for ( i = len; i >= 0; i-- )
  83.    {
  84.       text_pixels = LOWORD( GetTextExtent(hDC, ea->Buffer+ea->Offset, i) ) ;
  85.       if ( pixels >= text_pixels )
  86.          break ;
  87.    }
  88.    if ( w4release_dc( g4cb( ea ), ea->ca.gw.hWindow, hDC ) == 0 )  return -1 ;
  89.  
  90.    if ( i < 0 )  i = 0 ;
  91.    return i + ea->Offset ;
  92. }
  93.  
  94. int edit4_caretmove( G4EDIT *ea )
  95. {
  96.    HDC hDC ;
  97.    DWORD res ;
  98.  
  99.    if ( ea->Buffer == 0 )  return 0 ;
  100.  
  101.    hDC = w4get_dc( g4cb( ea ), ea->ca.gw.hWindow ) ;
  102.    if ( hDC == 0 )  return -1 ;
  103.  
  104.    #ifdef S4DEBUG
  105.       if ( ea->Offset > ea->Pos || ea->Offset < 0 || ea->Pos < 0 || ea->Pos > lstrlen(ea->Buffer)+1 )
  106.          return e4error( g4cb( ea ), e4result, (char *) 0 ) ;
  107.    #endif
  108.    res = GetTextExtent( hDC, ea->Buffer+ea->Offset, ea->Pos-ea->Offset ) ;
  109.  
  110.    SetCaretPos( ea->MarginTotal+LOWORD(res), 0 ) ;
  111.  
  112.    if ( w4release_dc( g4cb( ea ), ea->ca.gw.hWindow, hDC ) == 0 )  return -1 ;
  113.    return 0 ;
  114. }
  115.  
  116. int edit4_delete( G4EDIT *ea, int pos, int len )
  117. {
  118.    int l ;
  119.  
  120.    if ( len <= 0 )  return 0 ;
  121.    if ( ea->Buffer[pos] == '\0' )  return 0 ;
  122.  
  123.    ea->edit_changed = 1 ;
  124.    ea->is_valid = 0 ;
  125.  
  126.    InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  127.  
  128.    if ( ea->Pict == 0 || pos >= ea->PictLen )
  129.    {
  130.       char *temp ;
  131.       l = lstrlen( ea->Buffer ) ;
  132.  
  133.       /* No Picture for Deleted Section or no */
  134.       temp = (char *) u4alloc( l-len+1 ) ;
  135.       if ( temp == 0 )
  136.          return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  137.       memcpy( temp, ea->Buffer, pos ) ;
  138.       memcpy( temp+pos, ea->Buffer+pos+len, l-(len+pos) ) ;
  139.       temp[l-len] = 0 ;
  140.       u4free( ea->Buffer ) ;
  141.       ea->Buffer = temp ;
  142.       return 0 ;
  143.    }
  144.  
  145.    if ( pos + len > ea->PictLen )
  146.    {
  147.       /* Delete Part Overlaps Picture and Non-Picture */
  148.       edit4_delete( ea, ea->PictLen, pos+len-ea->PictLen ) ;
  149.       edit4_delete( ea, pos, ea->PictLen-ea->Pos ) ;
  150.       return 0 ;
  151.    }
  152.  
  153.    /* Only Picture for Delete Part */
  154.    for(; len > 0;)
  155.    {
  156.       char PictCh ;
  157.       int n ;
  158.  
  159.       PictCh = ea->Pict[pos] ;
  160.  
  161.       for( n = 1; ea->Pict[pos+n] != 0; n++ )
  162.          if ( ea->Pict[pos+n] != PictCh )
  163.             break ;
  164.  
  165.       if ( PictCh == '9' )
  166.       {
  167.          if ( len >= n )
  168.             memset( ea->Buffer+pos, '0', n ) ;
  169.          else
  170.             memset( ea->Buffer+pos, '0', len ) ;
  171.       }
  172.       else
  173.       {
  174.          if ( edit4_picturecheck( ea, pos, 0 ) == 0 )
  175.          {
  176.             if ( len >= n )
  177.                memset( ea->Buffer+pos, ' ', n ) ;
  178.             else
  179.             {
  180.                memmove( ea->Buffer+pos, ea->Buffer+pos+len, n-len ) ;
  181.                ea->Buffer[pos+n-1] = ' ' ;
  182.             }
  183.          }
  184.       }
  185.       pos += n ;
  186.       len -= n ;
  187.    }
  188.    l = lstrlen( ea->Buffer ) ;
  189.    for(; ea->Pos < l ; )
  190.    {
  191.       if ( *ea->Buffer+l == ' ' )
  192.          ea->Buffer[l] = 0 ;
  193.       else
  194.          break ;
  195.    }
  196.    return 0 ;
  197. }
  198.  
  199. int edit4_init( G4EDIT *ea, int x, int y, char *str, int type_get, int width, int dec )
  200. {
  201.    char *pict ;
  202.    TEXTMETRIC tm ;
  203.    HDC hDC ;
  204.    char *log_pict = "L" ;
  205.  
  206.    ea->Decimals = dec ;
  207.  
  208.    switch( type_get )                         /* set default pictures */
  209.    {
  210.       case t4date_str:
  211.            if ( g4picture( ea, ea->ca.gw.cw->cb.date_format ) < 0 )
  212.             return -1 ;
  213.          break ;
  214.  
  215.       case t4num_str:
  216.          pict = (char *) u4alloc( width+1 ) ;
  217.          if ( pict == 0 )
  218.             return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  219.          memset( pict, '#', width ) ;
  220.          memset( pict+width-dec, '9', dec ) ;
  221.          pict[width] = 0 ;
  222.          if ( dec > 0 )
  223.             pict[width-dec-1] = '.' ;
  224.          if ( g4picture( ea, pict ) < 0 )  return -1 ;
  225.          u4free( pict ) ;
  226.            break ;
  227.  
  228.       case t4log:
  229.          if ( g4picture( ea, log_pict ) < 0 )  return -1 ;
  230.          break ;
  231.    }
  232.  
  233.    ea->pResult    = str ;
  234.    ea->pResultLen = width ;
  235.    ea->EntryType  = type_get ;
  236.  
  237.    hDC = w4get_dc( g4cb( ea ), ea->ca.gw.hWindow ) ;
  238.    if ( hDC == 0 )  return -1 ;
  239.  
  240.    w4get_metrics( hDC, &tm ) ;
  241.  
  242.    ea->Margin = tm.tmAveCharWidth/2 ;
  243.    ea->x = x ;
  244.    ea->y = y ;
  245.  
  246.    if ( w4release_dc( g4cb( ea ), ea->ca.gw.hWindow, hDC ) == 0 )  return -1 ;
  247.  
  248.    SetWindowLong( ea->ca.gw.hWindow, 0, (LONG) ea ) ;
  249.    return 0 ;
  250. }
  251.  
  252. int edit4_insertchar( G4EDIT *ea, char ch, int pos )
  253. {                                         /* 0 - Inserted; 1 - Not Inserted */
  254.    char pChar ;
  255.    int nPictChars, i ;
  256.  
  257.    ea->edit_changed = 1 ;
  258.    ea->is_valid = 0 ;
  259.  
  260.    if ( pos >= ea->PictLen )
  261.    {
  262.       char str1[2] ;  str1[0] = ch ;  str1[1] = '\0' ;
  263.       return edit4_insertstr( ea, str1, pos ) ;
  264.    }
  265.  
  266.    pChar = ea->Pict[pos] ;
  267.  
  268.    if ( edit4_picturecheck( ea, pos, &ch ) != 0 )
  269.       return 1 ;
  270.  
  271.    for( nPictChars = 1;; nPictChars++ )
  272.    {
  273.       if ( pos+nPictChars >= ea->PictLen )
  274.          break ;
  275.       if ( ea->Pict[pos+nPictChars] != pChar )
  276.          break ;
  277.    }
  278.  
  279.    i = nPictChars - 1 ;
  280.    for ( ; i>0 ; i-- )
  281.       ea->Buffer[pos+i] = ea->Buffer[pos+i-1] ;
  282.    ea->Buffer[pos] = ch ;
  283.  
  284.    edit4_posset( ea, pos + 1, 1 ) ;
  285.    return 0 ;
  286. }
  287.  
  288. int S4FUNCTION edit4_insertstr( G4EDIT *ea, char *str, int pos )
  289. {                                    /* 0 - Inserted; 1 - Not Inserted */
  290.    unsigned start_to_len, move_len, from_len, to_len ;
  291.    char *temp, *to_ptr, *to_pos ;
  292.  
  293.    start_to_len = lstrlen( ea->Buffer ) ;
  294.    move_len     = start_to_len - pos ;
  295.    from_len     = lstrlen( str ) ;
  296.    to_len       = start_to_len + from_len ;
  297.  
  298.    temp = (char *) u4alloc( to_len+1 ) ;
  299.    if ( temp == 0 )
  300.       return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  301.  
  302.    ea->edit_changed = 1 ;
  303.    ea->is_valid = 0 ;
  304.  
  305.    to_ptr = temp ;
  306.    to_pos = to_ptr + pos ;
  307.  
  308.    memcpy( to_pos+from_len, ea->Buffer+pos, move_len ) ;
  309.    memcpy( to_pos, str, from_len ) ;
  310.    memcpy( to_ptr, ea->Buffer, pos ) ;
  311.    to_ptr[to_len] = 0 ;
  312.  
  313.    u4free( ea->Buffer ) ;
  314.    ea->Buffer = temp ;
  315.  
  316.    if ( lstrlen(ea->Buffer) > ea->MaxLen  && ea->MaxLen > 0 )
  317.       ea->Buffer[ea->MaxLen] = 0 ;
  318.    if ( edit4_pictureverify( ea ) == 0 )
  319.    {
  320.       edit4_posset( ea, pos + from_len, 1 ) ;
  321.       return 0 ;
  322.    }
  323.  
  324.    memcpy( ea->Buffer, ea->BufferPrev, lstrlen( ea->BufferPrev ) ) ;
  325.    return 1 ;
  326. }
  327.  
  328. int edit4_insertsaved( G4EDIT *ea )  /* 0 - Inserted; 1 - Not Inserted */
  329. {
  330.    int rc = 0 ;
  331.    HANDLE h ;
  332.  
  333.    if ( IsClipboardFormatAvailable( CF_TEXT ) )
  334.    {
  335.       if ( OpenClipboard( ea->ca.gw.hWindow ) )
  336.       {
  337.          h = GetClipboardData( CF_TEXT ) ;
  338.          if ( h != 0 )
  339.          {
  340.             char *ptr ;
  341.  
  342.             ptr = GlobalLock(h) ;
  343.             rc = edit4_insertstr( ea, ptr, edit4_posget( ea ) ) ;
  344.             GlobalUnlock(h) ;
  345.          }
  346.          CloseClipboard() ;
  347.          InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  348.       }
  349.    }
  350.    return rc ;
  351. }
  352.  
  353. int edit4_paint( G4EDIT *ea )
  354. {
  355.    RECT r ;
  356.    int ExtraPixels, LowSelect, HighSelect, OnPos ; 
  357.    int start = 0, l = lstrlen( ea->Buffer ) ;
  358.  
  359.    HDC hDC = w4get_dc( g4cb( ea ), ea->ca.gw.hWindow ) ;
  360.    if ( hDC == 0 )  return -1 ;
  361.  
  362.    HideCaret( 0 ) ;
  363.  
  364.    if ( SendMessage( ea->ca.gw.hWindow, WM_ERASEBKGND, hDC, 0 ) == 0 )
  365.    {
  366.       e4error( g4cb( ea ), e4result, "WM_ERASEBKGND", (char *) 0 ) ;
  367.       return -1 ;
  368.    }
  369.    w4get_rect( ea->ca.gw.hWindow, &r, 0 ) ;
  370.  
  371.    if ( ea->Pos > l )  ea->Pos = l ;
  372.    if ( ea->Offset >= ea->Pos )  ea->Offset = ea->Pos-1 ;
  373.    if ( ea->Offset < 0 )  ea->Offset = 0 ;
  374.  
  375.    for(;;)
  376.    {
  377.       int wTot ;
  378.       l = lstrlen( ea->Buffer ) ;
  379.  
  380.       ea->nChars = l - ea->Offset ;
  381.       wTot = r.right - ea->Margin*2 ;
  382.       if ( wTot < 0 )  wTot = 0 ;
  383.       for(;;)
  384.       {
  385.          int wChars = LOWORD( GetTextExtent( hDC, ea->Buffer+ea->Offset, ea->nChars ) ) ;
  386.          if ( wChars <= wTot )
  387.          {
  388.             ExtraPixels = wTot - wChars ;
  389.             break ;
  390.          }
  391.          ea->nChars-- ;
  392.       }
  393.  
  394.       if ( ea->Pos - ea->Offset < ea->nChars )
  395.          break ;
  396.       if ( ea->Pos - ea->Offset == ea->nChars )
  397.          if ( ea->Pos == l )
  398.             break ;
  399.  
  400.       ea->Offset = ea->Pos - ea->nChars + 1 ;
  401.  
  402.       if ( ea->Offset > ea->Pos )
  403.       {
  404.          ea->Offset = ea->Pos ;
  405.          break ;
  406.       }
  407.    }
  408.  
  409.    if ( ea->Pos < ea->SelectAnchor )
  410.    {
  411.       LowSelect  = ea->Pos ;
  412.       HighSelect = ea->SelectAnchor ;
  413.    }
  414.    else
  415.    {
  416.       LowSelect  = ea->SelectAnchor ;
  417.       HighSelect = ea->Pos ;
  418.    }
  419.    if ( LowSelect < 0 )
  420.       HighSelect = -1 ;
  421.  
  422.    SetTextAlign( hDC, TA_UPDATECP ) ;
  423.    ea->MarginTotal = ea->Margin ;
  424.    if ( ea->ca.gw.Style & ES_RIGHT )
  425.       ea->MarginTotal += ExtraPixels ;
  426.    else if ( ea->ca.gw.Style & ES_CENTER )
  427.       ea->MarginTotal += ExtraPixels/2 ;
  428.  
  429.    MoveTo( hDC, ea->MarginTotal, 0 ) ;
  430.  
  431.    OnPos = ea->Offset ;
  432.  
  433.    if ( ea->Offset < LowSelect )
  434.    {
  435.       int n = LowSelect - OnPos ;
  436.       if ( n > ea->nChars )
  437.          n = ea->nChars ;
  438.       start = LOWORD( GetTextExtent( hDC, ea->Buffer+OnPos, n ) ) ;
  439.       edit4_textout( ea, hDC, 0, 0, ea->Buffer+OnPos, n ) ;
  440.       ea->nChars -= n ;
  441.       OnPos += n ;
  442.    }
  443.  
  444.    if ( HighSelect > OnPos  &&  ea->nChars > 0 )
  445.    {
  446.       DWORD bk = GetBkColor( hDC ) ;
  447.       DWORD tx = GetTextColor( hDC ) ;
  448.       int n = HighSelect - OnPos ;
  449.  
  450.       SetBkColor( hDC, tx ) ;
  451.       SetTextColor( hDC, bk ) ;
  452.  
  453.       if ( n > ea->nChars )
  454.          n = ea->nChars ;
  455.       edit4_textout( ea, hDC, start, 0, ea->Buffer+OnPos, n ) ;
  456.       start += LOWORD( GetTextExtent( hDC, ea->Buffer+OnPos, n ) ) ;
  457.       ea->nChars -= n ;
  458.       OnPos += n ;
  459.  
  460.       SetBkColor( hDC, bk ) ;
  461.       SetTextColor( hDC, tx ) ;
  462.    }
  463.  
  464.    if ( ea->nChars > 0 )
  465.       edit4_textout( ea, hDC, start, 0, ea->Buffer+OnPos, ea->nChars ) ;
  466.  
  467.    if ( w4release_dc( g4cb( ea ), ea->ca.gw.hWindow, hDC )== 0 )  return -1 ;
  468.  
  469.    if ( GetFocus() == ea->ca.gw.hWindow )
  470.       edit4_caretmove( ea ) ;
  471.    ShowCaret(0) ;
  472.    ValidateRect( ea->ca.gw.hWindow, 0 ) ;
  473.  
  474.    return 0 ;
  475. }
  476.  
  477. int S4FUNCTION g4picture( G4EDIT *ea, char *pict )
  478. {
  479.    int l ;
  480.  
  481.    #ifdef S4DEBUG
  482.       if ( ea == 0 )
  483.          e4severe( e4parm, "g4picture", E4_PARM_ZER, (char *) 0 ) ;
  484.    #endif
  485.  
  486.    if ( ea->ca.gw.cw->cb.error_code < 0 )  return -1 ;
  487.  
  488.    if ( ea->EntryType == t4num_str )
  489.    {
  490.       /* ensures that the picture is of the form : "#,,,##.9,,,99" */
  491.       char *ptr = strchr( pict, '.' ) ;
  492.       if ( ptr == 0 )
  493.          memset( pict, '#', lstrlen( pict )) ; 
  494.       else
  495.       {
  496.          memset( pict, '#', lstrlen( pict ) - lstrlen( ptr ) ) ;
  497.          memset( ptr+1, '9', lstrlen( ptr ) - 1 ) ;
  498.       }
  499.    }
  500.  
  501.    l = lstrlen( pict ) ;
  502.  
  503.    if ( ea->Pict != 0 )  u4free( ea->Pict ) ;
  504.    ea->PictLen = 0 ;
  505.  
  506.    if ( pict != 0 )
  507.    {
  508.       ea->Pict = (char *) u4alloc( l + 1 ) ;
  509.       if ( ea->Pict == 0 )  return -1 ;
  510.       ea->Pict[l] = 0 ;
  511.  
  512.       memcpy( ea->Pict, pict, l ) ;
  513.       if ( ea->Pict != 0 )
  514.          ea->PictLen = l ;
  515.    }
  516.    else
  517.       ea->Pict = 0 ;
  518.  
  519.    return 0 ;
  520. }
  521.  
  522. const char YES_CHAR = 'Y' ;
  523.  
  524. int edit4_picturecheck( G4EDIT *ea, int pict_pos, char *pCh )
  525. {
  526.    unsigned char ch = 0, cPict ;
  527.    int final_rc ;
  528.  
  529.    if ( pCh != 0 )  ch = *pCh ;
  530.  
  531.    if ( ea->Pict == 0 )
  532.       return e4error( g4cb( ea ), e4result, E4_RESULT_PIC, (char *) 0 ) ;
  533.  
  534.    if ( pict_pos >= ea->PictLen )
  535.       return 0 ;
  536.  
  537.    cPict = ea->Pict[pict_pos] ;
  538.    final_rc = 0 ;
  539.  
  540.    switch ( cPict )
  541.    {
  542.       case '!':
  543.       case 'L':
  544.          if ( pCh == 0 )  break ;
  545.  
  546.          AnsiUpperBuff( pCh, 1 ) ;
  547.          if ( cPict == 'L' )
  548.          {
  549.             ch = *pCh ;
  550.  
  551.             if ( ch == 'Y' )  *pCh = 'T' ;
  552.             if ( ch == 'N' )  *pCh = 'F' ;
  553.  
  554.             if ( ch != 'Y' && ch != 'N' &&
  555.                #ifdef S4GERMAN
  556.                   ch != 'J' &&
  557.                #endif
  558.                ch != 'T' && ch != 'F' )
  559.             final_rc = 1 ;
  560.          }
  561.          if ( cPict == 'Y' )
  562.          {
  563.             ch = *pCh ;
  564.  
  565.             #ifdef S4GERMAN
  566.                if ( ch != 'Y' && ch != 'J' && ch != 'N' )
  567.                   final_rc = 1 ;
  568.             #else
  569.                if ( ch != 'Y' && ch != 'N' )
  570.                   final_rc = 1 ;
  571.             #endif
  572.          }
  573.          break ;
  574.  
  575.       case 'X':
  576.          return 0 ;
  577.  
  578.       case '9':
  579.          if ( ch < '0' || ch > '9' )
  580.             final_rc = 1 ;
  581.          break ;
  582.  
  583.       case '#':
  584.          if ( ch != '+' && ch != '-' && ch != ' ' && (ch < '0' || ch > '9') )
  585.             final_rc = 1 ;
  586.          break ;
  587.  
  588.       case 'A':
  589.       case 'N':
  590.          if ( ch >= 'A' && ch <= 'Z'  || ch >= 'a' && ch <= 'z' )
  591.             break ;
  592.          if ( (ch >= '0' && ch <= '9' || ch == '_' ) && cPict == 'N' )
  593.             break ;
  594.          #ifdef S4GERMAN   /* ANSI char codes  */
  595.             if ( (ch == 196) || (ch == 214) || (ch == 220) || (ch == 223) || 
  596.                  (ch == 228) || (ch == 246) || (ch == 252) ) 
  597.               break ;
  598.          #endif
  599.          #ifdef S4FRENCH   /* ANSI char codes */
  600.             if ( (ch == 192) || (ch == 194) || (ch == 206) || (ch == 207) ||
  601.                  (ch == 212) || (ch == 219) || (ch == 224) || (ch == 226) ||
  602.                  (ch == 238) || (ch == 239) || (ch == 244) || (ch == 251) ||
  603.                  (ch >= 199 && ch <= 203) || (ch >= 231 && ch <= 235) )   
  604.               break ;
  605.          #endif
  606.          final_rc = 1 ;
  607.          break ;
  608.  
  609.       case 'C':
  610.       case 'D':
  611.       case 'M':
  612.       case 'Y':
  613.          if ( ea->EntryType == t4date_str )
  614.          {
  615.             final_rc = 1 ;
  616.  
  617.             if ( cPict == 'M' )
  618.             {
  619.                int i, num = 0 ;
  620.  
  621.                for ( i = 0; ea->Pict[i] != 0; i++ )
  622.                   if ( ea->Pict[i] == 'M' )  num++ ;
  623.                if ( num > 2 )
  624.                {
  625.                   if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch == ' ')
  626.                      final_rc = 0 ;
  627.                   #ifdef S4GERMAN   /* ANSI char codes */
  628.                      if ( (ch == 196) || (ch == 214) || (ch == 220) || (ch == 223) ||
  629.                           (ch == 228) || (ch == 246) || (ch == 252) ) 
  630.                         final_rc = 0 ;
  631.                   #endif
  632.                   #ifdef S4FRENCH   /* ANSI char codes */
  633.                      if ( (ch == 192) || (ch == 194) || (ch == 206) || (ch == 207) ||
  634.                           (ch == 212) || (ch == 219) || (ch == 224) || (ch == 226) ||
  635.                           (ch == 238) || (ch == 239) || (ch == 244) || (ch == 251) ||
  636.                           (ch >= 199 && ch <= 203) || (ch >= 231 && ch <= 235) )   
  637.                         final_rc = 0 ;
  638.                   #endif
  639.                   break ;
  640.                }
  641.             }
  642.             if ( ch >= '0' && ch <= '9' || ch == ' ')
  643.                final_rc = 0 ;
  644.             break ;
  645.          }
  646.          else
  647.          {
  648.             if ( pCh == 0 )  break ;
  649.             if ( cPict == 'Y' )
  650.             {
  651.                AnsiUpperBuff( pCh, 1 ) ;
  652.                ch = *pCh ;
  653.  
  654.                #ifdef S4GERMAN
  655.                   if ( ch != 'Y' && ch != 'J' && ch != 'N' )
  656.                      final_rc = 1 ;
  657.                #else
  658.                   if ( ch != 'Y' && ch != 'N' )
  659.                      final_rc = 1 ;
  660.                #endif
  661.             }
  662.          }
  663.          break ;
  664.  
  665.       default:
  666.          if ( pCh != 0 )
  667.             *pCh = cPict ;
  668.          if ( ch == 0 || ch == cPict )
  669.             return 2 ;
  670.          else
  671.             return 3 ;
  672.    }
  673.    if ( ch == 0 )
  674.       final_rc = 0 ;
  675.    return final_rc ;
  676. }
  677.  
  678. int edit4_pictureverify( G4EDIT *ea )
  679. {                               /* 1 - Not Good; 0 - Good; < 0 Error */
  680.    char *ptr ;
  681.    int i, rc, len = lstrlen( ea->Buffer ) ;
  682.  
  683.    if ( (ea->EntryType == t4num_str) && (ea->BufferPrev != 0) )
  684.    {
  685.       int start, finish ;
  686.  
  687.       start  = edit4_posget( ea ) + 1 ;
  688.       finish = len - ea->Decimals - 1 ;
  689.       if ( ea->Decimals == 0 )  finish++ ;
  690.  
  691.       if ( (start > finish) && (ea->Buffer[ea->Pos] == '.') )  return 1 ;
  692.       if ( start > finish )  return 0 ;  /* added this ... */
  693.  
  694.       memset( ea->Buffer+start, ' ', finish-start ) ;
  695.  
  696. /* if '.' pressed on 'whole' part of number */
  697.       if ( ( ea->Buffer[ea->Pos] == '.' ) && ( ea->Decimals > 0 ) )
  698.       {
  699.          if ( ea->Pos == 0 )
  700.          {
  701.             memset( ea->Buffer, ' ', finish ) ;
  702.             ea->Buffer[finish-1] = '0' ;
  703.             edit4_posset( ea, finish-1, 1 ) ;
  704.          }
  705.          else
  706.          {
  707.             if ( ea->Pos > 0 )
  708.             {
  709.                ptr = (char *) u4alloc( ea->Pos+1 ) ;
  710.                if ( ptr == 0 )
  711.                   return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  712.                memcpy( ptr, ea->Buffer, ea->Pos+1 ) ;
  713.                memset( ea->Buffer, ' ', finish ) ;
  714.                memcpy( ea->Buffer+finish-ea->Pos, ptr, ea->Pos ) ;
  715.                edit4_posset( ea, finish-1, 1 ) ;
  716.                u4free( ptr ) ;
  717.             }
  718.          }
  719.  
  720.          ptr = strchr( ea->Buffer, '.' ) ;
  721.          if ( ptr != 0 )
  722.             if ( strcspn( ea->Buffer, "1234567890" ) > len-ea->Decimals-1 )
  723.                *(ptr-1) = '0' ;
  724.  
  725.          memset( ea->Buffer+finish+1, '0', len-finish-1 ) ;
  726.       }
  727.    }
  728.    if ( ea->Pict == 0 )
  729.    {
  730.       if ( ea->EntryType == t4num_str )
  731.       {
  732.          for( i = 0; i < len ; i++ )
  733.          {
  734.             char ch = ea->Buffer[i] ;
  735.             if ( ch != 0 && (ch < '0' || ch > '9') && ch != '+' && ch != '-' && ch != '.' )
  736.                return 1 ;
  737.          }
  738.          return 0 ;
  739.       }
  740.       return 0 ;
  741.    }
  742.    ptr = ea->Buffer ;
  743.    for ( i = 0; ea->Pict[i] != 0 && i < len; i++ )
  744.    {
  745.       rc = edit4_picturecheck( ea, i, ptr+i ) ;
  746.       if ( rc == 1 || rc == 3 )
  747.          return 1 ;
  748.    }
  749.    return 0 ;
  750. }
  751.  
  752. int edit4_posget( G4EDIT *ea )
  753. {
  754.    return ea->Pos ;
  755. }
  756.  
  757. void edit4_posset( G4EDIT *ea, int new_pos, int pict_dir )
  758. {                                   /* 0 - None; 1 Change Up; -1 Move Down */
  759.    int l = lstrlen( ea->Buffer ) ;
  760.  
  761.    if ( ea->isModify == 0 )  return ;
  762.    ea->Pos = new_pos ;
  763.  
  764.    if ( ea->Pos < 0 )  ea->Pos = 0 ;
  765.    if ( ea->Pos > l )  ea->Pos = l ;
  766.  
  767.    for ( ; ea->Pos < ea->PictLen ; )
  768.    {
  769.       if ( edit4_picturecheck( ea, ea->Pos, 0 ) > 1 )
  770.       {
  771.          ea->Buffer[ea->Pos] = ea->Pict[ea->Pos] ;
  772.          ea->Pos += pict_dir ;
  773.  
  774.          if ( ea->Pos < 0 )
  775.          {
  776.             ea->Pos = new_pos ;
  777.             pict_dir = 1 ;
  778.          }
  779.          continue ;
  780.       }
  781.       if ( ea->Pos > l )  ea->Pos = l ;
  782.       break ;
  783.    }
  784.  
  785.    if ( ea->Pos < ea->Offset )
  786.    {
  787.       ea->Offset = ea->Pos - 1 ;
  788.       if ( ea->Offset < 0 )  ea->Offset = 0 ;
  789.       InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  790.    }
  791.    else
  792.    {
  793.       if ( ea->Pos-ea->Offset > ea->nChars )
  794.          InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  795.       else
  796.          edit4_caretmove( ea ) ;
  797.    }
  798.    edit4_selectnone( ea ) ;
  799. }
  800.  
  801. int S4FUNCTION g4edit_save( G4EDIT *ea )
  802. {
  803.    int i, j ;
  804.    int l = lstrlen( ea->Buffer ) ;
  805.    int count ;
  806.    D4DATA *data ;
  807.  
  808.    if ( ea->data_field != 0 )
  809.    {
  810.       data  = f4data( ea->data_field ) ;
  811.       count = (int) d4reccount( data ) ;
  812.    }
  813.  
  814.    edit4_packnumeric( ea ) ;
  815.  
  816.    if ( ea->combo != 0 )
  817.    {
  818.       if ( l < ea->pResultLen )
  819.       {
  820.          memcpy( ea->pResult, ea->Buffer, l ) ;
  821.          memset( ea->pResult+l, ' ', ea->pResultLen-l ) ;
  822.          if ( ea->data_field == 0 )
  823.             ea->pResult[l] = 0 ;
  824.       }
  825.       else
  826.          memcpy( ea->pResult, ea->Buffer, ea->pResultLen ) ;
  827.  
  828.       if ( ea->data_field != 0 )
  829.          if ( count > 0 )
  830.             f4assign_ptr( ea->data_field ) ;
  831.          else
  832.          {
  833.             d4append_start( data, 1 ) ;
  834.             d4append( data ) ;
  835.          }
  836.       ea->edit_changed = 0 ;
  837.       return 0 ;
  838.    }
  839.  
  840.    if ( ea->edit_changed == 0 )
  841.       return 0 ;
  842.  
  843.    if ( ea->data_field != 0 )
  844.       if ( f4type( ea->data_field ) == 'M' )
  845.       {
  846.          m4assign( ea->data_field, ea->Buffer ) ;
  847.          ea->edit_changed = 0 ;
  848.          return 0 ;
  849.       }
  850.  
  851.    if ( ea->Pict == 0 )
  852.    {
  853.       if ( l < ea->pResultLen )
  854.       {
  855.          memcpy( ea->pResult, ea->Buffer, l ) ;
  856.          memset( ea->pResult+l, ' ', ea->pResultLen-l ) ;
  857.          if ( ea->data_field == 0 )
  858.             ea->pResult[l] = 0 ;
  859.       }
  860.       else
  861.          memcpy( ea->pResult, ea->Buffer, ea->pResultLen ) ;
  862.    }
  863.    else
  864.    {     /* need to also make sure it is a valid date picture */
  865.       if ( ea->EntryType == t4date_str )
  866.       {
  867.          if ( edit4_datecheck( ea ) != 0 )
  868.             return -1 ;   
  869.          a4init( ea->pResult, ea->Buffer, ea->Pict );
  870.       }
  871.       else
  872.       {
  873.          for ( i=0, j=0 ; j < l ; i++, j++ )
  874.             if ( j < ea->PictLen )
  875.             {
  876.                if ( ((ea->EntryType == 'n') || (ea->EntryType == 'N')) &&
  877.                      (ea->Decimals > 0) && (ea->Pict[j] == '.') )
  878.                   ea->pResult[i] = ea->Buffer[j] ;   
  879.                else
  880.                {
  881.                   if ( strrchr( "!9#ALNXYCYDM", ea->Pict[j] ) != 0 )
  882.                      ea->pResult[i] = ea->Buffer[j] ;   
  883.                   else
  884.                      i-- ;
  885.                }
  886.             }
  887.             else
  888.                ea->pResult[i] = ea->Buffer[j] ;
  889.       }
  890.    }
  891.    if ( ea->data_field != 0 )
  892.       if ( count > 0 )
  893.          f4assign_ptr( ea->data_field ) ;
  894.       else
  895.       {
  896.          d4append_start( data, 1 ) ;
  897.          d4append( data ) ;
  898.       }
  899.  
  900.    ea->edit_changed = 0 ;
  901.  
  902.    return 0 ;
  903. }
  904.  
  905. void edit4_selectblanks( G4EDIT *ea, int dir, int flag )
  906. {
  907.    char *ptr = ea->Buffer ;
  908.    int len = lstrlen( ea->Buffer ) ;
  909.  
  910.    for(;;)
  911.    {
  912.       if ( ea->Pos < 0 )
  913.          break ;
  914.       if ( ! (flag && ptr[ea->Pos] == ' ' || ! flag && ptr[ea->Pos] != ' ') )
  915.          break ;
  916.       if ( (ea->Pos >= len) && (dir > 0) )
  917.          break ;
  918.       ea->Pos += dir ;
  919.    }
  920. }
  921.  
  922. int edit4_selectdelete( G4EDIT *ea )
  923. {                               /* 1 - Did delete; 0 - Nothing to delete */
  924.    if ( ea->SelectAnchor >= 0 )
  925.    {
  926.       int rc ;
  927.       if ( ea->Pos < ea->SelectAnchor )
  928.       {
  929.          rc = edit4_delete( ea, ea->Pos, ea->SelectAnchor-ea->Pos ) ;
  930.          edit4_posset( ea, ea->Pos, 1 ) ;    
  931.       }
  932.       else
  933.       {
  934.          rc = edit4_delete( ea, ea->SelectAnchor, ea->Pos-ea->SelectAnchor ) ;
  935.          edit4_posset( ea, ea->SelectAnchor, 1 ) ;    
  936.       }
  937.       edit4_selectnone( ea ) ;
  938.       return rc ;
  939.    }
  940.    return 0 ;
  941. }
  942.  
  943. void edit4_selectextraword( G4EDIT *ea, int dir )
  944. {
  945.    if ( ea->SelectAnchor < 0 )  ea->SelectAnchor = ea->Pos ;
  946.    if ( dir < 0 )  ea->Pos-- ;
  947.    edit4_selectblanks( ea, dir, 1 ) ;     /* Select past blanks */
  948.    if ( dir > 0 )
  949.    {                                      /* Increasing selection */
  950.       edit4_selectblanks( ea, dir, 0 ) ;  /* Select past non-blanks */
  951.       edit4_selectblanks( ea, dir, 1 ) ;  /* Select past blanks */
  952.    }
  953.    else
  954.    {                                      /* Decreasing selection */
  955.       edit4_selectblanks( ea, dir, 0 ) ;  /* Select past non-blanks */
  956.       ea->Pos++ ;
  957.    }
  958.    if ( ea->SelectAnchor == ea->Pos )
  959.       edit4_selectnone( ea ) ;
  960.    InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  961. }
  962.  
  963. void edit4_selectnone( G4EDIT *ea )
  964. {
  965.    if ( ea->SelectAnchor >= 0 )
  966.       InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  967.  
  968.    ea->SelectAnchor = -1 ;
  969. }
  970.  
  971. int edit4_selectposlow( G4EDIT *ea )
  972. {
  973.    if ( ea->SelectAnchor < ea->Pos )
  974.       return ea->SelectAnchor ;
  975.    return ea->Pos ;
  976. }
  977.  
  978. int edit4_selectlen( G4EDIT *ea )
  979. {
  980.    int len ;
  981.  
  982.    if ( ea->SelectAnchor < 0 )
  983.       return 0 ;
  984.    len = ea->SelectAnchor - ea->Pos ;
  985.    if ( len < 0 )  len = -len ;
  986.    return len ;
  987. }
  988.  
  989. int edit4_selectsave( G4EDIT *ea )    /* Save to clipboard */
  990. {
  991.    HANDLE h ;
  992.    char *ptr ;
  993.    int len, pos = edit4_selectposlow( ea ) ;
  994.  
  995.    if ( pos >= 0 )
  996.    {
  997.       if ( ! OpenClipboard( ea->ca.gw.hWindow ))
  998.          return 1 ;
  999.  
  1000.       len = edit4_selectlen( ea ) ;
  1001.  
  1002.       h = GlobalAlloc( GHND, (DWORD)(len)+1 ) ;
  1003.       if ( h == 0 )
  1004.       {
  1005.          e4error( g4cb( ea ), e4memory, "edit4_selectsave", (char *) 0 ) ;
  1006.          CloseClipboard() ;
  1007.          return -1 ;
  1008.       }
  1009.       ptr = GlobalLock( h ) ;
  1010.       memcpy( ptr, ea->Buffer+pos, edit4_selectlen( ea ) ) ;
  1011.  
  1012.       GlobalUnlock( h ) ;
  1013.  
  1014.       EmptyClipboard() ;
  1015.       SetClipboardData( CF_TEXT, h ) ;
  1016.       CloseClipboard() ;
  1017.    }
  1018.    return 0 ;
  1019. }
  1020.  
  1021. void edit4_selectto( G4EDIT *ea, int pos )
  1022. {
  1023.    int l = lstrlen( ea->Buffer ) ;
  1024.  
  1025.    if ( pos < 0 )  pos = 0 ;
  1026.    if ( pos > l )  pos = l ;
  1027.    if ( ea->SelectAnchor < 0 )
  1028.       ea->SelectAnchor = ea->Pos ;
  1029.    ea->Pos = pos ;
  1030.    if ( ea->Pos == ea->SelectAnchor )
  1031.       ea->SelectAnchor = -1 ;
  1032.    InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1033. }
  1034.  
  1035. void edit4_selectusingmouse( G4EDIT *ea, int pixels )
  1036. {
  1037.    RECT r ;
  1038.  
  1039.    if ( g4handle( ea ) != GetFocus() )  return ;
  1040.  
  1041.    if ( pixels < 0 )
  1042.    {
  1043.       edit4_selectto( ea, ea->Pos-1 ) ;
  1044.       return ;
  1045.    }
  1046.  
  1047.    w4get_rect( ea->ca.gw.hWindow, &r, 0 ) ;
  1048.    if ( pixels > r.right )
  1049.       edit4_selectto( ea, ea->Pos+1 ) ;
  1050.    else
  1051.       edit4_selectto( ea, edit4_calcpos( ea, pixels ) ) ;
  1052. }
  1053.  
  1054. void edit4_typeoverflip( G4EDIT *ea )
  1055. {
  1056.    ea->ca.gw.cw->TypeOver =! ea->ca.gw.cw->TypeOver ;
  1057.    edit4_caretcreate( ea ) ; 
  1058.    ShowCaret( ea->ca.gw.hWindow ) ;
  1059. }
  1060.  
  1061. void edit4_undo( G4EDIT *ea )
  1062. {
  1063.    int l = lstrlen( ea->Buffer ) ;
  1064.  
  1065.    ea->edit_changed = 1 ;
  1066.    ea->is_valid = 0 ;
  1067.  
  1068.    memcpy( ea->Buffer, ea->BufferPrev, l ) ;
  1069.    ea->SelectAnchor = -1 ;
  1070.    if ( ea->Pos > l )  ea->Pos = l ;
  1071.    InvalidateRect( ea->ca.gw.hWindow, NULL, 0 ) ;
  1072. }
  1073.  
  1074. int edit4_process_message( G4EDIT *ea, WORD message, WORD wParam, LONG lParam )
  1075. {
  1076.    int l, rc, move = 1 ;
  1077.  
  1078.    if ( ea->Buffer != 0 )  l = lstrlen( ea->Buffer ) ;
  1079.    if ( ea == 0 )  return 0 ;    /* static area chosen in browse */
  1080.  
  1081.    rc = control4_process_message( &ea->ca, message, wParam, lParam ) ;
  1082.    if ( rc )  return rc ;
  1083.  
  1084.    switch( message )
  1085.    {
  1086.       case WM_NCPAINT:
  1087.       {
  1088.          G4CONTROL *ca ;
  1089.          G4COMBO *cba ;
  1090.          W4ENTRY *ew = w4entry( ea ) ;
  1091.  
  1092.          for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  1093.             if ( ca->area_type == c4edit )
  1094.             {
  1095.                cba = (G4COMBO *) ((G4EDIT *)ca->area)->combo ;
  1096.                if ( cba != 0 )
  1097.                   if ( (cba->is_down == 1) && (cba->isDrop == 1) )
  1098.                      return 1 ;
  1099.             }
  1100.          return 0 ;
  1101.       }
  1102.  
  1103.       case WM_CHAR:
  1104.          if ( ea->isModify == 0 )  return 1 ;
  1105.          if ( wParam == VK_BACK )  return 1 ;
  1106.  
  1107.          if ( ea->BufferPrev != 0 ) 
  1108.             u4free( ea->BufferPrev ) ;
  1109.          ea->BufferPrev = (char *) u4alloc( l + 1 ) ;
  1110.          memcpy( ea->BufferPrev, ea->Buffer, l + 1 ) ;
  1111.          edit4_selectdelete( ea ) ;
  1112.  
  1113.          if ( (ea->ca.gw.cw->TypeOver) || (ea->EntryType == t4num_str) )
  1114.             rc = edit4_replace( ea, wParam, edit4_posget( ea ) ) ;
  1115.          else
  1116.             rc = edit4_insertchar( ea, (char) wParam, edit4_posget( ea ) ) ;
  1117.  
  1118.          if ( rc == 0 )
  1119.             InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1120.          break ;
  1121.  
  1122.       case WM_KEYDOWN:
  1123.       {
  1124.          int is_shift, is_ctrl, is_none, is_shift_ctrl, final_pos ;
  1125.  
  1126.          if ( ea->combo != 0 )
  1127.             if ( (wParam == VK_UP) || (wParam == VK_DOWN) )
  1128.             {
  1129.                G4COMBO *combo = (G4COMBO *) ea->combo ;
  1130.                SendMessage( combo->list->ca.gw.hWindow, WM_KEYDOWN, wParam, NULL ) ;
  1131.                return 1 ;
  1132.             }
  1133.  
  1134.          if ( ea->isModify == 0 )  return 1 ;
  1135.          is_shift = GetKeyState( VK_SHIFT ) < 0 ;
  1136.          is_ctrl  = GetKeyState( VK_CONTROL ) < 0 ;
  1137.          is_none = 1 ;
  1138.          if ( is_shift || is_ctrl )  is_none = 0 ;
  1139.          is_shift_ctrl = is_shift && is_ctrl ;
  1140.          if ( is_shift_ctrl )
  1141.             is_shift = is_ctrl = 0 ;
  1142.  
  1143.          switch ( wParam )
  1144.          {
  1145.             case VK_BACK:
  1146.                if ( is_none )
  1147.                {
  1148.                   int cur_pos = edit4_posget( ea ) ;
  1149.                   if ( cur_pos > 0 )
  1150.                   {
  1151.                      edit4_posset( ea, edit4_posget( ea ) - 1, -1 ) ;
  1152.                      if ( edit4_posget( ea ) < cur_pos )
  1153.                         edit4_delete( ea, edit4_posget( ea ), 1 ) ;
  1154.                   }
  1155.                }
  1156.                return 1 ;
  1157.  
  1158.             case VK_INSERT:
  1159.                if ( is_ctrl )  edit4_selectsave( ea ) ;
  1160.                if ( is_shift )
  1161.                {
  1162.                   u4free( ea->BufferPrev ) ;
  1163.                   ea->BufferPrev = (char *) u4alloc( l + 1 ) ;
  1164.                   memcpy( ea->BufferPrev, ea->Buffer, l + 1 ) ;
  1165.                   edit4_insertsaved( ea ) ;
  1166.                }
  1167.                if ( is_none )
  1168.                   if ( ea->isModify == 1 )
  1169.                      edit4_typeoverflip( ea ) ;
  1170.                break ;
  1171.  
  1172.             case VK_DELETE:
  1173.                final_pos = edit4_selectposlow( ea ) ;
  1174.                if ( is_shift )
  1175.                {
  1176.                   if ( final_pos < 0 )
  1177.                      break ;
  1178.                   if ( edit4_selectsave( ea ) )
  1179.                      return 1 ;
  1180.                   edit4_selectdelete( ea ) ;
  1181.                   edit4_posset( ea, final_pos, 1 ) ;
  1182.                   break ;
  1183.                }
  1184.                if ( edit4_selectdelete( ea ) )
  1185.                {
  1186.                   edit4_posset( ea, final_pos, 1 ) ;
  1187.                   break ;
  1188.                }
  1189.                edit4_delete( ea, edit4_posget( ea ), 1 ) ;
  1190.                break ;
  1191.  
  1192.             case VK_HOME:
  1193.                if ( is_shift || is_shift_ctrl )
  1194.                   edit4_selectto( ea, 0 ) ;
  1195.                if ( is_none )
  1196.                   edit4_posset( ea, 0, 1 ) ;
  1197.                break ;
  1198.  
  1199.             case VK_END:
  1200.             {
  1201.                int j = l - 1 ;
  1202.                while ( (ea->Buffer[j] == ' ') && (j>=0) )
  1203.                   j-- ;
  1204.  
  1205.                if ( is_shift || is_shift_ctrl )
  1206.                   edit4_selectto( ea, j+1 ) ;
  1207.                else
  1208.                   edit4_posset( ea, j+1, 1 ) ;
  1209.             }
  1210.                break ;
  1211.  
  1212.             case VK_LEFT:
  1213.                move = -1 ;
  1214.             case VK_RIGHT:
  1215.                if ( is_shift )
  1216.                   edit4_selectto( ea, ea->Pos + move ) ;
  1217.                if ( is_shift_ctrl )
  1218.                   edit4_selectextraword( ea, move ) ;
  1219.                if ( is_none )
  1220.                   edit4_posset( ea, edit4_posget( ea )+move, move ) ;
  1221.                break ;
  1222.          }
  1223.          break ;
  1224.       }
  1225.  
  1226.       case WM_PAINT:
  1227.          if ( ea->ca.nopaint == 1 )
  1228.             ea->ca.nopaint = 0 ;
  1229.          else
  1230.             edit4_paint( ea ) ;
  1231.          return 1 ;
  1232.  
  1233.       case WM_SETFOCUS:
  1234.       {
  1235.          W4ENTRY *entry = ea->ca.ew ;
  1236.  
  1237.          edit4_caretcreate( ea ) ;
  1238.          edit4_caretmove( ea ) ;
  1239.          ShowCaret( ea->ca.gw.hWindow ) ;
  1240.          InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1241.  
  1242.          if ( (entry->bw != 0) && (entry->isReady != 0) )
  1243.          {
  1244.             browse4_current( entry->bw, ea ) ;
  1245.             browse4_refreshhorzscrollpos( entry->bw ) ;
  1246.          }
  1247.          break ;
  1248.       }
  1249.  
  1250.       case WM_KILLFOCUS:
  1251.          edit4_packnumeric( ea ) ;
  1252.          edit4_selectnone(ea);
  1253.          InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1254.          DestroyCaret() ;
  1255.          break ;
  1256.  
  1257.       case WM_SYSCHAR:
  1258.          if ( wParam == VK_BACK )
  1259.             if ( lParam & 0x20000000L )
  1260.             {
  1261.                edit4_undo( ea ) ;
  1262.                return 1 ;
  1263.             }
  1264.          if ( entry4_process_message( ea->ca.ew, WM_SYSCHAR, wParam, lParam ) )
  1265.             return 1 ;
  1266.          break ;
  1267.  
  1268.       case WM_LBUTTONDOWN:
  1269.          if ( control4_ok( ea->ca.ew, 1 ) == 0 )
  1270.      {
  1271.         if ( GetFocus() != ea->ca.gw.hWindow )
  1272.         {
  1273.            SetFocus( ea->ca.gw.hWindow ) ;
  1274.            ea->ca.ew->ControlList.selected = (void *) &ea->ca ;
  1275.         }
  1276.             if ( ea->isModify == 0 )  return 0 ;
  1277.             SetCapture( ea->ca.gw.hWindow ) ;
  1278.             if ( ! (wParam & MK_SHIFT) )
  1279.                edit4_selectnone( ea ) ;
  1280.             edit4_posset( ea, edit4_calcpos( ea, LOWORD(lParam) ), -1 ) ;
  1281.          }
  1282.          else
  1283.          {
  1284.             if ( GetFocus() == ea->ca.gw.hWindow )
  1285.             {
  1286.                if ( ea->isModify == 0 )  return 0 ;
  1287.                SetCapture( ea->ca.gw.hWindow ) ;
  1288.                if ( ! (wParam & MK_SHIFT) )
  1289.                   edit4_selectnone( ea ) ;
  1290.                edit4_posset( ea, edit4_calcpos( ea, LOWORD(lParam) ), -1 ) ;
  1291.             }
  1292.          }
  1293.          break ;
  1294.  
  1295.       case WM_LBUTTONUP:
  1296.          if ( control4_ok( ea->ca.ew, 0 ) != 0 )  return 0 ;
  1297.          if ( ea->isModify == 0 )  return 0 ;
  1298.          if ( ea->ca.gw.hWindow != GetFocus() )  return 0 ;
  1299.          ReleaseCapture() ;
  1300.          edit4_selectto( ea, edit4_calcpos( ea, LOWORD(lParam) ) ) ;
  1301.          break ;
  1302.  
  1303.       case WM_MOUSEMOVE:                                       
  1304.          if ( wParam & MK_LBUTTON )
  1305.             if ( ea->isModify == 1 )
  1306.                edit4_selectusingmouse( ea, LOWORD(lParam) ) ;
  1307.          break ;
  1308.    }
  1309.    return 0 ;
  1310. }
  1311.  
  1312. int S4FUNCTION g4edit_refresh( G4EDIT *ea )
  1313. {
  1314.    ea->Pos = 0 ;
  1315.  
  1316.    if ( ea->combo != 0 )
  1317.    {
  1318.       combo4_setselection( ea->ca.gw.hWindow, ea->ca.ew, 1 ) ;
  1319.       return 0 ;
  1320.    }
  1321.  
  1322.    if ( ea->Buffer != 0 )
  1323.       u4free( ea->Buffer ) ;
  1324.  
  1325.    if ( ea->data_field != 0 )
  1326.       if ( f4type( ea->data_field ) == 'M' )
  1327.          if ( ea->pResult != 0 )
  1328.          {
  1329.             int len = m4len( ea->data_field ) ;
  1330.             ea->Buffer = (char *) u4alloc( len+1 ) ;
  1331.             if ( ea->Buffer == 0 )
  1332.                return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1333.             m4ncpy( ea->data_field, ea->Buffer, len+1 ) ;
  1334.             ea->MaxLen = -1 ;
  1335.             InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1336.             return 0 ;
  1337.          }
  1338.  
  1339.    if ( ea->Pict == 0 )
  1340.    {
  1341.       ea->Buffer = (char *) u4alloc( ea->pResultLen+1 ) ;
  1342.       if ( ea->Buffer == 0 )
  1343.          return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1344.       memset( ea->Buffer, ' ', ea->pResultLen+1 ) ;
  1345.       ea->Buffer[ea->pResultLen] = 0 ;
  1346.       u4ncpy( ea->Buffer, ea->pResult, ea->pResultLen+1 ) ;
  1347.    }
  1348.    else
  1349.    {              /* if no picture specified for date, use default */
  1350.       if ( ea->EntryType == t4date_str )
  1351.       {
  1352.          ea->Buffer = (char *) u4alloc( ea->PictLen+1 ) ;
  1353.          if ( ea->Buffer == 0 )
  1354.             return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1355.          memset( ea->Buffer, ' ', ea->PictLen+1 ) ;
  1356.          ea->Buffer[ea->PictLen] = 0 ;
  1357.          a4format( ea->pResult, ea->Buffer, ea->Pict ) ;
  1358.       }
  1359.       else
  1360.       {
  1361.          if ( ea->EntryType == t4num_str )
  1362.          {
  1363.             ea->Buffer = (char *) u4alloc( ea->PictLen+1 ) ;
  1364.             if ( ea->Buffer == 0 )
  1365.                return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1366.             memset( ea->Buffer, ' ', ea->PictLen ) ;
  1367.             ea->Buffer[ea->PictLen] = 0 ;
  1368.             memcpy( ea->Buffer, ea->Pict, ea->PictLen ) ;
  1369.  
  1370.             if ( ea->pResult[ea->pResultLen-1] == ' ' )
  1371.             {
  1372.                double d ;
  1373.                c4atod2( ea->pResult, ea->pResultLen, &d ) ;
  1374.                c4dtoa45( d, ea->pResult, ea->pResultLen, ea->Decimals ) ;
  1375.             }
  1376.             memcpy( ea->Buffer, ea->pResult, ea->PictLen ) ;
  1377.          }
  1378.          else
  1379.          {
  1380.             int npict = edit4_nonpictchars( ea->Pict ) ;
  1381.             ea->Buffer = (char *) u4alloc( ea->pResultLen + npict + 1 ) ;
  1382.             if ( ea->Buffer == 0 )
  1383.                return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1384.             memset( ea->Buffer, ' ', ea->pResultLen + npict + 1 ) ;
  1385.             ea->Buffer[ea->pResultLen+npict] = 0 ;
  1386.             memcpy( ea->Buffer, ea->Pict, ea->PictLen ) ;
  1387.             edit4_pictureapply( ea ) ;
  1388.             memcpy( ea->Buffer+ea->PictLen, ea->pResult+(ea->PictLen-npict), (ea->pResultLen-ea->PictLen+npict) ) ;
  1389.          }
  1390.       }
  1391.    }
  1392.  
  1393.    if ( ea->Pict != 0 )
  1394.       ea->Pos = ea->PictLen - lstrlen( strpbrk( ea->Pict, "!9#ALNXYCYDM" )) ;
  1395.  
  1396.    if ( ea->pResultLen > lstrlen( ea->Buffer ) )
  1397.       ea->MaxLen = ea->pResultLen ;
  1398.    else
  1399.       ea->MaxLen = lstrlen( ea->Buffer ) ;
  1400.  
  1401.    InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1402.    return 0 ;
  1403. }
  1404.  
  1405. int edit4_replace( G4EDIT *ea, int chr, int pos )
  1406. {                                   /* 0 - Replaced; 1 - Not Replaced */
  1407.    int l = lstrlen( ea->BufferPrev ) ;
  1408.    if ( pos >= lstrlen( ea->Buffer ) )
  1409.       return edit4_insertchar( ea, (char) chr, pos ) ;
  1410.  
  1411.    ea->Buffer[pos] = (char) chr ;
  1412.  
  1413.    if ( edit4_pictureverify( ea ) != 0 )
  1414.    {                            /* reinstate the BufferPrev ... */
  1415.       if ( ea->Buffer != 0 ) u4free( ea->Buffer ) ;
  1416.       ea->Buffer = (char *) u4alloc( l + 1 ) ;
  1417.       if ( ea->Buffer == 0 )
  1418.          return e4error( g4cb( ea ), e4memory, (char *) 0 ) ;
  1419.        memcpy( ea->Buffer, ea->BufferPrev, l + 1 ) ;
  1420.       return 1 ;
  1421.    }
  1422.  
  1423.    ea->edit_changed = 1 ;
  1424.    ea->is_valid = 0 ;
  1425.    edit4_posset( ea, edit4_posget( ea ) + 1, 1 ) ;
  1426.  
  1427.    return 0 ;
  1428. }
  1429.  
  1430. int edit4_pictureapply( G4EDIT *ea )
  1431. {
  1432.    int i, j ;
  1433.  
  1434.    for ( i=0, j=0 ; j<ea->PictLen ; i++, j++ )
  1435.    {
  1436.       if ( strrchr( "!9#ALNXYCYDM", ea->Buffer[j] ) == 0 )
  1437.          i-- ;
  1438.       else
  1439.       {
  1440.          if ( ea->Buffer[j] == '9' && ea->pResult[i] == ' ' )
  1441.             ea->Buffer[j] = '0' ;
  1442.          else
  1443.             ea->Buffer[j] = ea->pResult[i] ;
  1444.       }
  1445.    }
  1446.    if ( edit4_pictureverify( ea ) != 0 )  return 1 ;   /* no good */
  1447.    return 0 ;
  1448. }
  1449.  
  1450. int edit4_nonpictchars( char *pict )
  1451. {
  1452.    int len, i, npict = 0 ;
  1453.  
  1454.    len = lstrlen( pict ) ;
  1455.  
  1456.    for ( i = 0 ; i < len ; i++ )
  1457.    {
  1458.       switch ( pict[i] )
  1459.       {
  1460.          case '!':
  1461.          case '9':
  1462.          case '#':
  1463.          case 'A':
  1464.          case 'L':
  1465.          case 'N':
  1466.          case 'X':
  1467.          case 'Y':    /* if any 'Y', it is a legal picture character */
  1468.             break ;
  1469.  
  1470.          case 'C':
  1471.          case 'D':                       /* these must have at least 2, or it */
  1472.          case 'M':                       /* is a nonpictchar ... */
  1473.             if ( pict[i+1] != pict[i] )
  1474.             {
  1475.                npict++ ;
  1476.                i++ ;
  1477.             }
  1478.             break ;
  1479.  
  1480.          default:
  1481.             npict++ ;
  1482.       }
  1483.    }
  1484.    return npict ;
  1485. }
  1486.  
  1487. G4EDIT *edit4_create( W4ENTRY *ew, C4CONTROLITEM *control, char *text,
  1488.                                                           int low, int high )
  1489. {
  1490.    G4EDIT *ea = entry4_get_create( ew, (control->X * low)/4, (control->Y * high)/8, 
  1491.                                        text, t4str, 0, 0, control->Id ) ;
  1492.  
  1493.    MoveWindow( g4handle( ea ), (control->X * low)/4, (control->Y * high)/8,
  1494.                                (control->CX * low)/4, (control->CY * high)/8, 1 ) ;
  1495.  
  1496.    g4set_style( ea, control->Style ) ;
  1497.    g4width( ea, (control->CX * low)/4 ) ;
  1498.  
  1499.    return ea ;
  1500. }
  1501.  
  1502. void edit4_textout( G4EDIT *ea, HDC hDC, int x, int y, char *str, int count )
  1503. {
  1504.    char *upper = str ;
  1505.  
  1506.    if ( ea != 0 )
  1507.       if ( ea->isUpper == 1 )
  1508.          upper = AnsiUpper( str ) ;
  1509.  
  1510.    TextOut( hDC, x, y, upper, count ) ;
  1511. }
  1512.  
  1513. void edit4_selectall( G4EDIT *ea )
  1514. {
  1515.    ea->Pos = lstrlen( ea->Buffer ) ;
  1516.    ea->SelectAnchor = 0 ;
  1517. }
  1518.  
  1519. void S4FUNCTION g4valid_work( G4EDIT *ea, S4VALID *valid, void *valid_data )
  1520. {
  1521.    #ifdef S4DLL
  1522.       if ( ! u4ptr_equal( (void *) 0, (void *) ea->valid ))
  1523.          FreeProcInstance( (FARPROC) ea->valid ) ;
  1524.    #endif
  1525.    ea->valid = valid ;
  1526.    ea->valid_data = valid_data ;
  1527. }
  1528.  
  1529. void edit4_packnumeric( G4EDIT *ea )
  1530. {
  1531.    if ( ea->EntryType == t4num_str )
  1532.    {
  1533.       int i, j, k ;
  1534.  
  1535.       j = lstrlen( ea->Buffer ) - 1 ;
  1536.       for ( i = j ; i >= 0 ; i-- )
  1537.       {
  1538.          ea->Buffer[j] = ea->Buffer[i] ;
  1539.          if ( ea->Buffer[i] != ' ' )
  1540.             j-- ;
  1541.       }
  1542.       for ( k = 0 ; k <= j ; k++ )
  1543.          ea->Buffer[k] = ' ' ;
  1544.       InvalidateRect( ea->ca.gw.hWindow, 0, 0 ) ;
  1545.    }
  1546. }
  1547.  
  1548. long S4FUNCTION g4get_style( void *control_pointer )
  1549. {
  1550.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  1551.    return GetWindowLong( g4handle( control ), GWL_STYLE ) ;
  1552. }
  1553.  
  1554. void S4FUNCTION g4set_style( void *control_pointer, long style )
  1555.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  1556.    control->gw.Style = style ;
  1557.    SetWindowLong( g4handle( control ), GWL_STYLE, style ) ;
  1558. }
  1559.  
  1560. void edit4_caretcreate( G4EDIT *ea )
  1561. {
  1562.    DestroyCaret() ;
  1563.  
  1564.    if ( ea->ca.gw.cw->TypeOver == 1 )
  1565.       CreateCaret( ea->ca.gw.hWindow, 1, 1, w4char_height( ea->ca.ew ) ) ;
  1566.    else
  1567.       CreateCaret( ea->ca.gw.hWindow, 0, 1, w4char_height( ea->ca.ew ) ) ;
  1568. }
  1569.  
  1570. int edit4_datecheck( G4EDIT *ea )  /* return 0, okay, -1 BAD */
  1571. {
  1572.    char day[9];
  1573.    long abc ;
  1574.    int mon, d, yr, rc = 0 ;
  1575.  
  1576.    day[8] = 0 ;  memset( day, ' ', 8 ) ;
  1577.    a4init( day, ea->Buffer, ea->Pict );
  1578.    if ( strcmp( day, "        " ) == 0 )  return 0 ; /* blank date - okay */
  1579.  
  1580.    abc = a4long( day ) ;
  1581.    a4assign( day, abc ) ;
  1582.  
  1583.    mon = a4month( day ) ;
  1584.    if ( (mon < 1) || (mon > 12) )  rc = -1 ;
  1585.  
  1586.    d = a4day( day ) ;
  1587.    if ( (d < 1) || (d > 31) )  rc = -1 ;
  1588.  
  1589.    yr = a4year( day ) ;
  1590.    if ( (yr < 1) )  rc = -1 ;
  1591.  
  1592.    ea->ca.gw.cw->bad_date = ( rc != 0 ) ? 1 : 0 ;
  1593.  
  1594.    return rc ;
  1595. }
  1596.  
  1597. /*****
  1598.    Here's how the changing of focus is handled among the controls :
  1599.  
  1600.    NB    - Non Button Control
  1601.    PUSH  - Either a BS_PUSHBUTTON or a BS_DEFPUSHBUTTON
  1602.    NPUSH - A button that is not a PUSH (ie. a CHECKBOX or RADIO)
  1603.  
  1604.    different cases           action
  1605.    ------------------        ------
  1606.    1.  NB    -> NB           nothing
  1607.    2.  NB    -> PUSH         turn off default, ca = BS_DEF
  1608.    3.  NB    -> NPUSH        nothing
  1609.    4.  PUSH  -> PUSH         old = BS_PUSH, ca = BS_DEF
  1610.    5.  PUSH  -> NB           old = BS_PUSH, turn on default
  1611.    6.  PUSH  -> NPUSH        old = BS_PUSH, turn on default
  1612.    7.  NPUSH -> NPUSH        nothing
  1613.    8.  NPUSH -> NB           nothing
  1614.    9.  NPUSH -> PUSH         turn off default, ca = BS_DEF
  1615. *****/
  1616.  
  1617. G4CONTROL *edit4_new( L4LIST *list, void *item, int dir )
  1618. {
  1619.    G4BUTTON *old_but, *ca_but ;
  1620.    G4CONTROL *old, *ca1 ;
  1621.    G4CONTROL *ca = (G4CONTROL *) item ;
  1622.  
  1623.    if ( ca->area_type == c4list )
  1624.    {
  1625.       G4LIST *list = (G4LIST *)ca->area ;
  1626.       if ( list->combo != 0 )
  1627.       {
  1628.          G4COMBO *combo = (G4COMBO *) list->combo ;
  1629.          ca = &(combo->edit.ca) ;
  1630.       }
  1631.    }
  1632.    old = ca ;
  1633.  
  1634.    if ( dir > 0 )
  1635.    {
  1636.       do {
  1637.             if (ca == (G4CONTROL *) l4last( list))
  1638.                ca = 0 ;
  1639.             ca = (G4CONTROL *) l4next( list, ca ) ;
  1640.          } while( ca->area_type == c4display ) ;
  1641.    }
  1642.    else
  1643.    {
  1644.       do {
  1645.             if (ca == (G4CONTROL *) l4first( list))
  1646.                ca = 0 ;
  1647.             ca = (G4CONTROL *) l4prev( list, ca ) ;
  1648.          } while( ca->area_type == c4display ) ;
  1649.    }
  1650.  
  1651.    if ( old->area_type == c4edit )
  1652.    {
  1653.       G4COMBO *combo = (G4COMBO *) ((G4EDIT *)old->area)->combo ;
  1654.       if ( combo != 0 )
  1655.       {
  1656.          combo->is_down = 0 ;
  1657.          combo4_process_message( combo, WM_SYSKEYDOWN, VK_UP, 0x20000000L ) ;
  1658.       }
  1659.    }
  1660.  
  1661.    if ( ca->area_type == c4button )
  1662.       ca_but = (G4BUTTON *) ca->area ;
  1663.  
  1664.    if ( old->area_type != c4button )
  1665.    {
  1666.       if ( ca->area_type != c4button )
  1667.          return ca ;
  1668.       if ( (ca_but->ButtonType != BS_PUSHBUTTON) && (ca_but->ButtonType != BS_DEFPUSHBUTTON) )
  1669.          return ca ;
  1670.  
  1671.       edit4_default( list, 0 ) ;
  1672.       SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_DEFPUSHBUTTON, 1L ) ;
  1673.       return ca ;
  1674.    }
  1675.  
  1676.    old_but = (G4BUTTON *) old->area ;
  1677.    if ( (old_but->ButtonType != BS_PUSHBUTTON) && (old_but->ButtonType != BS_DEFPUSHBUTTON) )
  1678.    {
  1679.       if ( ca->area_type != c4button )
  1680.          return ca ;
  1681.       if ( (ca_but->ButtonType != BS_PUSHBUTTON) && (ca_but->ButtonType != BS_DEFPUSHBUTTON) )
  1682.          return ca ;
  1683.  
  1684.       edit4_default( list, 0 ) ;
  1685.       SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_DEFPUSHBUTTON, 1L ) ;
  1686.       return ca ;
  1687.    }
  1688.  
  1689.    if ( ca->area_type != c4button )
  1690.    {
  1691.       SendMessage( old->gw.hWindow, BM_SETSTYLE, (WORD) BS_PUSHBUTTON, 1L ) ;
  1692.       edit4_default( list, 1 ) ;
  1693.       return ca ;
  1694.    }
  1695.  
  1696.    if ( (ca_but->ButtonType != BS_PUSHBUTTON) && ( ca_but->ButtonType != BS_DEFPUSHBUTTON) )
  1697.    {
  1698.       SendMessage( old->gw.hWindow, BM_SETSTYLE, (WORD) BS_PUSHBUTTON, 1L ) ;
  1699.       edit4_default( list, 1 ) ;
  1700.       return ca ;
  1701.    }
  1702.  
  1703.    SendMessage( old->gw.hWindow, BM_SETSTYLE, (WORD) BS_PUSHBUTTON, 1L ) ;
  1704.    SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_DEFPUSHBUTTON, 1L ) ;
  1705.    return ca ;
  1706. }
  1707.  
  1708. void edit4_default( L4LIST *list, int on_off )
  1709. {
  1710.    G4CONTROL *ca ;
  1711.  
  1712.    for ( ca = 0 ; ca = (G4CONTROL *) l4next( list, ca ) ; )
  1713.       if ( ca->is_default == 1 )
  1714.       {
  1715.          if ( on_off )
  1716.             SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_DEFPUSHBUTTON, 1L ) ;
  1717.          else
  1718.             SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_PUSHBUTTON, 1L ) ;
  1719.          break ;
  1720.       }
  1721. }
  1722.