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

📄 datashowview.cpp

📁 串口收发工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DataShowView.cpp : implementation of the CDataShowView class
//

#include "stdafx.h"
#include "DataShowView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDataShowView
IMPLEMENT_DYNCREATE(CDataShowView, CView)

CDataShowView::CDataShowView()
{
	m_bufferbytes=1000;//表示缓冲的大小
	m_bmousedown=FALSE;//鼠标左键是否按下
	m_selfrom=-1;//表示选中的范围,m_selfrom为-1表示未选中
	m_selto=0;
	m_firstsel=-1;//表示选中的起始位置
	m_bfrozen=FALSE;//表示是否冻结屏幕
	m_btimer=0;//当鼠标位于窗口上方和下方时,屏幕自动向上向下卷屏的定时器;2为上,1为下
	m_specialbyte=(BYTE)0x01;//表示以特殊颜色显示的字符
	m_bpointing=FALSE;//表示正在指定特殊字符
	m_oldcharpos=-1;//上指向的字符位置
}

CDataShowView::~CDataShowView()
{
}


BEGIN_MESSAGE_MAP(CDataShowView,CView )
	//{{AFX_MSG_MAP(CDataShowView)
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_CREATE()
	ON_WM_VSCROLL()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
	ON_COMMAND(1001, OnFreezeScreen)
	ON_COMMAND(1003, OnCopyData)
	ON_COMMAND(1002, OnCopyDisp)
	ON_COMMAND(1004, OnSelectAll)
	ON_COMMAND(1005, OnSetSpByte)
	ON_COMMAND(1006, OnClearWindow)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CDataShowView message handlers

BOOL CDataShowView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CView::PreCreateWindow(cs))
		return FALSE;

//	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.style|=WS_VSCROLL;
	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_IBEAM),HBRUSH(COLOR_WINDOW+1), NULL);//HBRUSH(COLOR_WINDOW+1)

	return TRUE;
}


///////////////////////////////////////////////////
//函数OnSize,在本函数中,确定窗口中显示的字符行数
//和每行字符的显示个数,另外设置滚动轴的范围和位置
//////////////////////////////////////////////////
void CDataShowView::OnSize(UINT nType, int cx, int cy) 
{
	//*weiyi begin
	m_bytesperline=(cx/8-2)/4;
//	weiyi end 在窗口中只显示16进制格式的数据*/
//	m_bytesperline=cx/24;

	m_linesshown=cy/15;
	if(m_bytesperline<1)
		m_bytesperline=1;
//	if(m_linesshown<0)
//		m_linesshown=0;


	CView ::OnSize(nType, cx, cy);
	if(cx!=0 && cy!=0)
	{
		int size=m_bytes.GetSize()/m_bytesperline;
		if(m_bytes.GetSize()%m_bytesperline ==0)
			size--;
		if(size<=0)
			size=1;
		SetScrollRange(SB_VERT,0,size);
		if(size==1)
			SetScrollPos(SB_VERT,0);
		else 
			SetScrollPos(SB_VERT,size);
	}
	
	// TODO: Add your message handler code here
	
}
/////////////////////////////////////////////////////
//函数:ShowData,功能是将一些字符放入显示缓冲区,并且
//在窗口中滚动显示出来。需要控制缓冲区的大小和滚动条的
//范围和位置。
//////////////////////////////////////////////////////
void CDataShowView::ShowData(BYTE *pbyte, int nlen)
{
	if(m_bfrozen)
		return;
	//将对m_bytes的操作作为临界区,使用临界区操作命令
	//进入临界区,如果已经有线程在临界区里了,则等待,
	//一直到没有线程在临界区里
	EnterCriticalSection(&cs);

	for(int i=0;i<nlen;i++)
		m_bytes.Add(pbyte[i]);
	int oldpos=GetScrollPos(SB_VERT);
	int removed=0;
	if(m_bytes.GetSize()>m_bufferbytes)
	{
		//保证每次竖直滚动,即每次从缓冲区刷出的字符为每行字符个数的倍数
		removed=(m_bytes.GetSize()-m_bufferbytes)/m_bytesperline*m_bytesperline;
		m_bytes.RemoveAt(0,removed);
		if(m_selfrom!=-1)
		{//由于缓冲区内容改变了,那么已经选中的范围也相应的改变
			m_selfrom-=removed;
			m_selto-=removed;
			if(m_selfrom<0)
				m_selfrom=0;
			if(m_selto<0)
				m_selfrom=-1;
		}
	}
	//离开临界区
	LeaveCriticalSection(&cs);
	//下面是对新数据的显示操作,包含滚动条的处理
	int size=m_bytes.GetSize()/m_bytesperline;
	if(m_bytes.GetSize()%m_bytesperline==0)
		size--;
	/*SetScrollRange(SB_VERT,0,size);
	SetScrollPos(SB_VERT,size);

	int line=size-oldpos+removed/m_bytesperline;
	
	if(m_bufferbytes<m_bytesperline*m_linesshown)
	{//如果所有的字符在一个屏幕以内就可以显示的话,则需要全屏刷新
		Invalidate();
	}
	else
	{//否则将屏幕向上滚动line行,然后刷新添入的一部分
		ScrollWindow(0,-15*line);		
		RECT rect;
		GetClientRect(&rect);
		rect.top=rect.bottom-15*(line+1);
		rect.bottom=rect.top+15;
		InvalidateRect(&rect);	
	}*/
	
	SetScrollRange(SB_VERT,0,size);
	SetScrollPos(SB_VERT,size);

	int line=size-oldpos+removed/m_bytesperline;
	
	if(m_bufferbytes<m_bytesperline*m_linesshown)
	{//如果所有的字符在一个屏幕以内就可以显示的话,则需要全屏刷新
		Invalidate();
	}
	else
	{//否则将屏幕向上滚动line行,然后刷新添入的一部分		
		//RECT rect;
		//GetClientRect(&rect);
		//rect.top=rect.bottom-15;		
		//InvalidateRect(&rect);	
		ScrollWindow(0,15);
		ScrollWindow(0,-15*line-15);
	}
}
///////////////////////////////////////////////////////////
//函数:OnDestroy,销毁窗口,释放空间,停止定时器
//////////////////////////////////////////////////////////
void CDataShowView::OnDestroy() 
{
	CView ::OnDestroy();
	
	// TODO: Add your message handler code here
	m_bytes.RemoveAll();
	if(m_btimer)
		KillTimer(1111);

	DeleteCriticalSection(&cs);

}
///////////////////////////////////////////////////////////
//函数:OnCreate; 进行窗口的初始化
///////////////////////////////////////////////////////////
int CDataShowView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView ::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	//设置显示字体
	LOGFONT logfont;
	memset(&logfont, 0, sizeof logfont);
	logfont.lfHeight = 16;
	logfont.lfWidth=8;
	logfont.lfWeight=FW_NORMAL;
	logfont.lfCharSet=DEFAULT_CHARSET;
	lstrcpy(logfont.lfFaceName, _T("宋体"));

	m_font.CreateFontIndirect(&logfont);
	SetFont(&m_font);

	m_color_normaltext=RGB(0,0,0);//正常颜色
	m_color_normalback=RGB(255,255,255);

	m_color_selecttext=RGB(255,255,255);//选中颜色
	m_color_selectback=RGB(0,0,0);

	//m_color_keywordtext=RGB(0,220,100);//特殊字符颜色
	m_color_keywordtext=RGB(255,0,0);//特殊字符颜色
	InitializeCriticalSection(&cs);//初始化临界区控制
	return 0;
}
/////////////////////////////////////////////////////////
//函数:OnVScroll;功能是处理滚动轴消息
/////////////////////////////////////////////////////////
void CDataShowView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	int min,max;
	GetScrollRange(SB_VERT,&min,&max);
	int pos=GetScrollPos(SB_VERT);
	switch(nSBCode)
	{
	case SB_LINEUP://向上滚动一行
		if(pos<=min)
			return;
		SetScrollPos(SB_VERT,pos-1);
		ScrollWindow(0,15);
//		UpdateWindow();
		break;
	case SB_LINEDOWN://向下滚动一行
		if(pos>=max)
			return;
		SetScrollPos(SB_VERT,pos+1);
		ScrollWindow(0,-15);
//		UpdateWindow();
		break;
	case SB_PAGEDOWN://向下翻页
		{
			int scrolls;
			if(pos>=max)
				return;
			if(pos+m_linesshown>max)
				scrolls=max-pos;
			else
				scrolls=m_linesshown;
			SetScrollPos(SB_VERT,pos+m_linesshown);
			ScrollWindow(0,-15*scrolls);
		}
		break;
	case SB_PAGEUP://向上翻页
		{
			int scrolls;
			if(pos<=min)
				return;
			if(pos-m_linesshown<min)
				scrolls=pos-min;
			else
				scrolls=m_linesshown;
			SetScrollPos(SB_VERT,pos-m_linesshown);
			ScrollWindow(0,15*scrolls);
		}
		break;
	case SB_BOTTOM://滚动到最下
		if(pos>=max)
			return;
		SetScrollPos(SB_VERT,max);
		ScrollWindow(0,-15*(max-pos));
		break;
	case SB_TOP://滚动到最上
		if(pos<=min)
			return;
		SetScrollPos(SB_VERT,min);
		ScrollWindow(0,15*(pos-min));
		break;
	case SB_THUMBPOSITION://拖动滚动轴
//		SetScrollPos(SB_VERT,nPos);
//		ScrollWindow(0,15*(pos-nPos));
//		break;
	case SB_THUMBTRACK:
		SetScrollPos(SB_VERT,nPos);
		ScrollWindow(0,15*(pos-nPos));
		break;
	}
//	Invalidate();
	CView ::OnVScroll(nSBCode, nPos, pScrollBar);
}
////////////////////////////////////////////////////////
//函数:OnLButtonDown;功能,处理鼠标左键点下的操作,包括:
//选中特殊字符,选择字符范围等
//////////////////////////////////////////////////////////
void CDataShowView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bpointing)
	{//如果正在选择特殊字符,鼠标左键点下后,就确定了当前指向的字符为需要
		//特殊显示的字符
	//	ReleaseCapture();
		SetClassLong(m_hWnd,GCL_HCURSOR,(long)(::LoadCursor(NULL,IDC_IBEAM)));
		m_bpointing=FALSE;
		RECT rect1;
		GetClientRect(&rect1);
		int curline=(rect1.bottom-point.y)/15;//(point.y+10)/15;
		curline=GetScrollPos(SB_VERT)-curline;
		if(curline<0)
			curline=0;
		int curchar=point.x>=m_bytesperline*24?m_bytesperline-1:point.x/24;
		curchar+=curline*m_bytesperline;
		if(curchar>=m_bytes.GetSize())
			curchar=m_bytes.GetSize()-1;
		Invalidate();
		if(curchar>=0 && m_bytes.GetSize()>0)
			m_specialbyte=m_bytes[curchar];
		m_oldcharpos=-1;
		CView::OnLButtonDown(nFlags,point);
		return;
	}
	//这是选择字符范围的开始,点下后就确认了选中的开始位置
	m_bmousedown=TRUE;
	SetCapture();
	m_oldpoint=point;
	RECT rect1;
	GetClientRect(&rect1);
	int curline=(rect1.bottom-point.y)/15;//(point.y+10)/15;
	curline=GetScrollPos(SB_VERT)-curline;
	if(curline<0)
		curline=0;
	int curchar=point.x>=m_bytesperline*24?m_bytesperline:(point.x+8)/24;
	curchar+=curline*m_bytesperline;
	
	m_firstsel=curchar;
	//如果以前已经有选择的范围,则将选择范围取消
	if(m_selfrom!=-1)
	{
		RECT rect;
		GetClientRect(&rect);
		//rect.top=m_selfrom/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT)-1;
		//rect.top*=15;
		//rect.bottom=m_selto/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT);
		//rect.bottom*=15;
		rect.top=rect1.bottom-(GetScrollPos(SB_VERT)-m_selfrom/m_bytesperline+1)*15;
		rect.bottom=rect1.bottom-(GetScrollPos(SB_VERT)-m_selto/m_bytesperline)*15;	
		rect.bottom++;
		m_selfrom=-1;
		InvalidateRect(&rect);
	}		
	CView ::OnLButtonDown(nFlags, point);
}
///////////////////////////////////////////////////////////
//函数:OnLButtonUp,功能确认选择范围,如果鼠标左键点下和弹起的
//位置在一个范围以内,则认为没有选中任何范围
/////////////////////////////////////////////////////////////
void CDataShowView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(!m_bmousedown )
		return;
	m_bmousedown=FALSE;
	ReleaseCapture();
	RECT rect1;
	GetClientRect(&rect1);
	//如果鼠标左键点下和弹起的位置在一个范围-直径10象素的矩形以内,则认为没有选中任何范围
	if(abs(point.x-m_oldpoint.x)<5 && abs(point.y-m_oldpoint.y)<5)
	{
		if(m_selfrom!=-1)
		{
			RECT rect;
			GetClientRect(&rect);
			//rect.top=m_selfrom/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT)-1;
			//rect.top*=15;
			//rect.bottom=m_selto/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT);
			//rect.bottom*=15;			
			rect.top=rect1.bottom-(GetScrollPos(SB_VERT)-m_selfrom/m_bytesperline+1)*15;
			rect.bottom=rect1.bottom-(GetScrollPos(SB_VERT)-m_selto/m_bytesperline)*15;
			m_selfrom=-1;
			InvalidateRect(&rect);
			
		}
		CView ::OnLButtonUp(nFlags, point);				
		return;
	}
	//确认选中范围
	int curline=(rect1.bottom-point.y)/15;//(point.y+10)/15;
	curline=GetScrollPos(SB_VERT)-curline;	
	if(curline<0)
		curline=0;
	int curchar=point.x>=m_bytesperline*24?m_bytesperline:point.x/24;
	curchar+=curline*m_bytesperline;

	int oldfrom=m_selfrom,oldto=m_selto;
	if(m_firstsel>=curchar)
	{
		m_selfrom=curchar;
		m_selto=m_firstsel;
	}
	else
	{
		m_selfrom=m_firstsel;
		m_selto=curchar;
	}
//	if(oldfrom>m_selfrom)
//		oldfrom=m_selfrom;
//	if(oldto<m_selto)
//		oldto=m_selto;		
	if(oldfrom!=m_selfrom)
	{
		if(oldfrom>m_selfrom)
		{
			oldto=oldfrom;
			oldfrom=m_selfrom;			
		}
		else
			oldto=m_selfrom;
	}
	else 
	{
		if(oldto<m_selto)
		{
			oldfrom=oldto;
			oldto=m_selto;
		}
		else
			oldfrom=m_selto;
	}
//	Invalidate();
	RECT rect;
	GetClientRect(&rect);
	//rect.top=oldfrom/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT)-1;
	//rect.top*=15;
	//rect.bottom=oldto/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT);
	//rect.bottom*=15;
	rect.top=rect1.bottom-(GetScrollPos(SB_VERT)-oldfrom/m_bytesperline+1)*15;
	rect.bottom=rect1.bottom-(GetScrollPos(SB_VERT)-oldto/m_bytesperline)*15;
	rect.bottom++;
	InvalidateRect(&rect);
	//KillTimer(1111);
	//如果自动滚动定时器在运行,停止该定时器
	if(m_btimer)
	{
		m_btimer=0;
		KillTimer(1111);
	}
	CView ::OnLButtonUp(nFlags, point);
}
///////////////////////////////////////////////////////
//函数:OnRButtonUp,功能,取消选择特殊字符操作或显示
//辅助菜单
////////////////////////////////////////////////////////
void CDataShowView::OnRButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bpointing)
	{//停止选择特殊字符
		m_bpointing=FALSE;
	//	ReleaseCapture();
		//设置默认鼠标
		SetClassLong(m_hWnd,GCL_HCURSOR,(long)(::LoadCursor(NULL,IDC_IBEAM)));
		RECT rect1;
		GetClientRect(&rect1);
		int curline=(rect1.bottom-point.y)/15;//(point.y+10)/15;
		curline=GetScrollPos(SB_VERT)-curline;
		if(curline<0)
			curline=0;
		int curchar=point.x>=m_bytesperline*24?m_bytesperline-1:point.x/24;
		curchar+=curline*m_bytesperline;
		if(curchar>=m_bytes.GetSize())
			curchar=m_bytes.GetSize()-1;
		RECT rect;
		rect.left=(curchar%m_bytesperline)*24;
		rect.right=rect.left+16;
		//rect.top=curchar/m_bytesperline+m_linesshown-GetScrollPos(SB_VERT)-1;
		rect.top=rect1.bottom-(GetScrollPos(SB_VERT)-curchar/m_bytesperline+1)*15;
		//rect.top*=15;
		rect.bottom=rect.top+15;
		rect.left--;
		rect.top--;
		rect.bottom++;
		rect.right++;
		InvalidateRect(&rect);
		m_oldcharpos=-1;
		CView::OnRButtonUp(nFlags,point);
		return;

	}

⌨️ 快捷键说明

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