void __fastcall TfrmMain::sbDownGoodsClick(TObject *Sender)
{
    int nCount = 0;
    unsigned char pszBuffer[65536];
    unsigned char pszResult[128];
    int  nFieldLength[16];
    AnsiString strData;
    //首先提取list中的数据长度
    int nGoodsAmount = lvList.Items.Count;
    TIniFile *pIniFile;
    AnsiString strFileName = editFile.Text;
    AnsiString strListFile = ChangeFileExt( strFileName, ".DLF" );
    pIniFile = new TIniFile( ChangeFileExt( strFileName, ".INI" ) );
    //提取有多少字段
    int nSector = pIniFile.ReadInteger( "Goods", "Amount", 1 );
    for(int i=0;i<nSector;i++)
    {
        char pszTest[16];
        sprintf(pszTest,"%d",i);
        nFieldLength[i] = pIniFile.ReadInteger( "Length", pszTest, 10 );
    }
    //提取条码索引字段
    int nIndex = pIniFile.ReadInteger( "Goods", "Index", 0 );
    //提取需要显示的字段
    strData = pIniFile.ReadString( "Goods", "pos", "0" );
    int nIndexPos = strData.Pos(IntToStr(nIndex));
    if(nIndexPos)nIndexPos--;
    char pszFieldList[16];
    strcpy(pszFieldList,strData.c_str());
    int nDownFieldList = strlen(pszFieldList);
    delete pIniFile;
    sbState.SimpleText = "正在处理数据...";
    //准备数据,准备下载  //首先要对数据按照要查找的索引进行排序  //读取文件进行下载,一次要读去所有的内容
    char* pszDownloadList;
    //提取文件长度
    FILE* fp;
    fp = fopen(strListFile.c_str(),"r");
    long curpos, length;
    curpos = ftell(fp);
    fseek(fp, 0L, SEEK_END);
    length = ftell(fp);
    fseek(fp, curpos, SEEK_SET);
    pszDownloadList = (char*)malloc(length*sizeof(char));
    curpos = 0;
    char pszTempList[256];
    memset(pszTempList,0x00,256);
    strcpy(pszDownloadList,"");
    nCount = 0;
    int nRecordLength;
    while(fgets(pszTempList,256,fp))
    {
        nRecordLength = strlen(pszTempList);
        curpos += nRecordLength;
        pszTempList[nRecordLength-1] = 0x00;
        strcat(pszDownloadList,pszTempList);
        memset(pszTempList,0x00,256);
        nCount++;
        //if(0 == nCount%100)
        {
        sbState.SimpleText = "正在处理数据..." + IntToStr(nCount);
        MSG msg;
        while(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))DispatchMessage(&msg);
        }
    }
    nGoodsAmount = nCount;
    length = strlen(pszDownloadList);
    fclose(fp);
    //发送物品库需要提供数目,长度等,备注:只下载显示字段
    //命令头格式:单次下载的长度(2)+记录数(3)+标志字节(1)+记录长度(1)+字段长度(1)...
    //备注:单次下载的长度为1024/2048/4096字节,记录数 商品库的数目
    //标志字节的高半个字节表示按照那个索引来查找条码 原则上下载的第一个字段是条码
    //低半个字节表示字段数目,记录数X记录长度是本次下载的所有商品库的字节
    //记录长度=所有字段的长度之和
    sbState.SimpleText = "准备发送物品库";
    //单次下载的长度
    pszBuffer[0] = SSI_UNIT_SEND_LENGTH/256;
    pszBuffer[1] = SSI_UNIT_SEND_LENGTH%256;
    //商品数目
    pszBuffer[2] = nGoodsAmount/(256*256);
    pszBuffer[3] = nGoodsAmount/256;
    pszBuffer[4] = nGoodsAmount%256;
    //标志字节
    pszBuffer[5] = nIndexPos<<4;
    pszBuffer[5] += nDownFieldList;
    //添加具体字段的长度
    int nDownloadLength = 0;
    for(int i=0;i<nDownFieldList;i++)
    {
        pszBuffer[7+i] = nFieldLength[pszFieldList[i]-0x30];
        nDownloadLength += nFieldLength[pszFieldList[i]-0x30];
    }
    //字长度
    pszBuffer[6] = nDownloadLength;
    int nDownFlag = 1;
    for(nCount=0;nCount<6;nCount++)
    {
        SHTP_PurgePort(m_hPortHandle,2);
        SHTP_PutMessage(m_hPortHandle,SSI_GOOD_LIST,pszBuffer,7+nDownFieldList);
        //等待接收下位机应答
        if(SHTP_SUCC == SHTP_GetMessage(m_hPortHandle,pszResult,30))
        {
            sbState.SimpleText = "正在发送物品库";
            nDownFlag = 0;
            break;
        }
    }
    //开始连续发送数据
    DWORD dwLength;
    int nOffset;
    sbState.SimpleText = "开始发送商品信息数据...";
    int nDown64KStep,nDownUnitStep;
    nDown64KStep = length/65536;
    for(nCount=0;nCount<nDown64KStep;nCount++)
    {//开始下载64K数据
        for(int i=0;i<64;i++)
        {
            nOffset =  nCount*65536 + i*SSI_UNIT_SEND_LENGTH;
            SHTP_PurgePort(m_hPortHandle,2);
            WriteFile(m_hPortHandle,pszDownloadList+nOffset,SSI_UNIT_SEND_LENGTH,&dwLength,NULL);
            //需要确认一下才能发下一部分数据
            if(SHTP_SUCC == SHTP_GetMessage(m_hPortHandle,pszResult,300))
            {
                sbState.SimpleText = IntToStr(nOffset/nDownloadLength+1);
                MSG msg;
                while(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))DispatchMessage(&msg);
            }
        }
    }
}