首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

表格控件TDrawGrid的使用方法

2012-12-14 
表格控件TDrawGrid的使用方法求助领导让写一个数据处理程序,我用的是C++ Builder 6。其中的功能是将一个十

表格控件TDrawGrid的使用方法求助
领导让写一个数据处理程序,我用的是C++ Builder 6。
其中的功能是将一个十六进制文件打开,并将所有的数据显示在一个16列×n行的表格中。
文件中的所有数据已经被我读到一个字符串数组中。
原先用的是TStringGrid控件,用逐个给格子赋值的方法(TStringGrid1->cells[i][j] = Buffer[k])可以实现。但是由于数据量大,运行时速度很慢,而且当行数达到300000行的时候,运行时会显示内存错误。

现换成TDrawGrid方法,打算使用OnDrawGrid事件将数据显示出来。在网上找不到这个组件的资料。
请问各位大神,这个方法怎么使用?
还有,作为一个刚毕业的学生,自学起来还真痛苦,有没有什么好书或者强大点的帮助文档可以推荐的?
[最优解释]
本帖最后由 ccrun 于 2012-12-05 14:19:49 编辑 Form上放置一个DrawGrid,两个Button,然后:
头文件中:

private:// User declarations
    byte *m_Buffer;  // 用来存放文件内容的缓冲
    int m_BufferLen; // 缓冲的长度


.cpp文件中:
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    m_BufferLen = 0;

    // 初始化DrawGrid
    DrawGrid1->DefaultColWidth = 20;
    DrawGrid1->ColWidths[0] = 48;
    DrawGrid1->DefaultRowHeight = 16;
    DrawGrid1->ColCount = 17;
    DrawGrid1->RowCount = 21;    
}

// ---------------------------------------
void __fastcall TForm1::DrawGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
    String strText;
    // 第一行作为标题,用来显示0x0-0xF的索引
    if (ARow == 0 && ACol > 0)
    {
        strText = IntToHex(ACol - 1, 2);
    }
    // 第一列作为地址段
    else if (ACol == 0 && ARow > 0)
    {
        strText.sprintf("%.5X0", ARow - 1);
    }
    // 数据以16进制显示
    else if (ACol > 0 && ARow > 0)
    {
        if ((ARow - 1) * 16 + ACol - 1 < m_BufferLen)
            strText.sprintf("%.2X", m_Buffer[(ARow - 1) * 16 + ACol - 1]);
        else
            strText = "";
    }
    DrawGrid1->Canvas->TextRect(Rect, Rect.Left + 4, Rect.top + 2, strText);
}

// ---------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 打开一个文件并读入缓冲
    FILE *fp = fopen("D:\\ccrun\\111.exe", "rb");
    fseek(fp, 0, SEEK_END);
    long lFileSize = ftell(fp);
    m_Buffer = new byte[lFileSize];
    fseek(fp, 0, SEEK_SET);
    m_BufferLen = fread(m_Buffer, 1, lFileSize, fp);


    fclose(fp);

    // 根据读入的字节数,设置DrawGrid的行数(除以16并加上标题行的数量)
    DrawGrid1->RowCount = m_BufferLen / 16 + 1;
    // 如果不是正好显示为16的倍数行,则多一行
    if (m_BufferLen % 16) DrawGrid1->RowCount++;

    // 重新绘制DrawGrid上的内容
    DrawGrid1->Invalidate();
}

// ---------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    // 记的释放缓冲
    delete []m_Buffer;
}


[其他解释]
写错了
请教的是OnDrawCell事件的使用。
[其他解释]
来个效果图:

[其他解释]
引用:
本帖最后由 ccrun 于 2012-12-05 14:19:49 编辑
            Form上放置一个DrawGrid,两个Button,然后:
头文件中:
C/C++ code?123private:    // User declarations    byte *m_Buffer;  // 用来存放文件内容的缓冲    int m_Buff……


谢谢版主的回复,
1、DrawGrid1->Canvas->TextRect(Rect, Rect.Left + 4, Rect.top + 2, strText);这条语句看不懂
2、还有这个DrawGrid1->Invalidate();//重新绘制。TDrawGrid在什么情况下会重新绘制呢?
[其他解释]
1. DrawGrid1->Canvas->TextRect(Rect, Rect.Left + 4, Rect.top + 2, strText);
在Rect区域内绘制文字strText,左偏移4个像素,上偏移2个像素(空开一点好看而已)。

2. 对于DrawGrid控件来说,要显示的内容发生了变化,但是DrawGrid并不知道的情况下,需要告诉它重绘以响应数据的变化。调用DrawGrid的Invalidate方法,就是让其重新绘制。

[其他解释]
引用:
1. DrawGrid1->Canvas->TextRect(Rect, Rect.Left + 4, Rect.top + 2, strText);
在Rect区域内绘制文字strText,左偏移4个像素,上偏移2个像素(空开一点好看而已)。

2. 对于DrawGrid控件来说,要显示的内容发生了变化,但是DrawGrid并不知道的情况下,需要告诉它重绘以响应数……
谢谢版主,在什么情况下,DrawGrid内容变化的时候,它会知道和不知道呢?
[其他解释]
或者说,重画需要什么事件进行触发呢?
[其他解释]
引用:
或者说,重画需要什么事件进行触发呢?


对于DrawGrid来说,如果有窗口挡在它所在的窗体上面以后再挪开的时候,它会自动重绘。或者所在窗口最小化后还原,或者从屏幕边缘挪到屏幕可视区的时候。

在你的需求中,如果读了新文件要在DrawGrid中重新显示新数据,就得手动让它触发一下重绘。
[其他解释]
引用:
引用:或者说,重画需要什么事件进行触发呢?

对于DrawGrid来说,如果有窗口挡在它所在的窗体上面以后再挪开的时候,它会自动重绘。或者所在窗口最小化后还原,或者从屏幕边缘挪到屏幕可视区的时候。

在你的需求中,如果读了新文件要在DrawGrid中重新显示新数据,就得手动让它触发一下重绘。
谢谢版主,真的太感谢了,回答地特仔细,打算长期驻扎CSDN论坛~~~膜拜下大神!
[其他解释]
引用:
本帖最后由 ccrun 于 2012-12-05 14:19:49 编辑
            Form上放置一个DrawGrid,两个Button,然后:
头文件中:
C/C++ code?123private:    // User declarations    byte *m_Buffer;  // 用来存放文件内容的缓冲    int m_Buff……

如果能指导下C++ Builder怎么入门,还有在写程序时遇到不会的组件时,到哪可以查到资料。小弟感激不尽!

热点排行