⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spbufferwnd.cpp

📁 窗口类CBufferWnd:能够作为子窗口或者时弹出窗口支持滚动
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//		TRACE("txt appened ScrollIfPointNotShown(%d,%d);\n",iNewX,iNewY);
		ScrollIfPointNotShown(iNewX,iNewY);

	}
	Invalidate();
}

BOOL CBufferWnd::IsSecondByteOfDBCS(int iX,int iY)
{//从第一个自己开始计算,直到查找到指定字节
	ASSERT(iX>=0 && iY>=0);
	ASSERT(iX<m_iWidthBuf);
	ASSERT(iY<m_iHeightBuf);
	int iStart=0;
	while(1)
	{
		if(IsDBCSLeadByte(m_pbBuffer[iY*m_iWidthBuf + iStart]))
		{
			iStart ++;
			if(iStart == iX)
				return TRUE;
			iStart++;
		}
		else
			iStart++;
		if(iStart >=iX)
			return FALSE;
	}
	return FALSE;
}

//绘制窗口
//step 1 找到有效窗口尺寸= 窗口实际尺寸+窗口滚动位置
//step 2 根据有效窗口尺寸绘制
//
void CBufferWnd::PaintWnd(CDC* pDC)
{//bug 在可视窗口边界出现半个汉字时会出现错误
	//step 1
	int iXPos= GetScrollPos(SB_HORZ );
	int iYPos= GetScrollPos(SB_VERT );
	CSize sizeShow(m_sizeIndeed.cx +iXPos, m_sizeIndeed.cy +iYPos);

	//step 2
	CMemDC mDC(pDC);
	CRect rcClient;
	GetClientRect(rcClient);
	mDC.FillSolidRect( rcClient, m_crBackground );
	mDC.SetBkMode(TRANSPARENT);
	mDC.SetTextColor(m_crFont);
	CFont* pOF = mDC.SelectObject(m_ftDraw);
	for(int y=0;y<m_sizeIndeedDraw.cy && y+iYPos<m_iHeightBuf ;y++)
	{
		for(int x=0;x<m_sizeIndeedDraw.cx && x+iXPos<m_iWidthBuf ;x++)
		{
			int iX= x+iXPos;
			int iY= y+iYPos;
			ASSERT(iY*m_iWidthBuf + iX < m_iWidthBuf * m_iHeightBuf);
			char cOut=m_pbBuffer[iY*m_iWidthBuf + iX];
			//2003/08/16 modify wenyy
			if(x==0 && iX!=0 && IsSecondByteOfDBCS(iX,iY) )
			{//是否每行的第一个输出的字符,并且是中文的第二个字节
				cOut=0x20;
				mDC.TextOut(x*m_iFontWidth ,y*m_iFontHeight ,&cOut,1);
			}
			else
			{
				if( x != m_iWidthBuf-1 && IsDBCSLeadByte(cOut) )// isleadbyte
				{//DBCS中文字符,并且不是最后一个字符
					char cOutDBCS[2];
					cOutDBCS[0]=cOut;
					cOutDBCS[1]=m_pbBuffer[iY*m_iWidthBuf + iX + 1];
					mDC.TextOut(x*m_iFontWidth ,y*m_iFontHeight ,cOutDBCS,2); 
					x++;
				}
				else
					mDC.TextOut(x*m_iFontWidth ,y*m_iFontHeight ,&cOut,1);
			}
		}
	}
	mDC.SelectObject(pOF);
}

void CBufferWnd::ScrollTxtUp(int iLines,char cFill)
{
	ASSERT(iLines<= m_iHeightBuf);
	int iCopy = (m_iHeightBuf - iLines) * m_iWidthBuf;
	int iStart = iLines * m_iWidthBuf;
//	int iTotal = m_iWidthBuf*m_iHeightBuf;
//	int iNeedCopy = max(iTotal-iCopy,iCopy);
	for(int i=0;i<iCopy;i++)
	{
		m_pbBuffer[i]=m_pbBuffer[i+iStart];
	}
	memset(m_pbBuffer+iCopy,cFill,iStart);
	Invalidate(FALSE);
}

BEGIN_MESSAGE_MAP(CBufferWnd, CWnd)
	ON_MESSAGE( WM_BW_NOTIFY,OnBWndNotifyMsg )
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONDBLCLK()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_CLOSE()
END_MESSAGE_MAP()

// CBufferWnd 消息处理程序
void CBufferWnd::NotifyParent(UINT msg)
{
   if (!::IsWindow(m_hWnd))
   {
      return;
   }

   CWnd *pParent = GetParent();
   if (pParent)
   {
	   WPARAM wParam = (WPARAM) MAKEWPARAM(m_nWndID, msg);
	   LPARAM lParam = (LPARAM) GetSafeHwnd();
	   pParent->SendMessage(WM_COMMAND, wParam, lParam);
   }
}

LRESULT CBufferWnd::OnBWndNotifyMsg(WPARAM wP, LPARAM lP)
{
	if(wP == 0)
	{
		int iLines = HIWORD(lP);
		int iFill = LOBYTE(LOWORD(lP));
		TRACE("need ScrollTxtUp %d\n",iLines);
		ScrollTxtUp(iLines,iFill);
	}
	else if(wP == 1)
	{
		struct strAppendTxt* pAT = (struct strAppendTxt*)lP;
		AppendTxtAtCaret(pAT->iTxtLen,pAT->pszTxt,pAT->fShowY,pAT->fShowX);
	}
	return 0;
}

void CBufferWnd::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	PaintWnd(&dc);

}

BOOL CBufferWnd::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	return CWnd::OnEraseBkgnd(pDC);
}

void CBufferWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// Get the minimum and maximum scroll-bar positions.
	int minpos;
	int maxpos;
	GetScrollRange(SB_HORZ ,&minpos, &maxpos); 
	
	// Get the current position of scroll box.
	int oldpos= GetScrollPos(SB_HORZ );
	int curpos =oldpos;
	
	// Determine the new position of scroll box.
	switch (nSBCode)
	{
	case SB_LEFT:      // Scroll to far left.
		curpos = minpos;
		break;
		
	case SB_RIGHT:      // Scroll to far right.
		curpos = maxpos;
		break;
		
	case SB_ENDSCROLL:   // End scroll.
		break;
		
	case SB_LINELEFT:      // Scroll left.
		if (curpos > minpos)
			curpos--;
		break;
		
	case SB_LINERIGHT:   // Scroll right.
		if (curpos < maxpos)
			curpos++;
		break;
		
	case SB_PAGELEFT:    // Scroll one page left.
		{
			
			if (curpos > minpos)
				curpos = max(minpos, curpos - HSCROLL_PAGE_SIZE);
		}
		break;
		
	case SB_PAGERIGHT:      // Scroll one page right.
		{
			if (curpos < maxpos)
				curpos = min(maxpos, curpos + HSCROLL_PAGE_SIZE);
		}
		break;
		
	case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
		curpos = nPos;      // of the scroll box at the end of the drag operation.
		break;
		
	case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
		curpos = nPos;     // position that the scroll box has been dragged to.
		break;
	}
	
	// Set the new position of the thumb (scroll box).
	if(oldpos != curpos)
	{
		SetScrollPos(SB_HORZ,curpos);
		Invalidate(FALSE);
//		TRACE("set hscroll %d\n",curpos);
		OpenCaretAsNecessary();
	}
	SetFocus();
	CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CBufferWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	int minpos;
	int maxpos;
	GetScrollRange(SB_VERT ,&minpos, &maxpos); 
	
	// Get the current position of scroll box.
	int oldpos= GetScrollPos(SB_VERT );
	int curpos =oldpos;
	
	// Determine the new position of scroll box.
	switch (nSBCode)
	{
	case SB_TOP:      // Scroll to far left.
		curpos = minpos;
		break;
		
	case SB_BOTTOM:      // Scroll to far right.
		curpos = maxpos;
		break;
		
	case SB_ENDSCROLL:   // End scroll.
		break;
		
	case SB_LINEUP:      // Scroll left.
		if (curpos > minpos)
			curpos--;
		break;
		
	case SB_LINEDOWN:   // Scroll right.
		if (curpos < maxpos)
			curpos++;
		break;
		
	case SB_PAGEUP:    // Scroll one page left.
		{
			
			if (curpos > minpos)
				curpos = max(minpos, curpos - VSCROLL_PAGE_SIZE);
		}
		break;
		
	case SB_PAGEDOWN:      // Scroll one page right.
		{
			if (curpos < maxpos)
				curpos = min(maxpos, curpos + VSCROLL_PAGE_SIZE);
		}
		break;
		
	case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
		curpos = nPos;      // of the scroll box at the end of the drag operation.
		break;
		
	case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
		curpos = nPos;     // position that the scroll box has been dragged to.
		break;
	}
	
	// Set the new position of the thumb (scroll box).
	if(oldpos != curpos)
	{
		SetScrollPos(SB_VERT,curpos);
		Invalidate(FALSE);
//		TRACE("set vscroll %d\n",curpos);
		OpenCaretAsNecessary();
	}
	SetFocus();
	CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CBufferWnd::OnSize(UINT nType, int cx, int cy)
{
   if (!::IsWindow(m_hWnd))
	   ReCalcScrollSize();

	CWnd::OnSize(nType, cx, cy);
}

void CBufferWnd::OnSetFocus(CWnd* pOldWnd)
{
//	TRACE("enter OnSetFocus()\n");
	OpenCaretAsNecessary();
	NotifyParent(EN_SETFOCUS);
	CWnd::OnSetFocus(pOldWnd);
}

void CBufferWnd::OnKillFocus(CWnd* pNewWnd)
{
	CloseCaret();
	NotifyParent(EN_KILLFOCUS);
	CWnd::OnKillFocus(pNewWnd);
}

void CBufferWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	SetFocus();
	CWnd::OnLButtonDown(nFlags, point);
}

void CBufferWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	SetFocus();

	CWnd::OnLButtonDblClk(nFlags, point);
}

void CBufferWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	SetFocus();

	CWnd::OnRButtonDown(nFlags, point);
}

void CBufferWnd::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	SetFocus();

	CWnd::OnRButtonDblClk(nFlags, point);
}

void spBase::CBufferWnd::OnDestroy()
{
	if(m_fCanExit)
		CWnd::OnDestroy();

	// TODO: 在此添加消息处理程序代码
}

void spBase::CBufferWnd::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if(m_fCanExit)
		CWnd::OnClose();
}

⌨️ 快捷键说明

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