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

  1. /* w4entry.c  Edit Window 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. int entry4_process_message( W4ENTRY *ew, WORD message, WORD wParam, LONG lParam )
  11. {
  12.    HWND hwnd ;
  13.    G4CONTROL *ca ;
  14.    LPDRAWITEMSTRUCT draw ;
  15.  
  16.    switch( message )
  17.    {
  18.       case WM_COMMAND:
  19.          if ( ew->gw.cw->cb.error_code < 0 )  return 1 ;
  20.          if ( HIWORD( lParam ) == LBN_SELCHANGE )
  21.          {
  22.             G4LIST *list = g4lookup_list( ew, wParam ) ;
  23.             G4COMBO *combo ;
  24.             if ( list == 0 )  return 1 ;
  25.             combo = (G4COMBO *)list->combo ;
  26.             if ( combo != 0 )
  27.                combo4_setselection( combo->edit.ca.gw.hWindow, ew, 0 ) ;
  28.             else
  29.                list4_setselection( LOWORD( lParam ), ew ) ;
  30.             break ;
  31.          }
  32.          break ;
  33.  
  34.       case WM_KILLFOCUS:
  35.          DestroyCaret();
  36.          break ;
  37.  
  38.       case WM_SETFOCUS:
  39.          DestroyCaret();
  40.       case WM_USER:
  41.          if ( ew->gw.cw->cb.error_code < 0 )  return 1 ;
  42.          hwnd = GetFocus() ;
  43.          if ( hwnd == ew->gw.hWindow )
  44.          {
  45.             if ( ew->ControlList.selected == 0 )
  46.             {
  47.                for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  48.                   if ( ca->gw.Style & WS_TABSTOP )
  49.                   {
  50.                      #ifdef S4DEBUG  /* some types don't get the focus */
  51.                         switch( ca->area_type )
  52.                         {
  53.                            case c4button:
  54.                               if ( LOBYTE( LOWORD( ca->gw.Style )) != BS_GROUPBOX )
  55.                                  break ;
  56.                            case c4display:
  57.                                  e4error( w4cb( ew ), e4result, E4_RESULT_TA2, (char *) 0 ) ;
  58.                                  return 1 ;
  59.                         }     
  60.                      #endif
  61.                            
  62.                      SetFocus( ca->gw.hWindow ) ;
  63.                      if ( ca->area_type == c4button )
  64.                      {
  65.                         G4BUTTON *ca_but = (G4BUTTON *) ca->area ;
  66.                         if ( (ca_but->ButtonType == BS_PUSHBUTTON) ||
  67.                              (ca_but->ButtonType == BS_DEFPUSHBUTTON) )
  68.                         {
  69.                            edit4_default( &ew->ControlList, 0 ) ;
  70.                            SendMessage( ca->gw.hWindow, BM_SETSTYLE, (WORD) BS_DEFPUSHBUTTON, 1L ) ;
  71.                         }
  72.                      }
  73.                      ew->ControlList.selected = (void *) ca ;
  74.                      return 1 ;
  75.                   }
  76.                #ifdef S4DEBUG
  77.                   e4error( w4cb( ew ), e4result, E4_RESULT_TA1, (char *) 0 ) ;
  78.                   return 1 ;
  79.                #endif
  80.             }
  81.             else
  82.                SetFocus( g4handle( (G4CONTROL *) ew->ControlList.selected )) ;
  83.          }
  84.          break ;
  85.  
  86.       case WM_CLOSE:
  87.          ew->gw.IsDestroyed = 1 ;
  88.          ew->isReady = 0 ;
  89.          if ( ew->gw.hEnable != 0 )
  90.          {
  91.             EnableWindow( ew->gw.hEnable, 1 ) ;
  92.             SetActiveWindow( ew->gw.hEnable ) ;
  93.          }
  94.          break ;
  95.  
  96.       case WM_SYSCOMMAND:
  97.          if ( ew->gw.cw->cb.error_code < 0 )  return 1 ;
  98.          if ( wParam == SC_CLOSE )
  99.          {
  100.             ca = (G4CONTROL *) l4first( &ew->ControlList ) ;
  101.             if ( ca != 0 )
  102.                control4_process_message( ca, WM_CHAR, VK_ESCAPE, lParam ) ;
  103.          }
  104.          break ;
  105.  
  106.       case WM_NCDESTROY:
  107.          if ( ew->release == 1 )
  108.             entry4_free( ew ) ;
  109.          break ;
  110.  
  111.       case WM_PAINT:
  112.          if ( ew->gw.cw->cb.error_code < 0 )
  113.          {
  114.             SendMessage( ew->gw.hWindow, WM_CLOSE, 0, 0 ) ;
  115.             return 1 ;
  116.          }
  117.          if ( ew->isReady == 0 )
  118.          {
  119.             if ( ew->bw != 0 )
  120.             {
  121.                if ( d4reccount( ew->bw->pData ) < 1 )
  122.                {
  123.                   d4append_blank( ew->bw->pData ) ;
  124.                   d4top( ew->bw->pData ) ;
  125.                   ew->bw->CurRec = 1 ;
  126.                }
  127.             }
  128.             list4_setselect( ew ) ;
  129.             entry4_resizeedits( ew ) ;    
  130.             entry4_controlsrefresh( ew ) ;
  131.             PostMessage( ew->gw.hWindow, WM_USER, 0, 0 ) ;
  132.             if ( ew->bw != 0 )
  133.             {
  134.                browse4_area_create( ew ) ;
  135.                browse4_movecontrols( ew->bw, 0 ) ;
  136.                browse4_scrollset( ew->bw ) ;
  137.             }
  138.             ew->isReady = 1 ;
  139.          }
  140.          break ;
  141.  
  142.       case WM_DRAWITEM:
  143.          draw = (LPDRAWITEMSTRUCT) lParam ;
  144.          if ( draw->itemAction == ODA_DRAWENTIRE )
  145.             combo4_buttondraw( draw, ew );
  146.          break ;
  147.    }
  148.    return 0 ;
  149. }
  150.  
  151. void entry4_construct( W4ENTRY *ew )
  152. {
  153.    ew->release        =    1 ;
  154.    ew->return_code    =   -1 ;
  155.    ew->Pos            =    0 ;
  156.    ew->bw             =    0 ;
  157.    ew->max_id         = 2000 ;
  158.    ew->isReady        =    0 ;
  159.    ew->hasMessageLoop =    0 ;
  160. }
  161.  
  162. int entry4_controlsrefresh( W4ENTRY *ew )
  163. {
  164.    G4CONTROL *ca ;
  165.  
  166.    for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  167.    {
  168.       if ( ca->area_type == c4edit )
  169.          if ( ((G4EDIT *)ca->area)->pResult != 0 )
  170.             g4edit_refresh( (G4EDIT *)(ca->area) ) ;
  171.    }
  172.    return 0 ;
  173. }
  174.  
  175. int entry4_controlssave( W4ENTRY *ew )
  176. {
  177.    G4CONTROL *ca ;
  178.    int rc = 0 ;
  179.  
  180.    for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  181.    {
  182.       if ( ca->area_type == c4edit )
  183.          if ( ((G4EDIT *)(ca->area))->pResult != 0 )
  184.          {
  185.             if ( g4edit_save( (G4EDIT *)(ca->area) ) != 0 )
  186.                rc = -1 ;
  187.          }
  188.       if ( ca->area_type == c4list )
  189.          if ( ((G4LIST *)(ca->area))->pResult != 0 )
  190.             g4list_save( (G4LIST *)(ca->area) ) ;
  191.       if ( ca->area_type == c4button )
  192.          g4button_save( (G4BUTTON *)(ca->area) ) ;
  193.    }
  194.    return rc ;
  195. }
  196.  
  197. G4EDIT *entry4_get_create( W4ENTRY *ew, int x, int y, char *str,
  198.                                   int type_get, int width, int dec, int id )
  199. {
  200.    G4EDIT *ea ;
  201.  
  202.    #ifdef S4DEBUG
  203.       if ( ew == 0 )
  204.          e4severe( e4parm, "g4numeric()", E4_PARM_ZER, (void *) 0 ) ;
  205.    #endif
  206.  
  207.    if ( ew->gw.cw->cb.error_code < 0 )  return 0 ;
  208.  
  209.    ea = edit4_construct( ew ) ;
  210.    if ( ea == 0 )  return 0 ;
  211.    if ( edit4_make2( ew, ea, x, y, str, type_get, width, dec, id ) < 0 )
  212.    {
  213.       if ( ea->Pict != 0 )  u4free( ea->Pict ) ;
  214.       return 0 ;
  215.    }
  216.    l4add( &ew->ControlList, (void *) &ea->ca ) ;
  217.    return ea ;
  218. }
  219.  
  220. G4EDIT *S4FUNCTION g4text( W4ENTRY *ew, int x, int y, char *ptr, unsigned ptr_len )
  221. {
  222.    return entry4_get_create( ew, x, y, ptr, t4str, ptr_len, 0, -1 ) ;
  223. }
  224.  
  225. G4EDIT *S4FUNCTION g4date( W4ENTRY *ew, int x, int y, char *dt )
  226. {
  227.    return entry4_get_create( ew, x, y, dt, t4date_str, 8, 0, -1 ) ;
  228. }
  229.  
  230. G4EDIT *S4FUNCTION g4numeric( W4ENTRY *ew, int x, int y, char *str, int width, int dec )
  231. {
  232.    G4EDIT *ea ;
  233.    char *pict ;
  234.    double doub ;
  235.    c4atod2( str, width, &doub ) ;
  236.    c4dtoa45( doub, str, width, dec ) ;
  237.  
  238.    pict = (char *) u4alloc( width+1 ) ;
  239.    if ( pict == 0 )
  240.    {
  241.       e4error( w4cb( ew ), e4memory, "g4numeric()", (void *) 0 ) ;
  242.       return 0 ;
  243.    }
  244.    memset( pict, '#', width ) ;
  245.    memset( pict+width-dec, '9', dec ) ;
  246.    pict[width] = 0 ;
  247.    if ( dec > 0 )
  248.       pict[width-dec-1] = '.' ;
  249.    ea = entry4_get_create( ew, x, y, str, 'N', width, dec, -1 ) ;
  250.    g4picture( ea, pict ) ;
  251.    u4free( pict ) ;
  252.  
  253.    ea->EntryType = t4num_str ;
  254.  
  255.    g4set_style( ea, g4get_style( ea ) | ES_RIGHT ) ;
  256.  
  257.    ea->data_field = 0 ;
  258.    ea->pResult    = str ;
  259.    ea->pResultLen = width ;
  260.    ea->Decimals   = dec ;
  261.  
  262.    return ea ;
  263. }
  264.  
  265. G4EDIT *S4FUNCTION g4logical( W4ENTRY *ew, int x, int y, char *str )
  266. {
  267.    return entry4_get_create( ew, x, y, str, t4log, 1, 0, -1 ) ;
  268. }
  269.  
  270. void entry4_init( W4ENTRY *ew, C4WINDOWS *cw, char *class_name, char *caption, DWORD style,
  271.                   int x, int y, int width, int height, HWND parent, HMENU menu )
  272. {
  273.    memset( &ew->ControlList, 0, sizeof( ew->ControlList )) ;
  274.    entry4_construct( ew ) ;
  275.    general4_init( &ew->gw, cw, class_name, caption, style, x, y, width, height, parent, menu ) ;
  276. }
  277.  
  278. W4ENTRY *S4FUNCTION w4create( C4WINDOWS *cw, char *caption, DWORD style, int x, int y, int width,
  279.                               int height, HWND parent, HMENU menu )
  280. {
  281.    W4ENTRY *ew = (W4ENTRY *) u4alloc( sizeof( W4ENTRY )) ;
  282.    #ifdef S4DEBUG
  283.       if ( ew == 0 )
  284.       {
  285.          e4error( &cw->cb, e4parm, "w4create()", E4_PARM_ZER, (void *) 0 ) ;
  286.          return 0 ;
  287.       }
  288.    #endif
  289.  
  290.    if ( style == 0 )
  291.       style = WS_POPUPWINDOW | WS_CAPTION ;
  292.  
  293.    entry4_init( ew, cw, "W4ENTRY", caption, style, x, y, width, height, parent, menu ) ;
  294.    SetWindowLong( ew->gw.hWindow, 0, (LONG) ew ) ;
  295.    return ew ;
  296. }
  297.  
  298. G4CONTROL *S4FUNCTION g4lookup( W4ENTRY *ew, int id )
  299. {
  300.    G4CONTROL *ca ;
  301.  
  302.    #ifdef S4DEBUG
  303.       if ( ew == 0 )
  304.          e4severe( e4parm, "g4lookup()", E4_PARM_ZER, (void *) 0 ) ;
  305.    #endif
  306.  
  307.    for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  308.    {
  309.       if ( ca->area_type == c4edit )
  310.       {
  311.          G4COMBO *cba = (G4COMBO *) ((G4EDIT *)ca->area)->combo ;
  312.          if ( cba != 0 )
  313.          {
  314.             if ( cba->list != 0 )
  315.                if ( cba->list->ca.gw.Id == id )
  316.                   return &(cba->list->ca) ;
  317.             if ( cba->button != 0 )
  318.                if ( cba->button->ca.gw.Id == id )
  319.                   return &(cba->button->ca) ;
  320.          }
  321.       }
  322.       if ( ca->gw.Id == id )
  323.          return ca ;
  324.    }
  325.    #ifdef S4DEBUG
  326.       e4error( w4cb( ew ), e4parm, E4_RESULT_ID, (char *) 0 ) ;
  327.    #endif
  328.    return (G4CONTROL *) 0 ;
  329. }
  330.  
  331. G4BUTTON *S4FUNCTION g4lookup_button( W4ENTRY *ew, int id )
  332. {
  333.    G4CONTROL *ca = g4lookup( ew, id ) ;
  334.    if ( ca == 0 )  return 0 ;
  335.  
  336.    #ifdef S4DEBUG
  337.       if ( ca->area_type != c4button )
  338.          e4error( w4cb( ew ), e4parm, E4_RESULT_IDB, (char *) 0 ) ;
  339.    #endif
  340.    return (G4BUTTON *) ca->area ;
  341. }
  342.  
  343. G4DISPLAY *S4FUNCTION g4lookup_display( W4ENTRY *ew, int id )
  344. {
  345.    G4CONTROL *ca = g4lookup( ew, id ) ;
  346.    if ( ca == 0 )  return 0 ;
  347.  
  348.    #ifdef S4DEBUG
  349.       if ( ca->area_type != c4display )
  350.          e4error( w4cb( ew ), e4parm, E4_RESULT_IDD, (char *) 0 ) ;
  351.    #endif
  352.    return (G4DISPLAY *) ca->area ;
  353. }
  354.  
  355. G4LIST *S4FUNCTION g4lookup_list( W4ENTRY *ew, int id )
  356. {
  357.    G4CONTROL *ca = g4lookup( ew, id ) ;
  358.    if ( ca == 0 )  return 0 ;
  359.  
  360.    #ifdef S4DEBUG
  361.       if ( ca->area_type != c4list )
  362.          e4error( w4cb( ew ), e4parm, E4_RESULT_IDL, (char *) 0 ) ;
  363.    #endif
  364.    return (G4LIST *) ca->area ;
  365. }
  366.  
  367. G4EDIT *S4FUNCTION g4lookup_edit( W4ENTRY *ew, int id )
  368. {
  369.    G4CONTROL *ca = g4lookup( ew, id ) ;
  370.    if ( ca == 0 )  return 0 ;
  371.  
  372.    #ifdef S4DEBUG
  373.       if ( ca->area_type != c4edit )
  374.          e4error( w4cb( ew ), e4parm, E4_RESULT_IDT, (char *) 0 ) ;
  375.    #endif
  376.    return (G4EDIT *) ca->area ;
  377. }
  378.  
  379. G4COMBO *S4FUNCTION g4lookup_combo( W4ENTRY *ew, int id )
  380. {
  381.    G4CONTROL *ca = g4lookup( ew, id ) ;
  382.    G4EDIT    *ea ;
  383.  
  384.    if ( ca == 0 )  return 0 ;
  385.    ea = (G4EDIT *) ca->area ;
  386.  
  387.    #ifdef S4DEBUG
  388.       if ( ea->combo == 0 )
  389.          e4error( w4cb( ew ), e4parm, E4_RESULT_IDC, (char *) 0 ) ;
  390.    #endif
  391.    return (G4COMBO *) ea->combo ;
  392. }
  393.  
  394. int S4FUNCTION g4read( W4ENTRY *ew, HWND hDisableWindow )
  395. {
  396.    int return_code ;
  397.    G4CONTROL *ca ;
  398.  
  399.    if ( ew->gw.cw->cb.error_code < 0 )  return -1 ;
  400.  
  401.    #ifdef S4DEBUG
  402.       for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  403.       {
  404.          G4LIST *list = 0 ;
  405.          int len, count, i ;
  406.  
  407.          switch( ca->area_type )
  408.          {
  409.             case c4display:
  410.                if ( ((G4DISPLAY *)ca->area)->text_len == 0 )
  411.                   return e4error( w4cb( ew ), e4result, E4_RESULT_G4D, (char *) 0 ) ;
  412.                break ;
  413.  
  414.             case c4edit:
  415.                if ( ((G4EDIT *)ca->area)->pResultLen == 0 )
  416.                   return e4error( w4cb( ew ), e4result, E4_RESULT_G4E, (char *) 0 ) ;
  417.                break ;
  418.  
  419.             case c4list:
  420.                if ( ((G4LIST *)ca->area)->pResultLen == 0 )
  421.                   return e4error( w4cb( ew ), e4result, E4_RESULT_G4L, (char *) 0 ) ;
  422.                break ;
  423.  
  424.             default:
  425.                break ;
  426.          }
  427. /*                                        not currently working ...
  428.          if ( ca->area_type == c4edit )
  429.          {
  430.             G4EDIT *ea = (G4EDIT *) ca->area ;
  431.             if ( ea->combo != 0 )
  432.                list = ea->combo->list ;
  433.          }
  434.          if ( ca->area_type == c4list )
  435.             list = (G4LIST *) ca->area ;
  436.          if ( list != 0 )
  437.          {
  438.             count = SendMessage( g4handle( list ), LB_GETCOUNT, 0, 0 ) ;
  439.             for ( i=0 ; i<count ; i++ )
  440.             {
  441.                len = SendMessage( g4handle( list ), LB_GETTEXTLEN, i, 0 ) ;
  442.                if ( len > list->pResultLen )
  443.                   return e4error( w4cb( ew ), e4result, E4_RESULT_BUF, (char *) 0 ) ;
  444.             }
  445.          }
  446. */
  447.       }
  448.    #endif
  449.  
  450.    SetActiveWindow( ew->gw.hWindow ) ;
  451.    ShowWindow( ew->gw.hWindow,SW_SHOWNORMAL ) ;
  452.    UpdateWindow( ew->gw.hWindow ) ;
  453.  
  454.    ew->hasMessageLoop = 1 ;
  455.    general4_read( &ew->gw, hDisableWindow ) ;
  456.    return_code = ew->return_code ;
  457.  
  458.    ew->gw.IsDestroyed = 0 ;
  459.    g4release( ew, ew->release ) ;
  460.  
  461.    return return_code ;
  462. }
  463.  
  464. int entry4_readstring( char* str, H4SEQ_READ *seq, int nOption )
  465. {
  466.    int i ;
  467.    char ch[2] ;  ch[0] = ch[1] = 0 ;
  468.  
  469.    h4seq_read( seq, ch, 1 ) ;
  470.  
  471.    if ( (unsigned)(ch[0]) >= 0x80 )
  472.       return (int) (unsigned char) ch[0] ;
  473.  
  474.    for (i=0 ; ch[0] != 0; i++, h4seq_read( seq, ch, 1 ) )
  475.       str[i] = ch[0] ;
  476.  
  477.    str[i] = 0 ;
  478.    return 0 ;
  479. }
  480.  
  481. W4ENTRY *S4FUNCTION w4create_dialog( C4WINDOWS *cw, HWND hPar, char *DlgName )
  482. {
  483.    return (W4ENTRY *) entry4_init_dialog( cw, hPar, DlgName, c4entrywin, 0 ) ;
  484. }
  485.  
  486. void *entry4_init_dialog( C4WINDOWS *cw, HWND hPar, char *DlgName,
  487.                           int win_type, int do_browse )
  488. {
  489.    H4FILE res ;
  490.    HANDLE hDlg ;
  491.    H4SEQ_READ seq_read ;
  492.    C4DIALOGINFO info ;
  493.    char buf[1024], menu_name[256], class_name[256], caption[256] ;
  494.    HMENU hMenu = 0 ;
  495.    long base_units, offset ;
  496.    W4ENTRY *ew ;
  497.    int i, low, high, extra_y = 0, extra_x = 0 ;
  498.    char *name = { "Dialog Resource" } ;
  499.  
  500.    res.code_base = &cw->cb ;
  501.    res.hand = -1 ;
  502.    res.is_temp = 0 ;
  503.  
  504.    hDlg = FindResource( w4hInst( cw ), DlgName, RT_DIALOG ) ;
  505.    if ( hDlg == 0 )
  506.    {
  507.       e4error( &cw->cb, e4result, E4_RESULT_RES, (char *) 0 ) ;
  508.       return 0 ;
  509.    }
  510.    res.hand = AccessResource( w4hInst( cw ), hDlg ) ;
  511.    res.name = name ;
  512.  
  513.    offset = _llseek( res.hand, 0L, 1 ) ;
  514.  
  515.    h4seq_read_init( &seq_read, &res, offset, buf, sizeof(buf) ) ;
  516.    h4seq_read( &seq_read, &info, sizeof(info) ) ;
  517.    if ( cw->cb.error_code < 0 )  return 0 ;
  518.  
  519.    menu_name[255] = class_name[255] = caption[255] = 0 ;
  520.  
  521.    entry4_readstring( menu_name,  &seq_read, 3 ) ;
  522.    entry4_readstring( class_name, &seq_read, 0 ) ;
  523.    entry4_readstring( caption,    &seq_read, 0 ) ;
  524.  
  525.    if ( lstrlen(menu_name) > 0 )
  526.       hMenu = LoadMenu( w4hInst( cw ), menu_name ) ;
  527.  
  528.    if ( hMenu == 0 )
  529.       if ( win_type == c4browsewin )
  530.          extra_y += GetSystemMetrics( SM_CYMENU ) ;
  531.  
  532.    if ( (char *) caption != 0 )
  533.       extra_y += GetSystemMetrics( SM_CYCAPTION ) ;
  534.  
  535. /* depending on the frame used, add a certain width/height, these include :
  536.    WS_THICKFRAME, WS_DLGFRAME, sizeable and nonsizeable frames ...
  537.    For now, assume a sizeable frame ... */
  538.  
  539.    extra_y += 2 * GetSystemMetrics( SM_CYFRAME ) ;
  540.    extra_x += 2 * GetSystemMetrics( SM_CXFRAME ) ;
  541.  
  542. /* note that if the menu line is multiple line, then the user defined window
  543.    may be obstructed, similarly, the horizontal and vertical scroll bars are
  544.    made within the window, so the user should take that into account when
  545.    sizing the window in the resource editor. */
  546.  
  547.    base_units = GetDialogBaseUnits() ;
  548.    low  = LOWORD( base_units ) ;
  549.    high = HIWORD( base_units ) ;
  550.  
  551.    if ( win_type == c4entrywin )
  552.       ew = w4create( cw, caption, info.Style,
  553.                      (info.X  * low ) / 4,
  554.                      (info.Y  * high) / 8,
  555.                      ((info.CX * low ) / 4)+extra_x,
  556.                      ((info.CY * high) / 8)+extra_y, hPar, hMenu ) ;
  557.    else
  558.    {
  559.       ew = b4create( cw, caption, info.Style,
  560.                      (info.X  * low ) / 4,
  561.                      (info.Y  * high) / 8,
  562.                      ((info.CX * low ) / 4)+extra_x,
  563.                      ((info.CY * high) / 8)+extra_y, hPar, 0, do_browse ) ;
  564.    }
  565.  
  566.    if ( ew == 0 )  return 0 ;
  567.  
  568.    if ( DS_SETFONT & info.Style )         /* doesn't currently work */
  569.    {
  570.       short point_size  ;
  571.       char type_face[256] ;
  572.  
  573.       h4seq_read( &seq_read, &point_size, sizeof(point_size) ) ;
  574.       type_face[255] = 0 ;
  575.       entry4_readstring( type_face, &seq_read, 0 ) ;
  576.    }
  577.  
  578.    for( i = 0; i < (int) info.ItemCount; i++)
  579.    {
  580.       int iClass ;
  581.       C4CONTROLITEM control ;
  582.       char sClass[256], text[256], more_info[256] ;
  583.       G4COMBO *cba = 0 ;
  584.  
  585.       sClass[255] = text[255] = more_info[255] = 0 ;
  586.       
  587.       h4seq_read( &seq_read, &control, sizeof(control) ) ;
  588.       iClass = entry4_readstring( sClass, &seq_read, 1 ) ;
  589.       entry4_readstring( text, &seq_read, 3 ) ;
  590.       entry4_readstring( more_info, &seq_read, 0 ) ;
  591.  
  592.       if ( control.Id > ew->max_id )
  593.          ew->max_id = control.Id + 1 ;
  594.  
  595.       switch ( iClass )
  596.       {
  597.          case 0x80:  /* Button */
  598.             button4_create( ew, &control, text, low, high ) ;
  599.             break ;
  600.  
  601.          case 0x81:  /* Edit */
  602.             edit4_create( ew, &control, text, low, high ) ;
  603.             break ;
  604.  
  605.          case 0x82:  /* Static */
  606.             display4_create( ew, &control, text, lstrlen(text), low, high ) ;
  607.             break ;
  608.  
  609.          case 0x83:  /* ListBox */
  610.             list4_create( ew, &control, text, low, high ) ;
  611.             break ;
  612.  
  613.          case 0x85:  /* ComboBox */
  614.             cba = combo4_create( ew, &control, text, lstrlen(text), low, high ) ;
  615.  
  616.             if ( CBS_DROPDOWNLIST == (control.Style & CBS_DROPDOWNLIST) )
  617.                g4modify( &cba->edit, 0 ) ;
  618.             else
  619.                g4modify( &cba->edit, 1 ) ;
  620.  
  621.             if ( CBS_SIMPLE == (control.Style & CBS_SIMPLE) )
  622.                if ( control.Style+1 & 0x0002 )
  623.                   g4combo_simple( cba ) ;
  624.  
  625.             break ;
  626.       }
  627.    }
  628.    _lclose( res.hand ) ;
  629.    res.hand = -1 ;
  630.  
  631.    if ( win_type == c4entrywin )
  632.       return ew ;
  633.    else
  634.       return ew->bw ;
  635. }
  636.  
  637. int S4FUNCTION g4width( G4EDIT *ea, int n_pixels )
  638. {
  639.    #ifdef S4DEBUG
  640.       if ( ea == 0 )
  641.          e4severe( e4parm, "g4width()", E4_PARM_ZER, (void *) 0 ) ;
  642.    #endif
  643.  
  644.    if ( ea->ca.gw.cw->cb.error_code < 0 )  return -1 ;
  645.  
  646.    ea->width = n_pixels ;
  647.    return ea->width ;
  648. }
  649.  
  650. int entry4_resizeedits( W4ENTRY *ew )
  651. {
  652.    int width, height_pix ;
  653.    G4CONTROL *ca ;
  654.    TEXTMETRIC tm ;
  655.    G4EDIT *ea ;
  656.    HDC hDC ;
  657.  
  658.    for ( ca = 0 ; ca = (G4CONTROL *) l4next( &ew->ControlList, ca ) ; )
  659.       if ( ca->area_type == c4edit )
  660.       {
  661.          ea = (G4EDIT *)(ca->area) ;
  662.          hDC = w4get_dc( w4cb( ew ), ea->ca.gw.hWindow ) ;
  663.          if ( hDC == 0 )  return -1 ;
  664.  
  665.          w4get_metrics( hDC, &tm ) ;
  666.  
  667.          if ( ea->width > 0 )
  668.             width = ea->width ;
  669.          else
  670.          {
  671.             if ( ea->Pict == 0 )
  672.                width = ea->pResultLen ;
  673.             else
  674.                width = ea->pResultLen + edit4_nonpictchars( ea->Pict ) ;
  675.             width = width * ( 1+tm.tmAveCharWidth ) ;
  676.          }
  677.  
  678.          if ( width <= tm.tmMaxCharWidth )
  679.             ea->width = width = tm.tmMaxCharWidth + ea->Margin ;
  680.  
  681.          height_pix = tm.tmHeight + tm.tmInternalLeading ;
  682.  
  683.          if ( w4release_dc( w4cb( ew ), ea->ca.gw.hWindow, hDC ) == 0 )
  684.             return -1 ;
  685.  
  686.          MoveWindow( ea->ca.gw.hWindow, ea->x, ea->y, width, height_pix, 0 ) ;
  687.       }
  688.    return 0 ;
  689. }
  690.  
  691. void S4FUNCTION g4set_buffer( G4EDIT *ea, char *buf, unsigned buf_len )
  692. {
  693.    #ifdef S4DEBUG
  694.       if ( ea == 0 )
  695.          e4severe( e4parm, "g4set_buffer()", E4_PARM_ZER, (void *) 0 ) ;
  696.    #endif
  697.  
  698.    if ( ea->ca.gw.cw->cb.error_code < 0 )  return ;
  699.  
  700.    ea->pResult    = buf ;
  701.    ea->pResultLen = buf_len ;
  702.    ea->data_field = 0 ;
  703. }
  704.  
  705. int S4FUNCTION g4set_field( G4EDIT *ea, F4FIELD *fld_ptr )
  706. {
  707.    int type_get ;
  708.  
  709.    #ifdef S4DEBUG
  710.       if ( (ea == 0) || (fld_ptr == 0) )
  711.          e4severe( e4parm, "g4set_field()", E4_PARM_ZER, (void *) 0 ) ;
  712.    #endif
  713.  
  714.    if ( ea->ca.gw.cw->cb.error_code < 0 )  return -1 ;
  715.  
  716.    ea->data_field = fld_ptr ;
  717.    ea->pResult    = f4ptr( fld_ptr ) ;
  718.    ea->pResultLen = f4len( fld_ptr ) ;
  719.    ea->Decimals   = f4decimals( fld_ptr ) ;
  720.  
  721.    switch( f4type( fld_ptr ) )
  722.    {
  723.       case 'C':
  724.       case 'M':
  725.          type_get = t4str ;
  726.          break ;
  727.  
  728.       case 'D':
  729.          type_get = t4date_str ;
  730.          break ;
  731.  
  732.       case 'L':
  733.          type_get = t4log ;
  734.          break ;
  735.  
  736.       case 'N':
  737.       case 'F':
  738.          type_get = t4num_str ;
  739.          g4set_style( ea, g4get_style( ea ) | ES_RIGHT ) ;
  740.          break ;
  741.    }
  742.    return edit4_init( ea, ea->x, ea->y, ea->pResult, type_get, ea->pResultLen,
  743.                                                                ea->Decimals ) ;
  744. }
  745.  
  746. int S4FUNCTION g4field_id( W4ENTRY *ew, int id, F4FIELD *fld )
  747. {
  748.    G4EDIT *ea;
  749.    int type_get ;
  750.  
  751.    #ifdef S4DEBUG
  752.       if ( ew == 0 )
  753.          e4severe( e4parm, "g4field_id()", E4_PARM_ZER, (void *) 0 ) ;
  754.    #endif
  755.  
  756.    if ( ew->gw.cw->cb.error_code < 0 )  return -1 ;
  757.  
  758.    ea = g4lookup_edit( ew, id ) ;
  759.    return g4set_field( ea, fld ) ;
  760. }
  761.  
  762. G4EDIT *S4FUNCTION g4field( W4ENTRY *ew, int x, int y, F4FIELD *fld )
  763. {
  764.    G4EDIT *ea ;
  765.    int type_get ;
  766.  
  767.    #ifdef S4DEBUG
  768.       if ( ew == 0 )
  769.          e4severe( e4parm, "g4field()", E4_PARM_ZER, (void *) 0 ) ;
  770.    #endif
  771.  
  772.    if ( ew->gw.cw->cb.error_code < 0 )  return 0 ;
  773.  
  774.    switch( f4type( fld ) )
  775.    {
  776.       case 'C':
  777.       case 'M':
  778.          type_get = t4str ;
  779.          break ;
  780.  
  781.       case 'D':
  782.          type_get = t4date_str ;
  783.          break ;
  784.  
  785.       case 'L':
  786.          type_get = t4log ;
  787.          break ;
  788.  
  789.       case 'N':
  790.       case 'F':
  791.          type_get = t4num_str ;
  792.          break ;
  793.    }
  794.  
  795.    ea = entry4_get_create( ew, x, y, f4ptr( fld ), type_get,
  796.                                      f4len( fld ), f4decimals( fld ), -1 ) ;
  797.    g4set_field( ea, fld ) ;
  798.    return ea ;
  799. }
  800.  
  801. void S4FUNCTION g4upper( G4EDIT *ea )
  802. {
  803.    #ifdef S4DEBUG
  804.       if ( ea == 0 )
  805.          e4severe( e4parm, "g4upper()", E4_PARM_ZER, (void *) 0 ) ;
  806.    #endif
  807.  
  808.    ea->isUpper = 1 ;   
  809. }
  810.  
  811. int S4FUNCTION w4char_width( W4ENTRY *ew )
  812. {
  813.    int width ;
  814.    TEXTMETRIC tm ;
  815.    HDC hDC ;
  816.  
  817.    #ifdef S4DEBUG
  818.       if ( ew == 0 )
  819.          e4severe( e4parm, "w4char_width()", E4_PARM_ZER, (void *) 0 ) ;
  820.    #endif
  821.  
  822.    if ( ew->gw.cw->cb.error_code < 0 )  return -1 ;
  823.  
  824.    hDC = w4get_dc( w4cb( ew ), ew->gw.hWindow ) ;
  825.    if ( hDC == 0 )  return -1 ;
  826.  
  827.    w4get_metrics( hDC, &tm ) ;
  828.    width = tm.tmAveCharWidth ;
  829.  
  830.    if ( w4release_dc( w4cb( ew ), ew->gw.hWindow, hDC ) == 0 )  return -1 ;
  831.  
  832.    return width ;
  833. }
  834.  
  835. int S4FUNCTION w4char_height( W4ENTRY *ew )
  836. {
  837.    int height ;
  838.    TEXTMETRIC tm ;
  839.    HDC hDC ;
  840.  
  841.    #ifdef S4DEBUG
  842.       if ( ew == 0 )
  843.          e4severe( e4parm, "w4char_height()", E4_PARM_ZER, (void *) 0 ) ;
  844.    #endif
  845.  
  846.    if ( ew->gw.cw->cb.error_code < 0 )  return -1 ;
  847.  
  848.    hDC = w4get_dc( w4cb( ew ), ew->gw.hWindow ) ;
  849.    if ( hDC == 0 )  return -1 ;
  850.  
  851.    w4get_metrics( hDC, &tm ) ;
  852.    height = tm.tmHeight + tm.tmExternalLeading ;
  853.  
  854.    if ( w4release_dc( w4cb( ew ), ew->gw.hWindow, hDC ) == 0 )  return -1 ;
  855.  
  856.    return height ;
  857. }
  858.  
  859. int entry4_nextid( W4ENTRY *ew )
  860. {
  861.    ew->max_id++ ;
  862.    return ew->max_id-1 ;
  863. }
  864.  
  865. void entry4_free( W4ENTRY *ew )
  866. {
  867.    B4AREA *ba ;
  868.    G4CONTROL *ca ;
  869.    int n_links ;
  870.  
  871.    for ( n_links = (&ew->ControlList)->n_link ; n_links > 0 ; n_links-- )
  872.    {
  873.       ca = (G4CONTROL *) l4pop( &ew->ControlList ) ;
  874.  
  875.       switch ( ca->area_type )
  876.       {
  877.          case c4edit:
  878.             if ( ((G4EDIT *) ca->area)->combo != 0 )
  879.                combo4_free( (G4COMBO *) ((G4EDIT *) ca->area)->combo ) ;
  880.             else
  881.                edit4_free( (G4EDIT *) ca->area ) ;
  882.             break ;
  883.  
  884.          case c4list:
  885.             list4_free( (G4LIST *) ca->area ) ;
  886.             break ;
  887.  
  888.          case c4button:
  889.             button4_free( (G4BUTTON *) ca->area ) ;
  890.             break ;
  891.       }
  892.    }
  893.    if ( ew->bw != 0 )
  894.    {
  895.       for ( n_links = (&ew->bw->BrowseList)->n_link ; n_links > 0 ; n_links-- )
  896.       {
  897.          ba = (B4AREA *) l4pop( &ew->bw->BrowseList ) ;
  898.          u4free( ba ) ;
  899.       }
  900.       #ifdef __DLL__
  901.          if ( ! u4ptr_equal( (void *) 0, (void *) ew->bw->del ) )
  902.          {
  903.             FreeProcInstance( (FARPROC) ew->bw->del ) ;
  904.             ew->bw->del = 0 ;
  905.          }
  906.          if ( ! u4ptr_equal( (void *) 0, (void *) ew->bw->record ) )
  907.          {
  908.             FreeProcInstance( (FARPROC) ew->bw->record ) ;
  909.             ew->bw->record = 0 ;
  910.          }
  911.       #endif
  912.    }
  913.    if ( ew->hasMessageLoop == 0 )
  914.    {
  915.       if ( ew->bw != 0 )
  916.          u4free( ew->bw ) ;
  917.       else
  918.          u4free( ew ) ;
  919.    }
  920.    else
  921.       ew->hasMessageLoop = 0 ;
  922. }
  923.  
  924. void edit4_free( G4EDIT *ea )
  925. {
  926.    if ( ea->Pict != 0 )        u4free( ea->Pict ) ;
  927.    if ( ea->Buffer != 0 )      u4free( ea->Buffer ) ;
  928.    if ( ea->BufferPrev != 0 )  u4free( ea->BufferPrev ) ;
  929.  
  930.    #ifdef __DLL__
  931.       if ( ! u4ptr_equal( (void *) 0, (void *) ea->valid ) )
  932.          FreeProcInstance( (FARPROC) ea->valid ) ;
  933.    #endif
  934.  
  935.    u4free( ea ) ;
  936. }
  937.  
  938. void list4_free( G4LIST *la )
  939. {
  940.    if ( la->select != 0 )  u4free( la->select ) ;
  941.    if ( la->pStr != 0 )    u4free( la->pStr ) ;
  942.  
  943.    u4free( la ) ;
  944. }
  945.  
  946. void button4_free( G4BUTTON *bna )
  947. {
  948.    if ( bna != 0 )
  949.    {
  950.       #ifdef __DLL__
  951.          if ( bna->internal == 0 )
  952.             if ( ! u4ptr_equal( (void *) 0, (void *) bna->routine ) )
  953.                FreeProcInstance( (FARPROC) bna->routine ) ;
  954.       #endif
  955.       u4free( bna ) ;
  956.    }
  957. }
  958.  
  959. void combo4_free( G4COMBO *cba )
  960. {
  961.    list4_free( cba->list ) ;
  962.    button4_free( cba->button ) ;
  963.  
  964.    u4free( cba ) ;
  965. }
  966.  
  967. HWND S4FUNCTION w4handle( W4ENTRY *entry )
  968. {
  969.    #ifdef S4DEBUG
  970.       if ( entry == 0 )
  971.          e4severe( e4parm, "w4handle()", E4_PARM_ZER, (void *) 0 ) ;
  972.    #endif
  973.  
  974.    return entry->gw.hWindow ;
  975. }
  976.  
  977. HWND S4FUNCTION g4handle( void *control_pointer )
  978. {
  979.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  980.    #ifdef S4DEBUG
  981.       if ( control == 0 )
  982.          e4severe( e4parm, "g4handle()", E4_PARM_ZER, (void *) 0 ) ;
  983.    #endif
  984.    return control->gw.hWindow ;
  985. }
  986.  
  987. int S4FUNCTION g4id( void *control_pointer )
  988. {
  989.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  990.    #ifdef S4DEBUG
  991.       if ( control == 0 )
  992.          e4severe( e4parm, "g4id()", E4_PARM_ZER, (void *) 0 ) ;
  993.    #endif
  994.    return control->gw.Id ;
  995. }
  996.  
  997. W4ENTRY *S4FUNCTION w4entry( void *control_pointer )
  998. {
  999.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  1000.    #ifdef S4DEBUG
  1001.       if ( control == 0 )
  1002.          e4severe( e4parm, "w4entry()", E4_PARM_ZER, (void *) 0 ) ;
  1003.    #endif
  1004.    return control->ew ;
  1005. }
  1006.  
  1007. void S4FUNCTION g4modify( G4EDIT *edit, int can_modify )
  1008. {
  1009.    #ifdef S4DEBUG
  1010.       if ( edit == 0 )
  1011.          e4severe( e4parm, "g4modify()", E4_PARM_ZER, (void *) 0 ) ;
  1012.    #endif
  1013.    edit->isModify = can_modify ;
  1014. }
  1015.  
  1016. HANDLE S4FUNCTION w4hInst( void *ptr )
  1017. {
  1018.    C4CODE *cb = (C4CODE *) ptr ;
  1019.    #ifdef S4DEBUG
  1020.       if ( cb == 0 )
  1021.          e4severe( e4parm, "w4hInst()", E4_PARM_ZER, (void *) 0 ) ;
  1022.    #endif
  1023.    return cb->hInst ;
  1024. }
  1025.  
  1026. HANDLE S4FUNCTION g4hInst( void *control_pointer )
  1027. {
  1028.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  1029.    #ifdef S4DEBUG
  1030.       if ( control == 0 )
  1031.          e4severe( e4parm, "g4hInst()", E4_PARM_ZER, (void *) 0 ) ;
  1032.    #endif
  1033.    return control->gw.cw->cb.hInst ;
  1034. }
  1035.  
  1036. C4CODE *S4FUNCTION w4cb( W4ENTRY *ew )
  1037. {
  1038.    #ifdef S4DEBUG
  1039.       if ( ew == 0 )
  1040.          e4severe( e4parm, "w4cb()", E4_PARM_ZER, (void *) 0 ) ;
  1041.    #endif
  1042.    return &ew->gw.cw->cb ;
  1043. }
  1044.  
  1045. C4CODE *S4FUNCTION g4cb( void *control_pointer )
  1046. {
  1047.    G4CONTROL *control = (G4CONTROL *) control_pointer ;
  1048.    #ifdef S4DEBUG
  1049.       if ( control == 0 )
  1050.          e4severe( e4parm, "g4cb()", E4_PARM_ZER, (void *) 0 ) ;
  1051.    #endif
  1052.    return &control->gw.cw->cb ;
  1053. }
  1054.  
  1055. int S4FUNCTION g4release( W4ENTRY *ew, int do_release )
  1056. {
  1057.    ew->release = do_release ;
  1058.    if ( do_release )
  1059.    {
  1060.       DestroyWindow( ew->gw.hWindow ) ;
  1061.       entry4_free( ew ) ;
  1062.    }
  1063.    return 0 ;                     /* return error if in S4DEBUG ... */
  1064. }
  1065.