BUG: LCK _FindVar() Function Doesn't Work w/ Other Work Areas

ID: Q123206

The information in this article applies to:

SYMPTOMS

The Library Construction Kit (LCK) _FindVar() function returns incorrect results if the second parameter of the LCK _FindVar() function is specified to be a work-area number other than the currently selected work area.

WORKAROUND

Use the LCK _Execute() function to select the work area and then use _FindVar() function to find the value of the field in the selected work area. The code in the More Information section demonstrates this workaround.

STATUS

Microsoft has confirmed this to be a problem in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

The LCK _FindVar() function provides a way to initialize the Locator structure with information about a variable or field. The _FindVar() function has three parameters:

   int _FindVar(NTI nti, int where, Locator FAR *loc)

Parameters:

FoxPro and C Sample Code to Demonstrate Workaround

/* Date:  09/08/94
   Purpose: To pass the work area number and the field name to the
   function XREAD and return the corresponding value.

   FoxPro Code:

     CLEAR
     SELECT 1
     USE customer
     SELECT 2
     USE invoices
     SELECT 1

     SET LIBRARY TO test.dll     && This is the name of .dll
                                 && created by this C program.
     =XREAD(2,"itotal")
     SET LIBRARY TO

     CLOSE ALL
*/

#include <pro_ext.h>
#include <stdlib.h>
#include <string.h>

void FAR readfield(ParamBlk FAR *parm)
{
     long int work_area;
     NTI nti;
     char FAR * field_name;
     Locator loc;
     Value val;

     char FAR *select_cmd="SELECT ";
     Value current_wa;     /* used to store current work area */
     long int c_wa;
     char buffer[4];

     if (parm->p[0].val.ev_type='I')
        work_area=parm->p[0].val.ev_long;

     if (parm->p[1].val.ev_type='C')
          {
           //Null terminate character string that has field name.
           if (!_SetHandSize(parm->p[1].val.ev_handle,parm->
                      p[1].val.ev_length+1))
           {
                 _Error(182);   //Insufficient Memory
           }

           _HLock(parm->p[1].val.ev_handle);
           field_name=(char FAR *)_HandToPtr(parm->
                         p[1].val.ev_handle);
           field_name[parm->p[1].val.ev_length]='\0';


           // Display string Value
           _PutStr("Field Name: ");
           _PutStr(field_name);
           //Carrage Return and Line Feed
           _PutChr(13);
           _PutChr(10);

           /* Store current work area. */
             _Evaluate(&current_wa,"select(alias())");
             c_wa=current_wa.ev_long;

             _PutStr("Current Work Area: ");
             _PutChr(c_wa+48);  /* In our test workarea < 3 */
             _PutStr("\n");

             strcat(select_cmd,_itoa((int)work_area,buffer,10));
             _PutStr("Select Command: ");
             _PutStr(select_cmd);
             _PutStr("\n");
             _Execute(select_cmd);

             _StrCpy(select_cmd,"SELECT ");  /* Reset Select
                                                Command */

             nti=_NameTableIndex(field_name);
             if(nti == -1)
             {
              _HUnLock(parm->p[1].val.ev_handle);
              _UserError("Cannot find variable in named table.");
           }

           if (_FindVar(nti,0,&loc))
           {
              _Load(&loc,&val);

              //Display value returned by _FindVar()
              _PutStr("Value Returned by _FindVar()   : ");
              _PutValue(&val);
           }
             else
           {
            _PutStr("\nVariable does not exist!!!!");
           }

             /* Return to the previously selected work area. */
             strcat(select_cmd,_itoa((int)c_wa,buffer,10));
             _Execute(select_cmd);

           //Unlock Handle - send address back to heap
           _HUnLock(parm->p[1].val.ev_handle);
        }
}

/* First parameter is the Work Area Number
   Second parameter is the Field Name
*/

FoxInfo myFoxInfo[]={
 {"XREAD",(FPFI)readfield,2,"I,C"},
};

FoxTable _FoxTable={

 (FoxTable FAR *)0,sizeof(myFoxInfo)/sizeof(FoxInfo),myFoxInfo
};

FoxPro and C Sample Code to Reproduce Problem

/*  Purpose: To pass the work area number and the field name to the
    function XREAD and return the corresponding value

FoxPro Code:

  CLEAR
  SELECT 1
  USE customer
  SELECT 2
  USE invoices
  SELECT 1

  SET LIBRARY TO test.dll   && Where test is the name of this C
                            && program when compiled.
  =XREAD(2,"itotal")
  SET LIBRARY TO

  CLOSE ALL


*/


#include <pro_ext.h>

void FAR readfield(ParamBlk FAR *parm)
{
   long int work_area;
   NTI nti;
   char FAR * field_name;
   Locator loc;
   Value val;

   if (parm->p[0].val.ev_type='I')
      work_area=parm->p[0].val.ev_long;

   if (parm->p[1].val.ev_type='C')
   {
    //Null terminate character string that has field name.
    if (!_SetHandSize(parm->p[1].val.ev_handle,parm->
          p[1].val.ev_length+1))
    {
         _Error(182);   //Insufficient Memory
    }

    _HLock(parm->p[1].val.ev_handle);
    field_name=(char FAR *)_HandToPtr(parm->p[1].val.ev_handle);
      field_name[parm->p[1].val.ev_length]='\0';

      // Display string Value
    _PutStr("Field Name: ");
    _PutStr(field_name);

    //Carrage Return and Line Feed
    _PutChr(13);
    _PutChr(10);

    nti=_NameTableIndex(field_name);
    if(nti == -1)
    {
         _HUnLock(parm->p[1].val.ev_handle);
         _UserError("Cannot find variable in named table.");
    }

    //Display number returned by nti
    _PutStr(" A Value Was Returned by _NameTableIndex().");
    _PutChr(13);
    _PutChr(10);

      if (_FindVar(nti,(int)work_area,&loc))
    {
         _PutStr("Variable does exist.\n");
        _Load(&loc,&val);

        //Display value returned by _FindVar()
        _PutStr("Value Returned by _FindVar()   : ");
        _PutValue(&val);
      }
      else
      {
          _PutStr("\nVariable does not exist!!!!");
      }

      //Unlock Handle - send address back to heap
      _HUnLock(parm->p[1].val.ev_handle);
   }
}

/* First parameter is the Work Area Number
   Second parameter is the Field Name
*/

FoxInfo myFoxInfo[]={
 {"XREAD",(FPFI)readfield,2,"I,C"},
};

FoxTable _FoxTable={

 (FoxTable FAR *)0,sizeof(myFoxInfo)/sizeof(FoxInfo),myFoxInfo
};

REFERENCES

FoxPro Library Construction Kit "Developer's Guide," _FindVar() section.

Additional reference words: FoxWin LCK 2.50 2.50a 2.50b 2.60 2.60a buglist2.50 buglist2.50a buglist2.50b buglist2.60 buglist2.60a KBCategory: kbtool kbbuglist KBSubcategory: FxtoolLck

Last Reviewed: June 27, 1995