Example #1
0
void *Undo_Do_Block_Split(
	struct Tracker_Windows *window,
	struct WBlocks *wblock,
	struct WTracks *wtrack,
	int realline,
	void *pointer
){
	struct Undo_Block_MergeSplit *ubm=(struct Undo_Block_MergeSplit *)pointer;
	struct WBlocks *wblocktemp=NULL;

	if(ubm->nwblock==NULL){

//Undo
		ubm->nwblock=CB_CopyBlock(wblock);
//		wblocktemp=CB_CopyBlock((struct WBlocks*)ListPrevElement1(&window->wblocks->l,&wblock->l));
		wblocktemp=CB_CopyBlock(NextWBlock(wblock));
		CB_PasteBlock(window,ubm->wblock,wblock);
		DeleteBlock(ubm->blockpos+1);
		ubm->wblock=wblocktemp;
	}else{


//Redo

		InsertBlock(ubm->blockpos,20,20,"n");
		wblocktemp=CB_CopyBlock(wblock);
		CB_PasteBlock(window,ubm->wblock,wblock);
		CB_PasteBlock(window,ubm->nwblock,(struct WBlocks*)ListPrevElement1(&window->wblocks->l,&wblock->l));
		ubm->wblock=wblocktemp;
		ubm->nwblock=NULL;
	}


	BS_UpdateBlockList();
	BS_UpdatePlayList();


	return ubm;
}
Example #2
0
struct Blocks *InsertBlock_CurrPos(
                                   struct Tracker_Windows *window
                                   )
{
	struct WBlocks *wblock=window->wblock;
	NInt blockpos=wblock->l.num;

	ADD_UNDO(Block_Insert(blockpos));

        struct Blocks *ret;
        
        PC_Pause();{
          ret = InsertBlock(blockpos,wblock->block->num_tracks,wblock->block->num_lines,"NN");

          SelectWBlock(window,(struct WBlocks *)ListFindElement1(&window->wblocks->l,blockpos));

          BS_UpdateBlockList();
          BS_UpdatePlayList();

        }PC_StopPause(window);

        return ret;
}
Example #3
0
bool wxSheetSelection::SelectBlock( const wxSheetBlock &block, bool combineNow, 
                                    wxArraySheetBlock *addedBlocks )
{
    if (block.IsEmpty())
        return false;    

    wxArraySheetBlock extraBlocks;
    wxArraySheetBlock *extra = &extraBlocks;
    if (addedBlocks)
    {
        extra = addedBlocks;
        extra->Clear();
    }

    extra->Add(block);
    int extra_count = 1;

    int n, k, count = m_blocks.GetCount();
    if (((m_options & wxSHEET_SELECTION_MULTIPLE_SEL) == 0) && (count > 0) && 
        m_bounds.Intersects(block))
    {
        const int bottom_row = block.GetBottom();
        wxSheetBlock top, bottom, left, right;   

        // interate though blocks breaking up input block if it's already selected
        for (n=FindTopRow(bottom_row); n<count; n++)
        {
            if (bottom_row < m_blocks[n].GetTop())
                break;

            for (k=0; k<extra_count; k++)
            {
                const int combined = m_blocks[n].Combine(extra->Item(k), top, bottom, left, right);
                if (combined != wxSHEET_BLOCK_NONE)
                {
                    extra->RemoveAt(k);
                    extra_count--;
                    k--;

                    if (combined != wxSHEET_BLOCK_ALL)
                    {
                        if ((combined & wxSHEET_BLOCK_TOP)    != 0) 
                            { extra->Add(top);    extra_count++; }
                        if ((combined & wxSHEET_BLOCK_BOTTOM) != 0) 
                            { extra->Add(bottom); extra_count++; }
                        if ((combined & wxSHEET_BLOCK_LEFT)   != 0)   
                            { extra->Add(left);   extra_count++; }
                        if ((combined & wxSHEET_BLOCK_RIGHT)  != 0)  
                            { extra->Add(right);  extra_count++; }
                    }

                    if (extra_count == 0)
                    {
                        n = count;
                        break;
                    }
                }
            }
        }
    }
    
#ifdef CHECK_BLOCK_SORTING
    for (int m=1; m<m_blocks.GetCount(); m++)
        if (m_blocks[m] < m_blocks[m-1]) PRINT_BLOCK("Not sorted", m_blocks[m]);
#endif // CHECK_BLOCK_SORTING    
    
    if (extra_count != 0)
    {
        m_minimized = false;
        for (n=0; n<extra_count; n++)
            InsertBlock(extra->Item(n));
        if (combineNow)
            Minimize();
        
        return true;
    }
    
    return false;
}
Example #4
0
bool wxSheetSelection::DeselectBlock( const wxSheetBlock& block, bool combineNow,
                                      wxArraySheetBlock *deletedBlocks )
{
    int n, count = m_blocks.GetCount();
    if ((count == 0) || !m_bounds.Intersects(block))
        return false;    

    bool done = false;
    bool recalc_bounds = false;
    const int bottom_row = block.GetBottom();
    
    if (deletedBlocks)
        deletedBlocks->Clear();
    
    wxArraySheetBlock extraBlocks;
    wxSheetBlock top, bottom, left, right;
    // iterate though blocks cutting input block out and adding remainder to end
    for (n=FindTopRow(bottom_row); n<count; n++)
    {
        if (bottom_row < m_blocks[n].GetTop())
            break;
        
        const int deleted = m_blocks[n].Delete(block, top, bottom, left, right);
        if (deleted != wxSHEET_BLOCK_NONE)
        {
            done = true;
            int last_n = n;

            if (deletedBlocks) 
                deletedBlocks->Add(m_blocks[n].Intersect(block));
            if (m_bounds.SideMatches(m_blocks[n]) != wxSHEET_BLOCK_NONE)
                recalc_bounds = true;
            
            if (m_blocks[n].Contains(block))
                n = count + 100; // all done, but add cutouts back
            else
                n--;

            m_blocks.RemoveAt(last_n);
            count--;

            if (deleted != wxSHEET_BLOCK_ALL)
            {
                if ((deleted & wxSHEET_BLOCK_TOP)    != 0) 
                    extraBlocks.Add(top);
                if ((deleted & wxSHEET_BLOCK_BOTTOM) != 0) 
                    extraBlocks.Add(bottom);
                if ((deleted & wxSHEET_BLOCK_LEFT)   != 0)   
                    extraBlocks.Add(left);
                if ((deleted & wxSHEET_BLOCK_RIGHT)  != 0)  
                    extraBlocks.Add(right);
            }
        }
    }

    if (done)
    {
        m_minimized = false;
        const int extra_count = extraBlocks.GetCount();
        for (n=0; n<extra_count; n++)
            InsertBlock(extraBlocks.Item(n));        
        if (combineNow) 
            Minimize();
        if (recalc_bounds)
            CalculateBounds();
    }
    
    return done;
}
Example #5
0
BOOL FAR  MergeFile(LPSTR FileName, int view)
{
    HCURSOR hSaveCursor;
    char line[MAX_USER_LINE + 1];
    int offset; //Current offset of storage in block
    int lineLen; // length of line
    BYTE prevLength; //Previous line size
    LPVIEWREC v = &Views[view];
    WORD res;
    LPDOCREC d =&Docs[v->Doc];
    LPLINEREC pCurLine, pLastLine;
    LPBLOCKDEF pCurBlock, pNewBlock;
    long y;

    Assert( v->Doc >= 0);


    if ((hFileDoc = _lopen(FileName, OF_READ)) == HFILE_ERROR)
          return ErrorBox(ERR_File_Open, (LPSTR)FileName);

    if ((pszBufferDoc = DocAlloc(DISK_BLOCK_SIZE)) == NULL) {
        ErrorBox(SYS_Allocate_Memory);
        goto error1;
    }

    dwBytesReadDoc = DISK_BLOCK_SIZE;
    dwOffsetDoc = DISK_BLOCK_SIZE;
    lineLen = 0;

    //Delete selected text if any
    if (v->BlockStatus) {

        long XR, YR;

        GetBlockCoord (view, &(v->X), &(v->Y), &XR, &YR);
        DeleteStream(view, v->X, v->Y, XR, YR, FALSE);
    }

    //Set the Hour glass cursor
          hSaveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));

    //Insert first line

    res = LoadLine(line, &lineLen, d->NbLines);
    if (res == END_OF_FILE || res == END_OF_LINE) {

        //Add a CR+LF
        if (res == END_OF_LINE) {
            line[lineLen] = CR;
            line[lineLen + 1] = LF;
            lineLen += 2;
        }
        if (!InsertBlock(v->Doc, v->X, v->Y, (WORD) lineLen, line))
            goto error2;
    }
    else {

        if (res == ERR_File_Read || res == ERR_Not_A_Text_File)
              ErrorBox(res, (LPSTR)FileName);
        goto error2;
    }

    if (res != END_OF_FILE) {

        //Get current line status (we just inserted it)

        y = v->Y;
        if (!FirstLine(v->Doc, &pCurLine, &y, &pCurBlock))
              return FALSE;

        //Get next line (just after the line we just inserted)

        if (!NextLine(v->Doc, &pCurLine, &y, &pCurBlock))
              return FALSE;

        //Set offset to StoreLine start
              offset =  (LPSTR)pCurLine - (LPSTR)pCurBlock->Data;
        prevLength = pCurLine->PrevLength;

        //Split block in 2 blocks by first allocating a new block and then
        //copying right side of block in new block

        if (!AllocateBlock(pCurBlock, pCurBlock->NextBlock, &pNewBlock))
              return FALSE;

        pLastLine = (LPLINEREC)(pCurBlock->Data + pCurBlock->LastLineOffset);
        memmove(pNewBlock->Data, (LPSTR)pCurLine,
              (LPSTR)pLastLine - (LPSTR)pCurLine + pLastLine->Length);

        //Set new old block len and new new block len
              pCurBlock->LastLineOffset = (LPSTR)pCurLine - (LPSTR)pCurBlock->Data - pCurLine->PrevLength;
        pNewBlock->LastLineOffset = (LPSTR)pLastLine - (LPSTR)pCurLine;

        //Backward links next block with new one
        if (pCurBlock->NextBlock == NULL)
              d->LastBlock = pNewBlock;
        else
              (pCurBlock->NextBlock)->PrevBlock = pNewBlock;

        //Forward link current block with new block

        pCurBlock->NextBlock = pNewBlock;

        CloseLine(v->Doc, &pCurLine, y, &pCurBlock);

        //Read and store all lines in new blocks

        res = LoadLine(line, &lineLen, d->NbLines);
        while (res == END_OF_LINE) {

            //Truncate a file too large

            if (d->NbLines >= MAX_LINE_NUMBER - 1) {
                ErrorBox(ERR_Truncate_Doc);
                res = END_OF_FILE;
                break;
            }

            if (!StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) {
                res = END_ABORT;
                break;
            }

            res = LoadLine(line, &lineLen, ++d->NbLines);
        }

        //Take decisions
        switch (res) {

          case END_OF_FILE:

            //Store last line
            if (StoreLine(line, lineLen, &offset, &prevLength, &pCurBlock)) {

                d->NbLines++;

                //Forward link of last allocated block with new block

                pCurBlock->NextBlock = pNewBlock;

                //Backward link of new block with last allocated block

                pNewBlock->PrevBlock = pCurBlock;
                ((LPLINEREC)(pNewBlock->Data))->PrevLength = (BYTE)(lineLen + LHD);

                //Free memory

                if (!DocFree(pszBufferDoc))
                      InternalErrorBox(SYS_Free_Memory);

                //Restore cursor

                SetCursor(hSaveCursor);

                //Check syntax if C

                if (d->language == C_LANGUAGE) {
                    d->lineTop = 0;
                    d->lineBottom = d->NbLines;
                    CheckSyntax(v->Doc);
                }
                SetVerticalScrollBar(view, TRUE);

                PosXY(view, v->X, v->Y, FALSE);
                InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE);

                CloseHandle (hFileDoc);
                return TRUE;
            }
            else
                goto abort;

          case ERR_File_Read:
          case ERR_Not_A_Text_File:
            ErrorBox(res, (LPSTR)FileName);
            //Fall through

          case END_ABORT:
            {

              abort:
                SetCursor(hSaveCursor);
                break;
            }

          default:
            Assert(FALSE);
            break;
        }

    } else
          InvalidateRect(v->hwndClient, (LPRECT)NULL, FALSE);

  error2: {
        SetCursor (hSaveCursor);
        if (!DocFree(pszBufferDoc))
              InternalErrorBox(SYS_Free_Memory);
    }

  error1: {
        CloseHandle (hFileDoc);
    }

    return FALSE;
}                                       /* MergeFile() */
Example #6
0
LPBNDS
BuildBounds (
    WORD coff,
    LPUL rgoff,
    LPW lpcbnds
    )
{
    LPBNDS rgbnds     = (LPBNDS) MHAlloc (sizeof (BNDS) * cbndsAllocBlock);
    WORD   cbndsAlloc = cbndsAllocBlock;
    WORD   cbnds      = 0;
    WORD   ioff       = 0;

    while (ioff < coff) {
        ULONG uoffCurr  = rgoff [ ioff ];
        ULONG uoffMax   = 0;
        WORD  ibnds     = FindPosition (rgbnds, cbnds, rgoff, uoffCurr);

        if (ibnds == cbnds) {

            // We're after all other known blocks, so our max
            //  is "infinity"

            uoffMax = 0xFFFFFFFF;

            rgbnds = InsertBlock (ibnds, 1, rgbnds, &cbnds, &cbndsAlloc);

        } else if (rgoff [ rgbnds [ ibnds ].ilnStart ] > uoffCurr) {

            // We're at an insertion point, not in the middle of
            //  another block candidate

            uoffMax = rgoff [ rgbnds [ ibnds ].ilnStart ];

            rgbnds = InsertBlock (ibnds, 1, rgbnds, &cbnds, &cbndsAlloc);
        } else {

            // We're in the middle of another block candidate, so we
            //  must split it in two

            rgbnds = InsertBlock (ibnds, 2, rgbnds, &cbnds, &cbndsAlloc);

            // Start of ibnds is already set
            rgbnds [ ibnds ].ilnEnd = ScanBlock (
                rgoff,
                coff,
                rgbnds [ ibnds ].ilnStart,
                uoffCurr
           );

            rgbnds [ ibnds + 2 ].ilnStart = rgbnds [ ibnds ].ilnEnd + 1;
            // End of ibnds + 2 is already set

            uoffMax = rgoff [ rgbnds [ ibnds + 2 ].ilnStart ];

            ibnds += 1;
        }

        rgbnds [ ibnds ].ilnStart = ioff;
        rgbnds [ ibnds ].ilnEnd   = ScanBlock (rgoff, coff, ioff, uoffMax);

        ioff = rgbnds [ ibnds ].ilnEnd + 1;
    }

    *lpcbnds = cbnds;
    return rgbnds;
}
Example #7
0
bool	Strip::Load		(const TCHAR* lpszFileName)
{
	// ----- Initialize ----- //
	FILE* stream = _tfopen(lpszFileName, _T("rb") CHARSET);

	if (stream == NULL || _pPimpl == NULL)
	{
		return false;
	}

	TiXmlDocument		doc;
	TiXmlAttribute*		pAttr;
	TiXmlElement*		pRoot;
	TiXmlElement*		pBlockNode;
	TiXmlElement*		pUnitNode;
	TiXmlElement*		pBallNode;

	Block*				pBlockObject;
	Unit*				pUnitObject;
	Ball*				pBallObject;

	const char*			sRootName;
	const char*			sAttrName;

	double				dValue;
	int					nValue;

	if (!doc.LoadFile(stream))
	{
		return false;
	}

	pRoot = doc.RootElement();
	if (pRoot == false)
	{
		return false;
	}

	sRootName = pRoot->Value();
	if (strcmp(sRootName, ROOT_NAME_STRIP) != 0)
	{
		return false;
	}

	_pPimpl->vectorBlocks.clear();

	// ----- Get a Strip Data ----- //
	if (pRoot->QueryDoubleAttribute(ATTR_NAME_WIDTH,	&dValue) == TIXML_SUCCESS)
	{
		_pPimpl->dWidth		= dValue;
	}
	if (pRoot->QueryDoubleAttribute(ATTR_NAME_HEIGHT,	&dValue) == TIXML_SUCCESS)
	{
		_pPimpl->dHeight	= dValue;
	}

	// ----- Get Strip's childs ----- //
	pBlockNode = pRoot->FirstChildElement();

	if (pBlockNode != NULL)
	{
		do
		{
			pBlockObject = new Block();

			// ----- Get a Block Data ----- //
			if (pBlockNode->QueryIntAttribute		(ATTR_NAME_COLUMN,	&nValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetColumn	(nValue);
			}
			if (pBlockNode->QueryIntAttribute		(ATTR_NAME_ROW,		&nValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetRow	(nValue);
			}
			if (pBlockNode->QueryDoubleAttribute	(ATTR_NAME_WIDTH,	&dValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetWidth	(dValue);
			}
			if (pBlockNode->QueryDoubleAttribute	(ATTR_NAME_HEIGHT,	&dValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetHeight	(dValue);
			}
			if (pBlockNode->QueryDoubleAttribute	(ATTR_NAME_START_X,	&dValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetStartX	(dValue);
			}
			if (pBlockNode->QueryDoubleAttribute	(ATTR_NAME_START_Y,	&dValue) == TIXML_SUCCESS)
			{
				pBlockObject->SetStartY	(dValue);
			}

			// ----- Get Block's childs ----- //
			pUnitNode = pBlockNode->FirstChildElement();

			if (pUnitNode != NULL)
			{
				do
				{
					pUnitObject = new Unit();

					// ----- Get a Unit Data ----- //
					if (pUnitNode->QueryIntAttribute	(ATTR_NAME_COLUMN,		&nValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetColumn	(nValue);
					}
					if (pUnitNode->QueryIntAttribute	(ATTR_NAME_ROW,			&nValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetRow		(nValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_START_X,		&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetStartX	(dValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_START_Y,		&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetStartY	(dValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_CENTER_X,	&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetCenterX	(dValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_CENTER_Y,	&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetCenterY	(dValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_WIDTH,		&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetWidth	(dValue);
					}
					if (pUnitNode->QueryDoubleAttribute	(ATTR_NAME_HEIGHT,		&dValue) == TIXML_SUCCESS)
					{
						pUnitObject->SetHeight	(dValue);
					}

					// ----- Get Unit's childs ----- //
					pBallNode = pUnitNode->FirstChildElement();

					if (pBallNode != NULL)
					{
						do
						{
							pBallObject = new Ball();

							// ----- Get a Ball Data ----- //
							if (pBallNode->QueryDoubleAttribute	(ATTR_NAME_DIAMETER,	&dValue) == TIXML_SUCCESS)
							{
								pBallObject->SetDiameter	(dValue);
							}
							if (pBallNode->QueryDoubleAttribute	(ATTR_NAME_CENTER_X,	&dValue) == TIXML_SUCCESS)
							{
								pBallObject->SetCenterX		(dValue);
							}
							if (pBallNode->QueryDoubleAttribute	(ATTR_NAME_CENTER_Y,	&dValue) == TIXML_SUCCESS)
							{
								pBallObject->SetCenterY		(dValue);
							}
							if (pBallNode->QueryIntAttribute	(ATTR_NAME_BALL_STATUS,	&nValue) == TIXML_SUCCESS)
							{
								pBallObject->SetStatus		(nValue);
							}

							pUnitObject->InsertBall(pBallObject);
						}
						while (pBallNode = pBallNode->NextSiblingElement());

					}

					pBlockObject->InsertUnit(pUnitObject);
				}
				while (pUnitNode = pUnitNode->NextSiblingElement());
			}

			// ----- Add Block Object ----- //
			InsertBlock(pBlockObject);
		}
		while (pBlockNode = pBlockNode->NextSiblingElement());
	}

	// ----- Close ----- //
	fclose(stream);

	return true;
}
Example #8
0
//按文件名顺序插入
void CIndex::insert(IndexElemType Record,BOOL bDir)
{
    DebugTrace("**********插入记录\n");
    int (*FunCmpare)(IndexElemType,IndexElemType);
    if(bDir) FunCmpare=comp_dir;
    else FunCmpare=comp_file;
    ++m_size;
    int cmp;
    PINDEX_BLOCK_NODE pNode;

    int i;
    for(i=0;i<m_dwBlockCount;++i)
    {
        pNode=m_pIndex[i];
        cmp=FunCmpare(Record,pNode->PtrData[pNode->CurrentEnd-1]);
        if(cmp<=0) break;
    }
    if(i==m_dwBlockCount){//
        DebugTrace("当前插入的是最大文件目录名\n");
        //看最后节点是否有空间插入,如果没有,则新增加节点
        //满时:m_pLastNode->CurrentBegin==0 m_pLastNode->CurrentEnd==DirFrnIndexBlockNode::CountPerIndex
        //[CurrentBegin,CurrentEnd)
        if(m_pLastNode->IsEndFull()){//右满
            DebugTrace("右满\n");
            if(m_pLastNode->IsBeginFull()){//左满
                DebugTrace("左满\n");
                //先向左借空间
                if(m_dwBlockCount>=2 && !m_pIndex[m_dwBlockCount-2]->IsFull()){//左有借
                    DebugTrace("左有借\n");
                    pNode=m_pIndex[m_dwBlockCount-2];
                    if(pNode->IsEndFull()){//右满
                        DebugTrace("左右端满,左移前Beg=%d,End=%d\n",pNode->CurrentBegin,pNode->CurrentEnd);
                        pNode->LeftMove();
                        DebugTrace("左右端满,左移后Beg=%d,End=%d\n",pNode->CurrentBegin,pNode->CurrentEnd);
                    }
                    DebugTrace("最后右移动前,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                    pNode->AddEnd(m_pLastNode->RemoveBegin());//最后BEG右移
                    DebugTrace("最后右移动后,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                    m_pLastNode->LeftMove();//右移动一格
                    DebugTrace("左移动一格,【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                }else{//左无借,将最后一个节点分裂保留3/4 1/4进新节点
                    DebugTrace("左无借【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                    pNode=m_pLastNode;
                    AddLastBlock();//m_pLastNode已指向新块
                    DebugTrace("增加新块,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                    //分裂pNode
                    m_pLastNode->CutFromLeft(pNode);
                    DebugTrace("左剪切,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);         
                }
                DebugTrace("AddEnd【Beg=%d,End=%d】\n",m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                m_pLastNode->AddEnd(Record);
            }
            else{//左未满
                DebugTrace("左未满\n");
                //整体左移动一格
                m_pLastNode->LeftMove();
                m_pLastNode->AddEnd(Record);
            }
        }else{//右未满
            DebugTrace("右未满\n");
            m_pLastNode->AddEnd(Record);
        }           
    }else{//插入的值非最大值
        //pNode指向插入节点
        //寻找插入位置先
        
        int low=pNode->CurrentBegin,high=pNode->CurrentEnd-1;
        int mid;  
        DWORD dwInsert;
        while(low<=high)
        {
            mid=low+((high-low)>>1);
            cmp=FunCmpare(Record,pNode->PtrData[mid]);
            if(cmp<0) high=mid-1;
            else if(cmp>0) low=mid+1;
            else{//找到同名
                dwInsert=mid;
                break;
            }
        }
        if(low>high) dwInsert=low;   
        DebugTrace("寻找插入位置先【Beg=%d,dwInsert=%d,End=%d】\n",pNode->CurrentBegin,dwInsert,pNode->CurrentEnd);
        assert(dwInsert>=pNode->CurrentBegin && dwInsert<pNode->CurrentEnd);
        //插入位置 注意[dwInsert ,CurEnd) 应向右移动
        if(pNode->IsFull()){
            DebugTrace("插入节点满\n");
            if(pNode==m_pLastNode){//在最后一个节点中插入
                DebugTrace("是在最后一个节点中插入\n");
                if(i>=1 && !m_pIndex[i-1]->IsFull()){//左有借
                    DebugTrace("左有借\n");
                    pNode=m_pIndex[i-1];
                    if(pNode->IsEndFull()){//右满
                        DebugTrace("左节点 右满【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd);
                        pNode->LeftMove();
                        DebugTrace("左移动 右满【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd);
                    }
                    if(0==dwInsert){//BasicInfo< m_pLastNode的所有值
                        DebugTrace("直接插入左最后\n");
                        pNode->AddEnd(Record);
                        DebugTrace("【Beg=%d,End=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd);
                        return;
                    }else pNode->AddEnd(m_pLastNode->RemoveBegin());//最后BEG右移
                    m_pLastNode->Insert(dwInsert,Record);
                    DebugTrace("最后右移动后,【Beg1=%d,End1=%d】【Beg2=%d,End2=%d】\n",pNode->CurrentBegin,pNode->CurrentEnd,m_pLastNode->CurrentBegin,m_pLastNode->CurrentEnd);
                }else{//左无借,将最后一个节点分裂保留3/4 1/4进新节点
                    DebugTrace("左无借,分增加最后节点\n");
                    pNode=m_pLastNode;
                    AddLastBlock();//m_pLastNode已指向新块
                    //分裂pNode
                    m_pLastNode->CutFromLeft(pNode,&dwInsert);
                    pNode->AddEnd(Record);
                }
            }else if(pNode==*m_pIndex){//在第一个节点中插入
                DebugTrace("在第一个节点中插入\n");
                if(m_dwBlockCount>1 && !m_pIndex[1]->IsFull()){//右有借
                    DebugTrace("右有借\n");
                    pNode=m_pIndex[1];
                    if(pNode->IsBeginFull()){//左满
                        DebugTrace("左满则右移动\n");
                        pNode->RightMove();
                    }
                    //*m_pIndex的最后一个值一定大于插入指
                    pNode->AddBegin((*m_pIndex)->RemoveEnd());
                    (*m_pIndex)->Insert(dwInsert,Record);
                }else{//右无借
                    DebugTrace("右无借\n");
                    InsertBlock(1);
                    pNode=m_pIndex[1];
                    //分裂pNode
                    pNode->CutFromLeft(*m_pIndex,&dwInsert);
                    (*m_pIndex)->AddEnd(Record);
                }              
            }else{//即不是第一个节点 又不是最后节点插入 可能要向两边借
                DebugTrace("向两边借\n");
                if(!m_pIndex[i-1]->IsFull()){//试图向左借
                    pNode=m_pIndex[i-1];
                    if(pNode->IsEndFull()){//右满
                        pNode->LeftMove();
                    }
                    if(0==dwInsert){//BasicInfo< m_pLastNode的所有值
                        pNode->AddEnd(Record);
                        return;
                    }else pNode->AddEnd(m_pIndex[i]->RemoveBegin());//最后BEG右移
                    m_pIndex[i]->Insert(dwInsert,Record);
                }else if(!m_pIndex[i+1]->IsFull()){//试图向右借
                    pNode=m_pIndex[i+1];
                    if(pNode->IsBeginFull()){//左满
                        pNode->RightMove();
                    }
                    //*m_pIndex的最后一个值一定大于插入指
                    pNode->AddBegin(m_pIndex[i]->RemoveEnd());
                    m_pIndex[i]->Insert(dwInsert,Record);
                }else{//左右均无借的
                    //插入新节点,然后向两边借,本处仅实现的拷贝一边的
                    //优化:可以拷贝两边的数据,使得连续3个节点都未满
                    if(dwInsert<(INDEX_BLOCK_NODE::CountPerIndex>>1)){ 
                        //插入位置在前部 拷贝大块到令一块中央
                        InsertBlock(i+1);
                        m_pIndex[i+1]->CutFromLeft(m_pIndex[i],&dwInsert);
                        m_pIndex[i]->AddEnd(Record);  
                    }else{
                        InsertBlock(i);
                        m_pIndex[i]->CutFromRight(m_pIndex[i+1],&dwInsert);
                        m_pIndex[i+1]->AddBegin(Record);          
                    }
                }
            }
        }else{//本节点有位置可插