Exemple #1
0
void WaveTrack::AppendAlias(wxString fullPath,
                            sampleCount start,
                            sampleCount len, int channel)
{
   WaveBlock *newBlock = new WaveBlock();
   newBlock->start = numSamples;
   newBlock->len = len;
   newBlock->f =
       dirManager->NewAliasBlockFile(totalHeaderLen,
                                     fullPath, start, len, channel);

   InitBlock(newBlock);

   BlockFile *f = newBlock->f;

   sampleType *buffer = new sampleType[len];
   Read(buffer, newBlock, 0, len);

   wxASSERT(f);
   bool opened = f->OpenWriting();
   wxASSERT(opened);
   UpdateSummaries(buffer, newBlock, len);
   f->Close();

   delete[]buffer;

   block->Add(newBlock);
   numSamples += newBlock->len;

   envelope.SetTrackLen(numSamples / rate);
}
Exemple #2
0
WaveBlock *WaveTrack::NewInitedWaveBlock()
{
   WaveBlock *b = new WaveBlock();
   b->f = dirManager->NewBlockFile();
   bool inited = InitBlock(b);
   wxASSERT(inited);
   return b;
}
Exemple #3
0
//--------------------------------------------------------------------------------------------------
void* le_mem_TryAlloc
(
    le_mem_PoolRef_t    pool    ///< [IN] The pool from which the object is to be allocated.
)
{
    LE_ASSERT(pool != NULL);

    MemBlock_t* blockPtr = NULL;
    void* userPtr = NULL;

    Lock();

    #ifndef LE_MEM_VALGRIND
        // Pop a link off the pool.
        le_sls_Link_t* blockLinkPtr = le_sls_Pop(&(pool->freeList));

        if (blockLinkPtr != NULL)
        {
            // Get the block from the block link.
            blockPtr = CONTAINER_OF(blockLinkPtr, MemBlock_t, link);
        }
    #else
        blockPtr = malloc(pool->blockSize);

        if (blockPtr != NULL)
        {
            InitBlock(pool, blockPtr);
        }
    #endif

    if (blockPtr != NULL)
    {
        // Update the pool and the block.
        pool->numAllocations++;
        pool->numBlocksInUse++;

        if (pool->numBlocksInUse > pool->maxNumBlocksUsed)
        {
            pool->maxNumBlocksUsed = pool->numBlocksInUse;
        }

        blockPtr->refCount = 1;

        // Return the user object in the block.
        #ifdef USE_GUARD_BAND
            CheckGuardBands(blockPtr);
            userPtr = blockPtr->data + GUARD_BAND_SIZE;
        #else
            userPtr = blockPtr->data;
        #endif
    }

    Unlock();

    return userPtr;
}
Exemple #4
0
// In the spirt of so many exceptions! =D blah! https://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
LONG WINAPI vEhTracer(PEXCEPTION_POINTERS ExceptionInfo)
{
	DWORD OldPerm;
	PExecutionBlock pCtx = NULL;

	ULONG64 dwThr = __readgsdword(0x48);


	// TODO: just put the whole context in the array to remove an indirect anyhow
	if (CtxTable != NULL && CtxTable[dwThr].TID != 0)
		pCtx = &CtxTable[dwThr];
	else
		pCtx = InitBlock(dwThr);

	// allow exec
	//pCtx->DisabledUntil = (LPVOID)((ULONG64) ExceptionInfo->ExceptionRecord->ExceptionAddress & ~0x4095);
	
	pCtx->pExeption = ExceptionInfo;
	pCtx->TSC = __rdtsc();

	// check if my thread is a thread that's already entered into the VEH logging something lower on the stack
	// this means were probably getting an exception for something we did ourselves during the logging 
	// which is sort of pointless
	// we could test all Exception address against known entries we provide
	if (AmIinThreadTable())
		return EXCEPTION_CONTINUE_EXECUTION;


	if (ExceptionInfo->ExceptionRecord->ExceptionCode != STATUS_SINGLE_STEP)
		return EXCEPTION_CONTINUE_SEARCH;

	// no re-entrance while servicing exceptions
	EnterThreadTable(dwThr, false);

	// since we like to do logging
	//LogRIP(pCtx);
	// to dump info 
	//_DumpContext(pCtx);

	// Loop through all of the block fighters
	Fight(pCtx);

	// Thanks Feryno
	// http://x86asm.net/articles/backdoor-support-for-control-transfer-breakpoint-features/
	// 
	ExceptionInfo->ContextRecord->EFlags |= 0x100; // single step
	ExceptionInfo->ContextRecord->Dr7 |= 0x300; // setup branch tracing 

	// record keeping
	pCtx->BlockFrom = ExceptionInfo->ContextRecord->Rip;

	// exit lock
	ExitThreadTable(dwThr, false);
	
	return EXCEPTION_CONTINUE_EXECUTION;
}
Exemple #5
0
void WaveTrack::InsertSilence(double t, double lenSecs)
{
   // Create a new track containing as much silence as we
   // need to insert, and then call Paste to do the insertion

   sampleCount len = (sampleCount) (lenSecs * rate + 0.5);

   WaveTrack *sTrack = new WaveTrack(dirManager);
   sTrack->rate = rate;

   sampleCount idealSamples = GetIdealBlockSize();
   sampleType *buffer = new sampleType[idealSamples];
   sampleCount i;
   for (i = 0; i < idealSamples; i++)
      buffer[i] = 0;

   sampleCount pos = 0;
   BlockFile *firstBlockFile = NULL;

   while (len) {
      sampleCount l = (len > idealSamples ? idealSamples : len);

      WaveBlock *w = new WaveBlock();
      w->start = pos;
      w->len = l;
      w->min = 0;
      w->max = 0;
      if (pos == 0 || len == l) {
         w->f = dirManager->NewBlockFile();
         firstBlockFile = w->f;
         bool inited = InitBlock(w);
         wxASSERT(inited);
         FirstWrite(buffer, w, l);
      } else {
         w->f = dirManager->CopyBlockFile(firstBlockFile);
         if (!w->f) {
            wxMessageBox("Could not paste!  (Out of disk space?)");
         }            
      }

      sTrack->block->Add(w);

      pos += l;
      len -= l;
   }

   sTrack->numSamples = pos;

   Paste(t, sTrack);

   delete sTrack;

   ConsistencyCheck("InsertSilence");
}
Exemple #6
0
void WaveTrack::CopyWrite(sampleType * buffer, WaveBlock * b,
                          sampleCount start, sampleCount len)
{
   // Usually we don't write to an existing block; to support Undo,
   // we copy the old block entirely into memory, dereference it,
   // make the change, and then write the new block to disk.

   wxASSERT(b);
   wxASSERT(b->len <= maxSamples);
   wxASSERT(start + len <= b->len);

   dirty++;                     // forces redraw

   sampleType *newBuffer = 0;

   newBuffer = new sampleType[maxSamples];
   wxASSERT(newBuffer);

   Read(newBuffer, b, 0, b->len);

   for (int i = 0; i < len; i++)
      newBuffer[start + i] = buffer[i];

   BlockFile *oldBlockFile = b->f;
   b->f = dirManager->NewBlockFile();
   bool inited = InitBlock(b);
   wxASSERT(inited);

   buffer = newBuffer;
   start = 0;
   len = b->len;

   dirManager->Deref(oldBlockFile);

   // Write the block

   BlockFile *f = b->f;

   wxASSERT(f);
   bool opened = f->OpenWriting();
   wxASSERT(opened);

   f->SeekTo(totalHeaderLen + (start * sizeof(sampleType)));

   f->Write((void *) buffer, len * sizeof(sampleType));

   UpdateSummaries(buffer, b, len);

   if (newBuffer)
      delete[]newBuffer;

   f->Close();
}
Exemple #7
0
    //----------------------------------------------------------------------------------------------
    static void AddBlocks
    (
        le_mem_PoolRef_t    pool,       ///< [IN] The pool to be expanded.
        size_t              numBlocks   ///< [IN] The number of blocks to add to the pool.
    )
    {
        size_t i;
        size_t blockSize = pool->blockSize;
        size_t mallocSize = numBlocks * blockSize;

        // Allocate the chunk.
        MemBlock_t* newBlockPtr = malloc(mallocSize);

        LE_ASSERT(newBlockPtr);

        for (i = 0; i < numBlocks; i++)
        {
            InitBlock(pool, newBlockPtr);
            newBlockPtr = (MemBlock_t*)(((uint8_t*)newBlockPtr) + blockSize);
        }

        // Update the pool.
        pool->totalBlocks += numBlocks;
    }
Exemple #8
0
bool InstallThread(ULONG th32ThreadID, int reason)
{
	PExecutionBlock pCtx = NULL;

	pCtx = InitBlock(th32ThreadID);
	if (pCtx == NULL) {
		wprintf(L"unable to install thread %d (OOM?)\n", th32ThreadID);
		return false;
	}

	KnownThreadCount++;

	// OpenThreads for neighbor threads
	pCtx->hThr = OpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, th32ThreadID);

	// install branch tracing
	CONTEXT ContextRecord = { 0 };
	ContextRecord.ContextFlags = CONTEXT_ALL;

	wprintf(L"%d) attaching to thread ID: %d in process %d\n", reason, th32ThreadID, GetCurrentProcessId());

	if (!GetThreadContext(pCtx->hThr, &ContextRecord))
		wprintf(L"unable to get context on thread %d\n", th32ThreadID);

	// installed a thread
	EnterThreadTable(th32ThreadID, true);

	ContextRecord.EFlags |= 0x100;	// single step
	ContextRecord.Dr7 |= 0x300;		// setup branch tracing 

	if (!SetThreadContext(pCtx->hThr, &ContextRecord))
		wprintf(L"unable to set context on thread %d\n", th32ThreadID);


	return true;
}
Exemple #9
0
/* seek to space for attribute  (LIBRARY_INTERNAL)
 * CsfSeekAttrSpace seeks to the a point in the file where
 * the attribute must be stored and update the attribute control
 * blocks accordingly.
 * Writing can still fail since there is no check if that space is really
 * avalaible on the device. After this call returns the file is already
 * seeked to the point the functions returns.
 * returns the file position or 0 in case of error.
 *
 * Merrno
 * ATTRDUPL
 * NOACCESS
 * WRITE_ERROR
 */
CSF_FADDR32 CsfSeekAttrSpace(
	MAP *m,       		/* map handle */
	CSF_ATTR_ID id,               /* attribute identification only for check if avalaible */
	size_t size)            /* size to be seeked to */
{
	ATTR_CNTRL_BLOCK b;
	CSF_FADDR32 currBlockPos, prevBlockPos=USED_UNINIT_ZERO, newPos, endBlock, resultPos=0;
	int noPosFound;
	int i;

	if (MattributeAvail(m ,id))
	{
		M_ERROR(ATTRDUPL);
		goto error;
	}

	if (! WRITE_ENABLE(m))
	{
		M_ERROR(NOACCESS);
		goto error;
	}

	currBlockPos = m->main.attrTable;
        noPosFound = 1;
	while (noPosFound)
	{
		if (currBlockPos == 0)
		{
			if (m->main.attrTable == 0)
			{ /* FIRST BLOCK */
				newPos =( (CSF_FADDR)(m->raster.nrRows)*
					   (CSF_FADDR)(m->raster.nrCols)*
					  (CSF_FADDR)(CELLSIZE(RgetCellRepr(m))))
					  + ADDR_DATA;
				m->main.attrTable = newPos;
			}
			else
			{ /* NEW/NEXT BLOCK */
				newPos = b.attrs[LAST_ATTR_IN_BLOCK].attrOffset
					+
					b.attrs[LAST_ATTR_IN_BLOCK].attrSize;
				b.next = newPos;
				if (CsfWriteAttrBlock(m, prevBlockPos, &b))
				{
					M_ERROR(WRITE_ERROR);
					resultPos = 0;
				}
			}
			InitBlock(&b);
			b.attrs[0].attrOffset =
				newPos + SIZE_OF_ATTR_CNTRL_BLOCK;
			currBlockPos = newPos;
			noPosFound = 0;
		}
		else
			CsfReadAttrBlock(m, currBlockPos, &b);
		i = 0; /* this is also the right index if a new block
			   is added ! */
		while (noPosFound  && i < NR_ATTR_IN_BLOCK)
			switch (b.attrs[i].attrId)
			{
				case END_OF_ATTRS:
					POSTCOND(i >= 1);
					/* i >= 1 , no block otherwise */
					b.attrs[i].attrOffset =
						b.attrs[i-1].attrOffset  +
						b.attrs[i-1].attrSize;
					noPosFound = 0;
                                        break;
				case ATTR_NOT_USED:
					if (i == NR_ATTR_IN_BLOCK)
						endBlock = b.next;
					else
						endBlock = b.attrs[i+1].attrOffset;
					if ( (size_t)( endBlock - b.attrs[i].attrOffset) >= size)
						/* this position can
							hold the attr */
						noPosFound = 0;
                                        else
                                            i++;
                                        break;
				 default:
                                            i++;
			} /* switch */
/*		if (b.next == 0)
                     ? When did I change this CW
		       remember this block position since it may be have
		       to rewritten
*/
		prevBlockPos = currBlockPos;
		if (noPosFound)
			currBlockPos = b.next;
 	} /* while */

	b.attrs[i].attrSize = size;
	b.attrs[i].attrId   = id;
	resultPos = b.attrs[i].attrOffset;

	if (CsfWriteAttrBlock(m, currBlockPos, &b))
	{
		M_ERROR(WRITE_ERROR);
		resultPos = 0;
	}
	fseek(m->fp, (long)resultPos, SEEK_SET); /* fsetpos() is better */
error:	return resultPos;
} /* CsfSeekAttrSpace */
Exemple #10
0
void WaveTrack::Paste(double t, VTrack * src)
{
   wxASSERT(src->GetKind() == WaveTrack::Wave);

   envelope.ExpandRegion(t, src->GetMaxLen());

#if wxUSE_THREADS
   wxMutexLocker lock(*blockMutex);
#endif

   sampleCount s = (sampleCount) ((t - tOffset) * rate + 0.5);

   if (s < 0)
      s = 0;
   if (s >= numSamples)
      s = numSamples;

   BlockArray *srcBlock = ((WaveTrack *) src)->GetBlockArray();
   int addedLen = ((WaveTrack *) src)->numSamples;
   int srcNumBlocks = srcBlock->Count();

   if (addedLen == 0 || srcNumBlocks == 0)
      return;

   int b = FindBlock(s);
   int numBlocks = block->Count();

   if (numBlocks == 0) {
      // Special case: this track is currently empty.

      for (int i = 0; i < srcNumBlocks; i++)
         AppendBlock(srcBlock->Item(i));

      envelope.SetTrackLen(numSamples / rate);

      ConsistencyCheck("Paste branch one");

      return;
   }

   if (b >= 0 && b < numBlocks
       && block->Item(b)->len + addedLen < maxSamples) {
      // Special case: we can fit all of the new samples inside of
      // one block!

      sampleType *buffer = new sampleType[maxSamples];

      int splitPoint = s - block->Item(b)->start;
      Read(buffer, block->Item(b), 0, splitPoint);
      ((WaveTrack *) src)->Get(&buffer[splitPoint], 0, addedLen);
      Read(&buffer[splitPoint + addedLen], block->Item(b),
           splitPoint, block->Item(b)->len - splitPoint);

      WaveBlock *largerBlock = new WaveBlock();
      largerBlock->start = block->Item(b)->start;
      largerBlock->len = block->Item(b)->len + addedLen;
      largerBlock->f = dirManager->NewBlockFile();
      bool inited = InitBlock(largerBlock);
      wxASSERT(inited);

      FirstWrite(buffer, largerBlock, largerBlock->len);

      dirManager->Deref(block->Item(b)->f);
      delete block->Item(b);
      block->Item(b) = largerBlock;

      for (int i = b + 1; i < numBlocks; i++)
         block->Item(i)->start += addedLen;

      numSamples += addedLen;

      delete[]buffer;

      envelope.SetTrackLen(numSamples / rate);

      ConsistencyCheck("Paste branch two");

      return;
   }
   // Case two: if we are inserting four or fewer blocks,
   // it's simplest to just lump all the data together
   // into one big block along with the split block,
   // then resplit it all

   int i;

   BlockArray *newBlock = new BlockArray();
   newBlock->Alloc(numBlocks + srcNumBlocks + 2);
   int newNumBlocks = 0;

   for (i = 0; i < b; i++) {
      newBlock->Add(block->Item(i));
      newNumBlocks++;
   }

   WaveBlock *splitBlock = block->Item(b);
   sampleCount splitLen = block->Item(b)->len;
   int splitPoint = s - splitBlock->start;

   if (srcNumBlocks <= 4) {

      sampleCount sum = splitLen + addedLen;

      sampleType *sumBuffer = new sampleType[sum];

      Read(sumBuffer, splitBlock, 0, splitPoint);
      ((WaveTrack *) src)->Get(&sumBuffer[splitPoint], 0, addedLen);
      Read(&sumBuffer[splitPoint + addedLen], splitBlock,
           splitPoint, splitBlock->len - splitPoint);

      BlockArray *split = Blockify(sumBuffer, sum);
      for (i = 0; i < split->Count(); i++) {
         split->Item(i)->start += splitBlock->start;
         newBlock->Add(split->Item(i));
         newNumBlocks++;
      }
      delete split;

      delete[]sumBuffer;
   } else {

      // The final case is that we're inserting at least five blocks.
      // We divide these into three groups: the first two get merged
      // with the first half of the split block, the middle ones get
      // copied in as is, and the last two get merged with the last
      // half of the split block.

      sampleCount srcFirstTwoLen =
          srcBlock->Item(0)->len + srcBlock->Item(1)->len;
      sampleCount leftLen = splitPoint + srcFirstTwoLen;

      sampleType *leftBuffer = new sampleType[leftLen];

      Read(leftBuffer, splitBlock, 0, splitPoint);
      ((WaveTrack *) src)->Get(&leftBuffer[splitPoint], 0, srcFirstTwoLen);

      BlockArray *split = Blockify(leftBuffer, leftLen);
      for (i = 0; i < split->Count(); i++) {
         split->Item(i)->start += splitBlock->start;
         newBlock->Add(split->Item(i));
         newNumBlocks++;
      }
      delete split;
      delete[]leftBuffer;

      for (i = 2; i < srcNumBlocks - 2; i++) {
         WaveBlock *insertBlock = new WaveBlock();
         insertBlock->start = srcBlock->Item(i)->start + s;
         insertBlock->len = srcBlock->Item(i)->len;
         insertBlock->min = srcBlock->Item(i)->min;
         insertBlock->max = srcBlock->Item(i)->max;
         insertBlock->f = dirManager->CopyBlockFile(srcBlock->Item(i)->f);
         if (!insertBlock->f) {
            wxMessageBox("Could not paste!  (Out of disk space?)");
         }

         newBlock->Add(insertBlock);
         newNumBlocks++;
      }

      sampleCount srcLastTwoLen =
          srcBlock->Item(srcNumBlocks - 2)->len +
          srcBlock->Item(srcNumBlocks - 1)->len;
      sampleCount rightSplit = splitBlock->len - splitPoint;
      sampleCount rightLen = rightSplit + srcLastTwoLen;

      sampleType *rightBuffer = new sampleType[rightLen];

      sampleCount lastStart = srcBlock->Item(srcNumBlocks - 2)->start;
      ((WaveTrack *) src)->Get(rightBuffer, lastStart, srcLastTwoLen);
      Read(&rightBuffer[srcLastTwoLen], splitBlock, splitPoint,
           rightSplit);

      sampleCount pos = s + lastStart;

      split = Blockify(rightBuffer, rightLen);
      for (i = 0; i < split->Count(); i++) {
         split->Item(i)->start += pos;
         newBlock->Add(split->Item(i));
         newNumBlocks++;
      }
      delete split;
      delete[]rightBuffer;
   }

   dirManager->Deref(splitBlock->f);
   delete splitBlock;

   // Copy remaining blocks to new block array and
   // swap the new block array in for the old

   for (i = b + 1; i < numBlocks; i++) {
      block->Item(i)->start += addedLen;
      newBlock->Add(block->Item(i));
      newNumBlocks++;
   }

   delete block;
   block = newBlock;

   numSamples += addedLen;

   envelope.SetTrackLen(numSamples / rate);

   ConsistencyCheck("Paste branch three");
}
Exemple #11
0
void WaveTrack::Append(sampleType * buffer, sampleCount len)
{
#if wxUSE_THREADS
   wxMutexLocker lock(*blockMutex);
#endif

   // If the last block is not full, we need to add samples to it
   int numBlocks = block->Count();
   if (numBlocks > 0 && block->Item(numBlocks - 1)->len < minSamples) {
      WaveBlock *lastBlock = block->Item(numBlocks - 1);
      sampleCount addLen;
      if (lastBlock->len + len < maxSamples)
         addLen = len;
      else
         addLen = GetIdealBlockSize() - lastBlock->len;
      sampleCount pos = lastBlock->len;

      WaveBlock *newLastBlock = NewInitedWaveBlock();

      sampleType *buffer2 = new sampleType[lastBlock->len + addLen];
      Read(buffer2, lastBlock, 0, lastBlock->len);

      for (int j = 0; j < addLen; j++)
         buffer2[lastBlock->len + j] = buffer[j];

      newLastBlock->start = lastBlock->start;
      newLastBlock->len = lastBlock->len + addLen;

      FirstWrite(buffer2, newLastBlock, lastBlock->len + addLen);

      delete[]buffer2;

      dirManager->Deref(lastBlock->f);
      delete lastBlock;
      block->Item(numBlocks - 1) = newLastBlock;

      len -= addLen;
      numSamples += addLen;
      buffer += addLen;
   }
   // Append the rest as new blocks
   while (len) {
      sampleCount idealSamples = GetIdealBlockSize();
      sampleCount l = (len > idealSamples ? idealSamples : len);
      WaveBlock *w = new WaveBlock();
      w->f = dirManager->NewBlockFile();
      w->start = numSamples;
      w->len = l;
      bool inited = InitBlock(w);
      wxASSERT(inited);
      FirstWrite(buffer, w, l);
      block->Add(w);

      buffer += l;
      numSamples += l;
      len -= l;
   }

   envelope.SetTrackLen(numSamples / rate);

   ConsistencyCheck("Append");
}
Exemple #12
0
unsigned long UserWinProcedure(HWND Window,HMSG Message,long Param1,long Param2)
{
  int hlist,i,j;
  float Midf;
  switch (Message)
  {
     case DIALOGBOXOK:
            GetPrintPara();
            if (PG.Blocks>0)
                PG.Enable=1;
            else
                PG.Enable=0;
            return(DialogDefaultProcedure(Window, Message, Param1, Param2));
     case DIALOGBOXCANCEL:
            PG.Enable=0;
            return(DialogDefaultProcedure(Window, Message, Param1, Param2));
     case REDRAWMESSAGE:
            i=DialogDefaultProcedure(Window, Message, Param1, Param2);
            WaitMessageEmpty();
            InitOver=1;
            InitPrintCut();
            CurrentBlock=0;
            SetPrintPara();
            REFLASH;
            MessageInsert(PrintCutWin[wPAGEADDWIN],WINDOWINIT,0l,0l);
            ListSetCurrent(WindowList(PrintCutWin[wPAGEADDWIN]),CurrentBlock);
            
            REFLASHADD;
            return i;
            break;
     case WINDOWINIT:
            InitOver=0;

            i=DialogDefaultProcedure(Window, Message, Param1, Param2);
            //WaitMessageEmpty();
            return i;
            break;
     case ADDWIN:
            GetPrintPara();
            if (PG.Blocks<99) PG.Blocks++;
            CurrentBlock=PG.Blocks-1;
            if (CurrentBlock>0) CopyBlock(CurrentBlock,CurrentBlock-1);
            else InitBlock(CurrentBlock);
            SetPrintPara();
            hlist = WindowList(PrintCutWin[wPAGEADDWIN]);
            MessageGo(PrintCutWin[wPAGEADDWIN],WINDOWINIT,0,0);
            MessageGo(PrintCutWin[wPAGEADDWIN],WMPAINT,0,ListGetHeight(hlist)*CHARHEIGHT);
            if (CurrentBlock>=7)
             ListSetTop(hlist,CurrentBlock-7);
            else
            ListSetTop(hlist,0);
            ListSetCurrent(hlist,CurrentBlock);
            MessageGo(PrintCutWin[wPAGEADDWIN],REDRAWMESSAGE,0L,
                MAKELONG(WindowGetWidth(PrintCutWin[wPAGEADDWIN]),
                WindowGetHeight(PrintCutWin[wPAGEADDWIN])) );
            //MessageGo(PrintCutWin[wPAGEADDWIN],KEYDOWN,UP,0l);
            //MessageGo(PrintCutWin[wPAGEADDWIN],KEYDOWN,DOWN,0l);
            //ListSetTop(hlist,0);
            REFLASH;
            break;
     case DELETEWIN:
            GetPrintPara();
            for (i=CurrentBlock+1;i<PG.Blocks;i++) CopyBlock1(i-1,i);
            if (PG.Blocks>0) PG.Blocks--;
            if (CurrentBlock>=PG.Blocks&&CurrentBlock) CurrentBlock=PG.Blocks-1;
            SetPrintPara();
            hlist = WindowList(PrintCutWin[wPAGEADDWIN]);
            MessageGo(PrintCutWin[wPAGEADDWIN],WINDOWINIT,0,0);
            MessageGo(PrintCutWin[wPAGEADDWIN],WMPAINT,0,ListGetHeight(hlist)*CHARHEIGHT);
            if (CurrentBlock>=7)
             ListSetTop(hlist,CurrentBlock-7);
            else
            ListSetTop(hlist,0);
            ListSetCurrent(hlist,CurrentBlock);
            MessageGo(PrintCutWin[wPAGEADDWIN],REDRAWMESSAGE,0L,
                MAKELONG(WindowGetWidth(PrintCutWin[wPAGEADDWIN]),
                WindowGetHeight(PrintCutWin[wPAGEADDWIN])) );
            REFLASH;
            break;
     case DELETETAILWIN:
            GetPrintPara();
            PG.Blocks=CurrentBlock;
            if (CurrentBlock>=PG.Blocks&&CurrentBlock) CurrentBlock=PG.Blocks-1;
            SetPrintPara();
            hlist = WindowList(PrintCutWin[wPAGEADDWIN]);
            MessageGo(PrintCutWin[wPAGEADDWIN],WINDOWINIT,0,0);
            MessageGo(PrintCutWin[wPAGEADDWIN],WMPAINT,0,ListGetHeight(hlist)*CHARHEIGHT);
            if (CurrentBlock>=7)
             ListSetTop(hlist,CurrentBlock-7);
            else
            ListSetTop(hlist,0);
            ListSetCurrent(hlist,CurrentBlock);
            MessageGo(PrintCutWin[wPAGEADDWIN],REDRAWMESSAGE,0L,
                MAKELONG(WindowGetWidth(PrintCutWin[wPAGEADDWIN]),
                WindowGetHeight(PrintCutWin[wPAGEADDWIN])) );
            REFLASH;
            break;
     case COPYWIN:
            i=GetPrintPara();
            if (i<0)
              switch(i)
                {
                    case -99:
                        {
                        if (MessageBox("设置打印纸","     确认您的打印机可使用\n"
                                                    "     您所定义的纸张大小, \n"
                                                    "       否则,打印可能出错!"
                        ,2,1)) break;
                        }
                        PaperW=Tmp1;
                        PaperH=Tmp2;
                        if (PaperW<20.0) PaperW=20.0;
                        if (PaperW>1100.0) PaperW=1100.0;
                        if (PaperH<20.0) PaperH=20.0;
                        if (PaperH>1100.0) PaperH=1100.0;
                        printer->xpixel=PaperW*PrinterDPI/25.4;
                        printer->ypixel=PaperH*PrinterDPI/25.4;
                        InitPrintCut();
                        break;
                    case -5:               //Tmp1 = Scale
                        Tmp2=PageH*Tmp4;
                        Tmp1=PageW*Tmp3;
                        if (PG.Blocks)
                        {
                          j=(PG.PageBlock[0].Rotate&1);

                        }
                        else
                          j=0;
                        if (j)
                          {
                            Midf=Tmp2;
                            Tmp2=Tmp1;
                            Tmp1=Midf;
                          }
                    case -1:

                        if (Tmp1>5.0f)
                        {
                            Midf=0.0f;
                            ColLeadNum=0;
                            while (Midf+Tmp1<PaperW)
                             {
                                Midf +=Tmp1;
                                ColLead[ColLeadNum++]=Midf;
                             }
                        }

                        if (Tmp2>5.0f)
                        {
                            Midf=0.0f;
                            RowLeadNum=0;
                            while (Midf+Tmp1<PaperH)
                             {
                                Midf +=Tmp2;
                                RowLead[RowLeadNum++]=Midf;
                             }
                        }
                        break;
                    case -2:
                        ColLeadNum=0;
                        RowLeadNum=0;
                        break;
                    case -3:
                        ColLeadNum=0;
                        break;
                    case -4:
                        RowLeadNum=0;
                        break;
                    case -6:             //Auto Scale Fit
                        if (!PG.Blocks) break;
                        PG.Blocks=0;
                        CurrentBlock=0;
                        hlist=PG.PageBlock[0].Rotate;
                        for (i=0;i<RowLeadNum;i++)
                        {
                         for (j=0;j<ColLeadNum;j++)
                          {
                              if (GetColWidth(j)-5.0f>Tmp1+Tmp3&&
                                 GetRowHeight(i)-5.0f>Tmp2+Tmp4)
                              {
                                if (hlist&1)
                                {
                                    PG.PageBlock[PG.Blocks].Yscale=(GetColWidth(j)-Tmp1-Tmp3)/PageH;
                                    PG.PageBlock[PG.Blocks].Xscale=(GetRowHeight(i)-Tmp2-Tmp4)/PageW;
                                }
                                else
                                {
                                    PG.PageBlock[PG.Blocks].Xscale=(GetColWidth(j)-Tmp1-Tmp3)/PageW;
                                    PG.PageBlock[PG.Blocks].Yscale=(GetRowHeight(i)-Tmp2-Tmp4)/PageH;
                                }

                                PG.PageBlock[PG.Blocks].Xoffset=GetColOffset(j)+Tmp1;
                                PG.PageBlock[PG.Blocks].Yoffset=GetRowOffset(i)+Tmp3;
                                PG.PageBlock[PG.Blocks].PageOffset=0;
                                PG.PageBlock[PG.Blocks++].Rotate=hlist;
                              }
                              if (PG.Blocks>=99) break;
                          }
                          if (PG.Blocks>=99) break;
                        }
                        break;
                    case -7:             //Auto Scale Fit
                        if (!PG.Blocks) break;
                        PG.Blocks=0;
                        CurrentBlock=0;
                        hlist=PG.PageBlock[0].Rotate;
                        for (i=0;i<=RowLeadNum;i++)
                        {
                         for (j=0;j<=ColLeadNum;j++)
                          {
                              if (GetColWidth(j)-5.0f>Tmp1+Tmp3&&
                                 GetRowHeight(i)-5.0f>Tmp2+Tmp4)
                              {
                                if (hlist&1)
                                {
                                    PG.PageBlock[PG.Blocks].Yscale=(GetColWidth(j)-Tmp1-Tmp3)/PageH;
                                    PG.PageBlock[PG.Blocks].Xscale=(GetRowHeight(i)-Tmp2-Tmp4)/PageW;
                                }
                                else
                                {
                                    PG.PageBlock[PG.Blocks].Xscale=(GetColWidth(j)-Tmp1-Tmp3)/PageW;
                                    PG.PageBlock[PG.Blocks].Yscale=(GetRowHeight(i)-Tmp2-Tmp4)/PageH;
                                }

                                PG.PageBlock[PG.Blocks].Xoffset=GetColOffset(j)+Tmp1;
                                PG.PageBlock[PG.Blocks].Yoffset=GetRowOffset(i)+Tmp3;
                                PG.PageBlock[PG.Blocks].PageOffset=0;
                                PG.PageBlock[PG.Blocks++].Rotate=hlist;
                              }
                              if (PG.Blocks>=99) break;
                          }
                          if (PG.Blocks>=99) break;
                        }
                        break;

                    case -8:
                        if (!PG.Blocks) break;
                        PG.Blocks=0;
                        CurrentBlock=0;
                        for (i=0;i<RowLeadNum;i++)
                        {
                         for (j=0;j<ColLeadNum;j++)
                          {
                              if (GetColWidth(j)-5.0f>Tmp1&&
                                 GetRowHeight(i)-5.0f>Tmp2)
                              {
                                PG.PageBlock[PG.Blocks].Xoffset=GetColOffset(j)+Tmp1;
                                PG.PageBlock[PG.Blocks].Yoffset=GetRowOffset(i)+Tmp2;
                                PG.PageBlock[PG.Blocks].Xscale=PG.PageBlock[0].Xscale;
                                PG.PageBlock[PG.Blocks].Yscale=PG.PageBlock[0].Yscale;
                                PG.PageBlock[PG.Blocks].PageOffset=0;
                                PG.PageBlock[PG.Blocks++].Rotate=PG.PageBlock[0].Rotate;
                              }
                              if (PG.Blocks>=99) break;
                          }
                          if (PG.Blocks>=99) break;
                        }
                        break;
                    case -9:
                        if (!PG.Blocks) break;
                        PG.Blocks=0;
                        CurrentBlock=0;
                        for (i=0;i<=RowLeadNum;i++)
                        {
                         for (j=0;j<=ColLeadNum;j++)
                          {
                              if (GetColWidth(j)-5.0f>Tmp1&&
                                 GetRowHeight(i)-5.0f>Tmp2)
                              {
                                PG.PageBlock[PG.Blocks].Xoffset=GetColOffset(j)+Tmp1;
                                PG.PageBlock[PG.Blocks].Yoffset=GetRowOffset(i)+Tmp2;
                                PG.PageBlock[PG.Blocks].Xscale=PG.PageBlock[0].Xscale;
                                PG.PageBlock[PG.Blocks].Yscale=PG.PageBlock[0].Yscale;
                                PG.PageBlock[PG.Blocks].PageOffset=0;
                                PG.PageBlock[PG.Blocks++].Rotate=PG.PageBlock[0].Rotate;
                              }
                              if (PG.Blocks>=99) break;
                          }
                          if (PG.Blocks>=99) break;
                        }
                        break;

                }
            REFLASH;
            REFLASHADD;
            break;
     default:
            return(DialogDefaultProcedure(Window, Message, Param1, Param2));
  }
  /* return(DialogDefaultProcedure(Window, Message, Param1, Param2)); */
  return(TRUE);
}