不借助任何三方组件,利用TStringGrid完成了一个可伸缩的表格,这里给出伸展代码。有兴趣者可完成收缩和重画部分。

BlueDeepOcean 2006-09-12 04:47:45
//结构体及自定义函数部分

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unt_StringGrid_EC.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;

TStringList *Lines;

struct FieldInfo
{
int CurrentIdx;
AnsiString CurrentField;
int ID; /* 0——NoSub
1——HasSub
2——IsSub*/
AnsiString NextField;
} FldInfo[MAX_PATH];

int ECRowCount, //动态记录总行数
gbl_Col, //动态记录当前列索引
gbl_Row; //动态记录当前行索引

bool Selected;
//---------------------------------------------------------------------------
__fastcall TMain::TMain(TComponent* Owner)
: TForm(Owner)
{
Lines = new TStringList;
ECRowCount = 0;
}
//---------------------------------------------------------------------------
bool __fastcall TMain::IsSubList(AnsiString TargetReceive)
{
bool IsSub = false;
char *FirstField = new char[MAX_PATH];

FirstField = TargetReceive.c_str();

while(*FirstField != '\0')
{
if (*FirstField == '*')
{
IsSub = true;
break;
}
else
FirstField ++;
}

delete FirstField;
FirstField = NULL;

return IsSub;
}
//---------------------------------------------------------------------------
void __fastcall TMain::Decode_Spread(char *TargetDecoded,int CurrentID, int ID,
int FlashRowCount)
{
/********************************************************************
TargetDecoded : 结构体中目标待解析字符串
CurrentID : 结构体中目标待解析字符串索引
ID : 结构体中目标待解析字符串属性标识
FlashRowCount : StringGrid总行数
********************************************************************/
/*-------------------------------------------------------------------
解码
-------------------------------------------------------------------*/

AnsiString AsArray[10]; //此处的范围可以修改
int Count = 0,cnt = 0; //'cnt'用于处理字符间多个空格的情况

StringGridEC->RowCount = 1;
StringGridEC->RowCount = FlashRowCount;

while (*TargetDecoded != '\0')
{
if (*TargetDecoded != ' ')
{
AsArray[Count] += *TargetDecoded;
cnt = 0;
}
else
{
cnt ++;
if (cnt <= 1)
Count ++;
}
TargetDecoded ++;
}

StringGridEC->ColCount = Count + 1;

/*-------------------------------------------------------------------
分配
-------------------------------------------------------------------*/

if (ID == 0 || ID == 1)
{
if (ID == 0)
{
for (int ridx = StringGridEC->RowCount - 1;ridx < StringGridEC->RowCount;ridx ++)
for (int cidx = 0;cidx < StringGridEC->ColCount;cidx ++)
StringGridEC->Cells[cidx][ridx] = AsArray[cidx];
}
else
{
for (int ridx = StringGridEC->RowCount - 1;ridx < StringGridEC->RowCount;ridx ++)
for (int cidx = 0;cidx < StringGridEC->ColCount;cidx ++)
{
if (cidx == 0)
StringGridEC->Cells[cidx][ridx] = "+" + AsArray[cidx];
else
StringGridEC->Cells[cidx][ridx] = AsArray[cidx];
}
}
}
else
{
for (int cidx = 0;cidx < StringGridEC->ColCount;cidx ++)
StringGridEC->Cells[cidx][CurrentID] = AsArray[cidx];
}
}
...全文
383 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjsyw 2007-04-19
  • 打赏
  • 举报
回复
学习,谢谢
hzx518 2007-02-10
  • 打赏
  • 举报
回复
carp27 2006-11-06
  • 打赏
  • 举报
回复
^_^,学习了
BlueDeepOcean 2006-09-13
  • 打赏
  • 举报
回复
听取更多意见。:)
僵哥 2006-09-12
  • 打赏
  • 举报
回复
建议改成一个StringGrid组件吧.包括什么多选,行选等功能也添加进行这样子就...抱歉哈.
BlueDeepOcean 2006-09-12
  • 打赏
  • 举报
回复
嗯……过段时间放到老妖的www.ccrun.com上吧。
wt_sanlian 2006-09-12
  • 打赏
  • 举报
回复
有没有现成的工程文件可以下载啊 ,要不然测试太累了
BlueDeepOcean 2006-09-12
  • 打赏
  • 举报
回复
//加载文件格式及内容

1 2 3 4 5
*6 7 8 9 10
*11 12 13 14 15
*16 17 18 19 20
21 22 23 24 25
A α б ぁ ∑
*★ ▲ ※ ♂ ♀
26 27 28 29 30
*31 32 33 34 35
*36 37 38 39 40
BlueDeepOcean 2006-09-12
  • 打赏
  • 举报
回复
//具体应用部分

//---------------------------------------------------------------------------
void __fastcall TMain::LoadFile(TObject *Sender)
{
OpenBox->Filter = "Text Files(*.txt)|*.txt";
if (OpenBox->Execute())
{
Lines->LoadFromFile(OpenBox->FileName);

/*-----------------------------------------------------------
解码矩阵数据并构造矩阵结构
-----------------------------------------------------------*/

for (int i = 0;i < Lines->Count;i ++)
{
FldInfo[i].CurrentIdx = i;
FldInfo[i].CurrentField = Lines->Strings[i];

if (IsSubList(Lines->Strings[i]))
{
FldInfo[i].ID = 2;

if (i > 0)
{
if (FldInfo[i - 1].ID != 2) //判断该节点是否为'IsSub'节点
FldInfo[i - 1].ID = 1;
}
}
else
{
if (i < Lines->Count - 1)
{
if (IsSubList(Lines->Strings[i + 1]))
FldInfo[i].ID = 1;
else
FldInfo[i].ID = 0;
}
else
FldInfo[i].ID = 0;
}

if (i < Lines->Count - 1)
FldInfo[i].NextField = Lines->Strings[i + 1];
else
FldInfo[i].NextField = "";
}

/*-----------------------------------------------------------
根据矩阵结构形成StringGrid数据
-----------------------------------------------------------*/

for (int fidx = 0;fidx < Lines->Count;fidx ++)
{
if (FldInfo[fidx].ID != 2)
{
ECRowCount ++;
Decode_Spread(Lines->Strings[fidx].c_str(),NULL,FldInfo[fidx].ID,ECRowCount);
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::FocusCellRect(TObject *Sender, int ACol, int ARow,
bool &CanSelect)
{
gbl_Col = ACol;
gbl_Row = ARow;

Selected = CanSelect = true;
}
//---------------------------------------------------------------------------
void __fastcall TMain::CellDoubleClick(TObject *Sender)
{
int LockRow = -1, //锁定StringGrid中的'+'行
PointSubList = -1, //锁定'FldInfo'结构中'*'行
LoopTimes = 0; //增加StringGrid行的次数

bool LastOne = false; //父节点行是否为StringGrid的最后一行

if (Selected)
{
if (StringGridEC->Cells[gbl_Col][gbl_Row].SubString(1,2) == "+") //'+'是两个字节
{
for (int pointr = 0;pointr < Lines->Count;pointr ++) //在结构'FldInfo'中查找
{
if (StringGridEC->Cells[gbl_Col][gbl_Row].SubString(1 + 2,
StringGridEC->Cells[gbl_Col][gbl_Row].Length() - (1 + 2) + 1) ==
FldInfo[pointr].CurrentField.SubString(1,
FldInfo[pointr].CurrentField.Pos(" ") - 1))
{
LockRow = gbl_Row;
ECRowCount = StringGridEC->RowCount;

//判断点击行的索引是否为最后一行
if (gbl_Row != ECRowCount - 1)
LastOne = false;
else
LastOne = true;

PointSubList = pointr + 1;

for (int nextpointr = pointr + 1;nextpointr < Lines->Count;nextpointr ++) //从'+'标识的第二行开始
{
if (FldInfo[nextpointr].ID != 2)
break;
else
{
//插入行
ECRowCount ++;
StringGridEC->RowCount = ECRowCount;
LoopTimes ++;
}
}
break;
}
}
//插值
if (LastOne) //结束行,无须移动
{
//插值
for (int ridx = LockRow + 1;ridx < LockRow + LoopTimes + 1;ridx ++)
{
Decode_Spread(FldInfo[PointSubList].CurrentField.c_str(),ridx,FldInfo[PointSubList].ID,ECRowCount);
PointSubList ++;
}
}
else //非结束行,需移动
{
//移行
for (int movetimes = 0;movetimes < LoopTimes;movetimes ++)
for (int cidx = 0;cidx < StringGridEC->ColCount;cidx ++)
for (int ridx = ECRowCount - 1;ridx > LockRow + 1;ridx --)
{
StringGridEC->Cells[cidx][ridx] = StringGridEC->Cells[cidx][ridx - 1];
StringGridEC->Cells[cidx][ridx - 1] = "";
}
//插值
for (int ridx = LockRow + 1;ridx < LockRow + LoopTimes + 1;ridx ++)
{
Decode_Spread(FldInfo[PointSubList].CurrentField.c_str(),ridx,FldInfo[PointSubList].ID,ECRowCount);
PointSubList ++;
}
}
}
}
}
//---------------------------------------------------------------------------

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧