displaydlg.cpp

来自「winsail v2.0是用于DOS下的图形界面空间系统」· C++ 代码 · 共 1,590 行 · 第 1/3 页

CPP
1,590
字号
			//是否返回结果
			if(pTreeNode_Target != NULL)
			{
				return (pTreeNode_Target);
			}

			//度计算
			m_nDegree--;
			//访问根结点
			pTreeNode_Target = this->VisitTree(
				pTreeNode, m_pVisitUser, m_pnCol[m_nDegree - 1]);
			//列计算
			if (m_pnCol != NULL)
			{
				m_pnCol[m_nDegree - 1] += 1;
			}
			//是否是返回结果
			if (pTreeNode_Target != NULL)
			{
				return(pTreeNode_Target);
			}

			break;
		}
		//其它
		default:
		{
			break;
		}
	}
	m_nDegree = nOldDegree;
	return(NULL);
}


//函数功能:遍历操作
CTreeNode* CBinaryTree::TraverseBinaryTree(
	CTreeNode* (*pFc)(CTree* pTree, CTreeNode*, void*, int, int), 
	void* pUser, int nStyle)
{
	m_nDegree = 0;
	if (pFc == CTree::CalcDegreeFc)
	{
		m_nMaxDegree = 0;
	}
	//根结点不能为空
	if (m_pRoot == NULL)
	{
		return(NULL);
	}
	
	//设置“度”= 0
	m_nDegree = 1;
	if (pFc == CTree::CalcDegreeFc)
	{
		m_nMaxDegree = 1;
	}
	//列
	m_pnCol = new int[MAX_TREE_DEGREE];
	for (int i = 0; i < MAX_TREE_DEGREE; i++)
	{
		m_pnCol[i] = 0;
	}

	//设置遍历的类型
	this->SetVisitStyle(nStyle);
	//设置遍历的内容
	this->SetVisitUser(pUser);
	//设置遍历函数
	this->SetVisitFc(pFc);

	//从根结点开始遍历
	CTreeNode* pTreeNode = this->TraverseBinaryTree(m_pRoot);

	//删除列
	delete m_pnCol;
	m_pnCol = NULL;

	//返回遍历结果
	return (pTreeNode);
}




void CBinaryTree::CalcCoordinate(RECT* pRc, int nMaxDegree, 
	int nDegree, int nCol, int* pnLeft, int* pnTop)
{
	int nLeft, nTop;	
	//计算最大度的总列数
	int nNodes = 1 << (nMaxDegree - 1);

	//计算“当前度”结点Y向距离
	float fInternalY = 0.0f;
	if (nMaxDegree > 1)
	{
		fInternalY = 1.0f * (pRc->bottom - pRc->top) / (nMaxDegree - 1);
	}

	//计算“最大度”的X向分隔距离
	float fInternalX = 0.0f;
	if (nMaxDegree > 1)
	{
		fInternalX = 1.0f * (pRc->right - pRc->left) / (nNodes - 1);
	}

	//计算“当前度”的Y向坐标值
	nTop = (int)(pRc->top + fInternalY * (nDegree - 1));

	//如果是第一个度
	if (nDegree == 1)
	{
		nLeft = (int)(pRc->left + pRc->right)/2;
	}
	//中间的度
	else if (nDegree != nMaxDegree)
	{
		int nColR1 = (nCol + 1) * (1 << (nMaxDegree - nDegree)) - 1;
		int nColR2 = (nCol + 0) * (1 << (nMaxDegree - nDegree)) + 0;

		int nLeft1 = (int)(pRc->left + nColR1 * fInternalX);
		int nLeft2 = (int)(pRc->left + nColR2 * fInternalX);

		nLeft = (nLeft1 + nLeft2)/2;
	}
	//如果是最后的度
	else
	{
		nLeft = (int)(pRc->left + nCol * fInternalX);
	}

	//计算横向坐标值
	if (pnLeft != NULL)
	{
		*pnLeft = nLeft;
	}

	//计算纵向坐标值
	if (pnTop != NULL)
	{
		*pnTop  = nTop;
	}
}


//遍历筛选函数
CTreeNode* DisplayFc(CTree* pTree, CTreeNode* pTreeNode, void* pUser, int nDegree, int nCol)
{

	RECT* pRc =  (RECT *)pUser;

	CWindowDC  mDC(AfxGetApp()->m_pMainWnd);//->GetSafeHwnd());
	mDC.MoveTo(pRc->left, pRc->top);
	mDC.LineTo(pRc->right, pRc->top);
	mDC.LineTo(pRc->right, pRc->bottom);
	mDC.LineTo(pRc->left, pRc->bottom);
	mDC.LineTo(pRc->left, pRc->top);


	int nMaxDegree= pTree->GetMaxDegree();

	int nLeft1, nLeft2, nTop1, nTop2, nLeft3, nTop3;
	CBinaryTree::CalcCoordinate(pRc, nMaxDegree, 
		nDegree, nCol, &nLeft1, &nTop1);



	if (nDegree > 1)
	{
		if ((nCol % 2) == 0) 
		{
			CBinaryTree::CalcCoordinate(pRc, nMaxDegree, 
				nDegree, nCol + 1, &nLeft2, &nTop2);
		}
		else
		{
			CBinaryTree::CalcCoordinate(pRc, nMaxDegree, 
				nDegree, nCol - 1, &nLeft2, &nTop2);
		}
		
		CBinaryTree::CalcCoordinate(pRc, nMaxDegree, 
			nDegree - 1, nCol/2, &nLeft3, &nTop3);

		mDC.MoveTo(nLeft1, nTop1);
		mDC.LineTo(nLeft3, nTop3);
	}
	
	//画圆
	mDC.Ellipse(nLeft1-3, nTop1-3, nLeft1+3, nTop1+3);

	int nNodes = 1 << (nMaxDegree - 1);	
	float fInternalX = 0.0f;
	if (nMaxDegree > 1)
	{
		fInternalX = 1.0f * (pRc->right - pRc->left) / (nNodes - 1);
	}
	float fInternalY = 0.0f;
	if (nMaxDegree > 1)
	{
		fInternalY = 1.0f * (pRc->bottom - pRc->top) / (nMaxDegree - 1);
	}

	for (int i = 0; i < nNodes; i++)
	{
		for (int j = 0; j < nMaxDegree; j++)
		{
			int nLeft5 = (int)(pRc->left + i * fInternalX);
			int nTop5 = (int)(pRc->bottom - j * fInternalY);
			mDC.Ellipse(nLeft5-1, nTop5-1, nLeft5+1, nTop5+1);
		}

	}


	return(NULL);
}

char bysCh[100] = {
	'-', 
	'+',
	'/',
	'a',
	'*',
	'e',
	'f',
	'b',
	'-',
	'c',
	'd'};
void CDisplayDlg::OnOK() 
{
	// TODO: Add extra validation here

	CTreeNode msTreeNode[100];
	for (int i = 0; i < 100; i++)
	{
		memset(&msTreeNode[i], 0 ,sizeof(CTreeNode));
		msTreeNode[i].pUser = (void *)(DWORD)bysCh[i];
	}

	CBinaryTree mBinaryTree;
	mBinaryTree.InitiateTree();
	mBinaryTree.BuildBinaryTree(&msTreeNode[0], &msTreeNode[1], &msTreeNode[2]);

	mBinaryTree.InsertChildL(&msTreeNode[1], &msTreeNode[3]);
	mBinaryTree.InsertChildR(&msTreeNode[1], &msTreeNode[4]);

	mBinaryTree.InsertChildL(&msTreeNode[2], &msTreeNode[5]);
	mBinaryTree.InsertChildR(&msTreeNode[2], &msTreeNode[6]);

	mBinaryTree.InsertChildL(&msTreeNode[4], &msTreeNode[7]);
	mBinaryTree.InsertChildR(&msTreeNode[4], &msTreeNode[8]);

	mBinaryTree.InsertChildL(&msTreeNode[8], &msTreeNode[9]);
	mBinaryTree.InsertChildR(&msTreeNode[8], &msTreeNode[10]);

	//计算树的度
	mBinaryTree.CalcMaxDegree();

	//显示
	RECT rc;
	rc.left  = 200;
	rc.top = 200;
	rc.right = 500;
	rc.bottom = 500;
	mBinaryTree.TraverseBinaryTree(DisplayFc, &rc, TRAVERSING_BINARYTREE_LAST);



	//CDialog::OnOK();
}

#define COMM_BASE_COM1 0x3F8
#define COMM_BASE_COM2 0x2F8
#define COMM_BASE_COM3 0x3E8
#define COMM_BASE_COM4 0x2E8

struct WORDREGS 
{
	unsigned int ax, bx, cx, dx, si, di,cflag, flags;
}; 

struct BYTEREGS 
{
	unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};

union REGS 
{
	struct WORDREGS x;
	struct BYTEREGS h;
};


int  int86(int intno, union REGS *inregs, union REGS *outregs);

BOOL InitCommEx_Rs232Bios(int nBase, WORD wBaud, int nDataBit, 
	int nStopBit, int nEvenOdd, WORD* pwState)
{
	//AH = 0 初始化端口
	//AH = 1 向串口写字符
	//AH = 2 从串口读字符
	//AH = 3 取通讯口状态
	//AH = 4 扩充的初始化状态
	//AH = 5 扩充的通信口控制
	
	//dx = 0 COMM1
	//dx = 1 COMM2
	//dx = 2 COMM3
	//dx = 3 COMM4

	int nComm = 0;
	if (nBase == COMM_BASE_COM1) nComm = 0;
	if (nBase == COMM_BASE_COM2) nComm = 1;
	if (nBase == COMM_BASE_COM3) nComm = 2;
	if (nBase == COMM_BASE_COM4) nComm = 3;

	REGS mRegsIn, mRegsOut;

	do
	{
		//奇偶性
		mRegsIn.h.bh = nEvenOdd;
		//停止位
		mRegsIn.h.bl = nStopBit & 0x1;
		//数据位
		mRegsIn.h.ch = (BYTE)(nDataBit - 5);
		//设置波特率
		mRegsIn.h.cl = (BYTE)(0.5 + log((BYTE)(wBaud / 150)) / log(2));
		
		//扩展初始化端口,中断14H功能--AH=4子功能调用
		mRegsIn.h.ah = 4; 
		mRegsIn.x.dx = (BYTE)nComm;
		::int86(0x14, &mRegsIn, &mRegsOut);
	}while(mRegsOut.h.ah >= (BYTE)0x80u);
	
	if (NULL != pwState)
	{
		*pwState = mRegsOut.x.ax;
	}

	return(TRUE);
}

BOOL ReadState_Rs232Bios(int nBase, WORD* pwState)
{
	//AH = 0 初始化端口
	//AH = 1 向串口写字符
	//AH = 2 从串口读字符
	//AH = 3 取通讯口状态
	//AH = 4 扩充的初始化状态
	//AH = 5 扩充的通信口控制
	
	//dx = 0 COMM1
	//dx = 1 COMM2
	//dx = 2 COMM3
	//dx = 3 COMM4

	int nComm = 0;
	if (nBase == COMM_BASE_COM1) nComm = 0;
	if (nBase == COMM_BASE_COM2) nComm = 1;
	if (nBase == COMM_BASE_COM3) nComm = 2;
	if (nBase == COMM_BASE_COM4) nComm = 3;

	REGS mRegsIn, mRegsOut;

	//取通讯口状态,中断14H功能--AH=3子功能调用
	mRegsIn.h.ah = 3; //取通讯口状态
	mRegsIn.x.dx = nComm;
	::int86(0x14, &mRegsIn, &mRegsOut);

	if (NULL != pwState)
	{
		*pwState = mRegsOut.x.ax;
	}

	return (TRUE);
}

BOOL WriteData_Rs232Bios(int nBase, BYTE * pBuffer, int nLength)
{
	//AH = 0 初始化端口
	//AH = 1 向串口写字符
	//AH = 2 从串口读字符
	//AH = 3 取通讯口状态
	//AH = 4 扩充的初始化状态
	//AH = 5 扩充的通信口控制
	
	//dx = 0 COMM1
	//dx = 1 COMM2
	//dx = 2 COMM3
	//dx = 3 COMM4

	int nComm = 0;
	if (nBase == COMM_BASE_COM1) nComm = 0;
	if (nBase == COMM_BASE_COM2) nComm = 1;
	if (nBase == COMM_BASE_COM3) nComm = 2;
	if (nBase == COMM_BASE_COM4) nComm = 3;

	REGS mRegsIn, mRegsOut;
	for (int i = 1; i < nLength; i++)
	{
		do
		{
			//向串口写字符,中断14H功能--AH = 1子功能调用
			mRegsIn.h.ah = 1;
			mRegsIn.h.al = *pBuffer;
			mRegsIn.x.dx = nComm;
			::int86(0x14, &mRegsIn, &mRegsOut);
		}while(mRegsOut.h.ah >= (BYTE)0x80u);
		
		pBuffer++;
	}
	
	return (TRUE);
}


BOOL ReadData_Rs232Bios(int  nBase, BYTE* pBuffer, int nLength)
{
	//AH = 0 初始化端口
	//AH = 1 向串口写字符
	//AH = 2 从串口读字符
	//AH = 3 取通讯口状态
	//AH = 4 扩充的初始化状态
	//AH = 5 扩充的通信口控制
	
	//dx = 0 COMM1
	//dx = 1 COMM2
	//dx = 2 COMM3
	//dx = 3 COMM4

	int nComm = 0;
	if (nBase == COMM_BASE_COM1) nComm = 0;
	if (nBase == COMM_BASE_COM2) nComm = 1;
	if (nBase == COMM_BASE_COM3) nComm = 2;
	if (nBase == COMM_BASE_COM4) nComm = 3;

	REGS mRegsIn, mRegsOut;

	for (int i = 0; i < nLength; i++)
	{
		do
		{
			//从串口读字符,中断14H功能--AH = 2子功能调用
			mRegsIn.h.ah = 2; 
			mRegsIn.x.dx = nComm;
			::int86(0x14, &mRegsIn, &mRegsOut);
		}while(mRegsOut.h.ah >= (BYTE)0x80u);
	}

	return(TRUE);
}

#define  COMM_BUFFER_SIZE 1024




#define  interrupt
#define  inportb(a) _inp(a)
#define  outportb(a, b) _outp(a, b)
void setvect (int interruptno, void interrupt (*isr) ());


char bufAfxComm1[COMM_BUFFER_SIZE];
int  nAfxCommPoint1 = 0;

void interrupt _Comm1Int()
{
	int nState;
	do
	{
		nState  = inportb(COMM_BASE_COM1 + 5);
		if (nState &1)
		{
			bufAfxComm1[nAfxCommPoint1++] = inportb(COMM_BASE_COM1);
			if (nAfxCommPoint1 >= COMM_BUFFER_SIZE)
			{
				nAfxCommPoint1 = 0;
			}
		}
	}while (nState &1);
	outportb(0x20, 0x20);
}


void InitComm_Rs232Interrupt(int nBase)
{
	/* PORT 1 - Communication Settings */
	outportb(nBase + 3, 0x80); /* SET DLAB ON */
	outportb(nBase + 0, 0x0C); /* Set Baud rate - Divisor Latch Low Byte */
	/* Default 0x03 = 38,400 BPS */
	/* 0x01 = 115,200 BPS */
	/* 0x02 = 57,600 BPS */
	/* 0x06 = 19,200 BPS */
	/* 0x0C = 9,600 BPS */
	/* 0x18 = 4,800 BPS */
	/* 0x30 = 2,400 BPS */

	outportb(nBase + 1, 0x00); /* Set Baud rate - Divisor Latch High Byte */
	outportb(nBase + 3, 0x03); /* 8 Bits, No Parity, 1 Stop Bit */
	outportb(nBase + 2, 0xC7); /* FIFO Control Register */
	outportb(nBase + 4, 0x0B); /* Turn on DTR, RTS, and OUT2 */

	outportb(0x21, (inportb(0x21) &0xEF)); /* Set Programmable Interrupt Controller */
	/* COM1 (IRQ4) - 0xEF */
	/* COM2 (IRQ3) - 0xF7 */
	/* COM3 (IRQ4) - 0xEF */
	/* COM4 (IRQ3) - 0xF7 */

	outportb(nBase + 1, 0x01); /* Interrupt when data received */
}

void CloseComm_Re232Interrupt(int nBase)
{
	outportb(nBase + 1, 0);
	
	// 关闭COM口的IRQ
	if (nBase == COMM_BASE_COM1 || nBase == COMM_BASE_COM3)
	{
		outportb(0x21, (inportb(0x21) | 0x10)); /* MASK IRQ using PIC */
	}
	else
	{
		outportb(0x21, (inportb(0x21) | 0x10)); /* MASK IRQ using PIC */
	}
}

//CProgress

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?