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

📄 grid.cpp

📁 金融pos机前台源码
💻 CPP
字号:
/*******************************************************************************
	模  块:	网格.
	功  能:	数据网格,能编辑,上下移动,并上下翻页.
	程序员:	雷中南.
	版  本:	v1.1
	时  间:	1999-05-18
*******************************************************************************/
#include <graphics.h>
#include <string.h>
#include "stdio.h"
#include "grid.h"
#include "fileio.h"

//求最小值的函数.
#ifdef __cplusplus
int min(int value1, int value2)
{
	return ( (value1 < value2) ? value1 : value2);
}
#endif

/*============================================================================*/

//构造函数.
Grid::Grid(struct RECT R, int cols, int width[], char *title[])
	  :Object(R)
{
		//循环变量.
		int i;

		//文件缓冲,用于保存临时数据.
		DataFile = new FileIO();

		//当前列.
		Col = 0;

		//总列数.
		Cols = cols;

		//列宽.
		for(i=0; i<Cols; i++)
		{
			ColWidth[i] = width[i];
		}

		//一条记录的总长度.
		DataLength = 0;

		//当前行数据.
		for(i=0; i<Cols; i++)
		{
			//给字符串数组分配内存.
			Data[i] = new char[ColWidth[i]*2];
			Title[i] = new char[ColWidth[i]*2];
			strcpy(Title[i], title[i]);
			DataLength = DataLength + ColWidth[i]*2;
		}

		//给文件读写缓冲分配内存.
		Buffer = new char[DataLength + 1];

		//只读标记.L_YES表示编辑模式.L_NO表示只读模式.
		ReadOnlyFlag = L_NO;

		//总行数.
		Rows = 0;

		//当前行.
		Row = 0;

		//页首行.
		FirstRow = 0;

		//头尾的高度.
		HeadHeight = 20;
		TailHeight = 20;

		//可见行数.
		VisibleRow = (Rect.Height - HeadHeight - TailHeight) / 20;

		//行高度.
		LineHeight = 20;

		//设置允许刷新.
		IsRefresh();
}

//析构函数.
Grid::~Grid()
{
	int i;
	delete DataFile;
	delete Buffer;
	for(i=0; i<Cols; i++)
	{
		delete []Data[i];
	}
}


/*============================================================================*/


//全部重画.
void
Grid::Draw()
{
	//如果不允许刷新则返回.
	if(Refable == L_NO)
	{
		return;
	}
	int i=0, j=0, temp=0;
	//按行画有数据列.
	for(i=FirstRow; i<=min(Rows - 1, FirstRow + VisibleRow); i++)
	{
		ItemDraw(i);
	}
	//画无数据列.
	for(j=min(Rows - 1, FirstRow + VisibleRow) + 1; j<FirstRow + VisibleRow; j++)
	{
		setcolor(7);
		temp = 0;
		for(i=0; i<Cols; i++)
		{
			temp = temp + ColWidth[i]*8 + 1;
			//设定视口.
			setviewport(0, 0, 639, 479, 1);
			setviewport(Rect.Left + temp - ColWidth[i]*8 + 1,
					Rect.Top + LineHeight + (j - FirstRow) * LineHeight +2,
					Rect.Left + temp - 1,
					Rect.Top + LineHeight + (j + 1 - FirstRow) * LineHeight - 1, 1);
			//清除视口.
			clearviewport();
		}
	}
}

//画网格.
void
Grid::InitDraw()
{
	int i, sum;

	setcolor(15);
	//画大框.
	rectangle(0, 0, Rect.Width, Rect.Height);
	//画题头.
	setviewport(0, 0, 639, 479, 1);
	setviewport(Rect.Left, Rect.Top, Rect.Left + Rect.Width,
					Rect.Top + HeadHeight, 1);
	//设定题头的颜色和模式.
	setfillstyle(SOLID_FILL, 8);
	bar(0, 0, Rect.Width, HeadHeight);
	rectangle(0, 0, Rect.Width, HeadHeight);
	//写题头文字.
	sum = 0;
	han.Color = 7;
	setcolor(7);//设置题头分割线的颜色.
	for(i=0; i<Cols; i++)
	{
		//画列线.
		han.Out(sum + 2, 2, Title[i]);
		//累加列宽.
		sum = sum + 8*ColWidth[i] + 1;
		//画列线.
		line(sum, 1, sum, TailHeight - 1);
	}

	//恢复视口.
	setviewport(0, 0, 639, 479, 1);
	setviewport(Rect.Left, Rect.Top, Rect.Left + Rect.Width,
					Rect.Top + Rect.Height, 1);
	//画尾.
	setfillstyle(SOLID_FILL, 8);
	bar(0, Rect.Height - TailHeight, Rect.Width, Rect.Height);
	setcolor(15);
	rectangle(0, Rect.Height - TailHeight, Rect.Width, Rect.Height);

	setcolor(8);
	sum=0;
	for(i=0; i<=Cols; i++)
	{
		//累加列宽.
		sum = sum + 8*ColWidth[i] + 1;
		//画列线.
		line(sum, HeadHeight + 1, sum, Rect.Height - TailHeight - 1);
	}
}

//画一行数据.
void
Grid::ItemDraw(int ID)
{
	//如果不允许刷新则返回.
	if(Refable == L_NO)
	{
		return;
	}
	//如果此行在可视范围内的话.
	if(ID >= FirstRow && ID < FirstRow + VisibleRow)
	{
		int i=0, temp=0;
		//读取指定行.
		Read(ID);
		for(i=0; i<Cols; i++)
		{
			//累加获取列位置.
			temp = temp + ColWidth[i]*8 + 1;
			//设定视口.
			setviewport(0, 0, 639, 479, 1);
			setviewport(Rect.Left + temp - ColWidth[i]*8 + 1,
					Rect.Top + LineHeight + (ID - FirstRow) * LineHeight +2,
					Rect.Left + temp - 1,
					Rect.Top + LineHeight + (ID + 1 - FirstRow) * LineHeight - 1, 1);
			//清除视口.
			clearviewport();
			//输出字段.
			han.Color = 15;
			han.Out(0, 1, Data[i]);
		}
	}
}

//将对象画出来.
void
Grid::Show()
{
	//如果object不具备可见属性则返回.
	if(Visible==L_ERROR || Refable == L_NO) return;
	//视口变化太多了,重定义视口是有必要.
	setviewport(0,0,639,479,1);
	setviewport(Rect.Left,Rect.Top,Rect.Left+Rect.Width,Rect.Top+Rect.Height,1);
	clearviewport();
	//画网格基础.
	InitDraw();
	//画对象.
	Draw();
}


/*============================================================================*/


//往缓冲里写数据.
int
Grid::Write(long ID)
{
	//临时字符串指针.
	char *t = Buffer;

	//将数据按列写入缓冲.
	for(int i=0; i<Cols; i++)
	{
		strncpy(t, Data[i], ColWidth[i] * 2);
		t += ColWidth[i] * 2;
	}

	//将数据写入文件.
	return DataFile->Write(Buffer, ID * DataLength, DataLength);
}

//从缓冲读数据.
int
Grid::Read(long ID)
{
	//从缓冲文件读数据.
	if(DataFile->Read(Buffer, ID * DataLength, DataLength) == L_OK)
	{
		//产生临时字符串指针.
		char *t = Buffer;

		//将缓冲中的数据赋给字段.
		for(int i=0; i<Cols; i++)
		{
			strncpy(Data[i], t, ColWidth[i] * 2);
			t += ColWidth[i] * 2;
		}
		return L_OK;
	}
	else
	{
		return L_ERROR;
	}
}

//插入一行.
void
Grid::InsertRow(char *data[])
{

	//将数据赋给对应字段.
	for(int i=0; i<Cols; i++)
	{
		strcpy(Data[i],data[i]);
	}

	//改变行号.
	Row=Rows;

	//行数加一.
	Rows++;

	//将数据保存到文件.
	Write(Row);

	//超出显示范围,滚动显示.
	if(Rows > FirstRow + VisibleRow)
	{
		//翻页并重画.
		FirstRow = FirstRow + VisibleRow - 1;
		//如果行数大于总行数,当前行等于总行数.
		if(FirstRow > Rows - 1)
		{
			FirstRow = Rows - 1;
		}
		Show();
	}
	else
	{
		//将插入行画出来.
		ItemDraw(Row);
	}
}

//删除一行.
void
Grid::Delete(int ID)
{
	//要删除的前提条件是行数大于1.
	if(Rows >= 1)
	{
		//如果只有一行.
		if(Rows == 1)
		{
			//用空字符串覆盖所有字段.
			for(int i=0; i<Cols; i++)
			{
				strcpy(Data[i],"");
			}
			//将空字段写入文件.
			Write(Row);
		}
		//如果网格多于一条记录.
		for(int i=ID; i<Rows; i++)
		{
			//将数据前移一行.
			Read(i + 1);
			Write(i);
		}
		//行数减一.
		Rows--;
		//重画
		Draw();
	}
}

//全部删除.
void
Grid::DeleteAll()
{
	//行数为一.
	Rows = 1;
	//当前行为零.
	Row = 0;
	//页首行为0.
	FirstRow = 0;
	//写空数据行.
	for(int i=0; i<Cols; i++)
	{
		strcpy(Data[i],"");
	}
	//写入数据文件.
	Write(Row);
	//显示.
	Show();
}

//插入新行.
void
Grid::AddNew()
{
	//将数据字段置为空.
	for(int i=0; i<Cols; i++)
	{
		strcpy(Data[i],"");
	}

	//将数据写入文件.
	Write(Rows);

	//改变当前行.
	Row = Rows;

	//行数加一.
	Rows++;

	//如果在可视范围内.
	if(Row - FirstRow < VisibleRow)
	{
		//画一行.
		ItemDraw(Row);
	}
	else
	{
		//翻页并重画.
		FirstRow = FirstRow + VisibleRow - 1;
		//如果行数大于总行数,当前行等于总行数.
		if(FirstRow > Rows - 1)
		{
			FirstRow = Rows - 1;
		}
		Draw();
	}
}

//修改一行.
void
Grid::Update()
{
	//将现有数据保存到文件.
	Write(Row);
	//重画修改行.
	ItemDraw(Row);
}

//下一行.
void
Grid::MoveNext()
{
	//如果小于总行数, 行数加一.
	if(Row < Rows - 1)
	{
		Row++;
	}
	//如果超出可视范围.
	if(Row-FirstRow >= VisibleRow)
	{
		//向下翻页.
		FirstRow = FirstRow + VisibleRow - 1;
		//如果行数大于总行数,当前行等于总行数.
		if(FirstRow > Rows - 1)
		{
			FirstRow = Rows - 1;
		}
		//重画.
		Draw();
	}
}

//上一行.
void
Grid::MovePrev()
{
	//如果当前行大于0,行数减一.
	if(Row > 0)
	{
		Row--;
	}
	//如果行在页首,重画网格.
	if(Row - FirstRow < 0)
	{
		FirstRow = Row;
		Draw();
	}
}

//上一页.
void
Grid::PageUp()
{
	//如果当前行大于0,行数减一.
	if(Row > 0)
	{
		Row = Row - VisibleRow + 1;
	}
	if(Row < 0)
	{
		Row = 0;
	}
	//如果行在页首,重画网格.
	FirstRow = Row;
	Draw();
}

//下一页.
void
Grid::PageDown()
{
	//行数下翻一页.
	Row = Row + VisibleRow - 1;
	//如果大于总行数.
	if(Row > Rows - 1)
	{
		//当前行为最末行.
		Row = Rows - 1;
	}
	//如果总行数大于可见行数.
	if(Rows >= VisibleRow)
	{
		FirstRow = Row - VisibleRow + 1;
	}
	else
	{
		FirstRow = 0;
	}
	//重画.
	Draw();
}


/*============================================================================*/


//设置为不可刷新状态.
void
Grid::IsFreeze()
{
	Refable = L_NO;
}

//设置为可刷新状态.
void
Grid::IsRefresh()
{
	Refable = L_YES;
	Show();
}


/*============================================================================*/


//编辑焦点.
void
Grid::DoIt()
{
	unsigned int Event, i;
	//行编辑.
	for(;;)
	{
		Read(Row);
		Line= new LineGrid(
			CreateRect(Rect.Left, Rect.Top + HeadHeight + (Row - FirstRow) * LineHeight,
			Rect.Width, LineHeight), Data, ColWidth, Cols, ReadOnlyFlag);
		Line->Col = Col;
		Line->Show();
		Line->Run();
		for(i=0; i<Cols; i++)
		{
			strcpy(Data[i], Line->Data[i]);
		}
		Line->Hide();
		delete Line;
		GetEvent(Event);
		switch(Event)
		{
			case EV_NEXT:
				MoveNext();
				PutEvent(Event);
				return;
			case EV_PREV:
				MovePrev();
				PutEvent(Event);
				return;
			case KEY_PGUP:
				PageUp();
				PutEvent(Event);
				return;
			case KEY_PGDWN:
				PageDown();
				PutEvent(Event);
				return;
			default:
				PutEvent(Event);
				return;
		}
	}
}


⌨️ 快捷键说明

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