初步了解如何自己写一个网格控件

Posted bcbobo21cn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初步了解如何自己写一个网格控件相关的知识,希望对你有一定的参考价值。

网上下的一个源码,VC6打开如下;

    一个MFC工程,控件的源码包含在demo工程里面;构建时是全部一起构建;

先看一下版权;

// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name and all copyright 
// notices remains intact. 

desire
n:欲望,愿望

此代码可以按你的愿望使用。


profit
n:利润,赢利,


consent
v:同意,答应

此文件可以重分发;

intact
a:完整,完好无损

提供此注意事项,以及作者的名字,保留所有权利;

大意是说可以使用此源码,但要保留作者的名字和所写的注意事项;

构建一下;

提示一个错误,col重定义,把后面定义的col前面的 int 删掉,

 

提示row重定义,把后面定义的row前面的 int 删掉;

 

warning C4100: 'bFirst' : unreferenced formal parameter;

    一个警告不用理;

链接出错,

    LINK : fatal error LNK1104: cannot open file "mfc42u.lib"

提示缺少2个lib文件,带u的是unicode版本的库文件,从VC安装光盘拷到相应目录即可;

运行起来如下;

 

可以编辑单元格,选中整行整列,等,

 

先看一下单元格界面是如何实现的;它源码里面有Edit相关的类,看一下是否每个单元格是一个编辑框控件;

用句柄查看工具看一下;所有的单元格只有一个句柄;

 

    整个单元格界面它是一个CWnd类;

那么单元格界面就应该是绘制的横竖线;

看一下单元格基类的实现代码;

有一个结构体,这应该是代表一个单元格;属性包括:行列位置,格式,字体,文本等;

 

单元格基类有Draw成员函数,它有类似如下的一些代码,

if (bHiliteFixed)
        
            rect.right++; rect.bottom++;
            pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT);
            rect.DeflateRect(1,1);
        
        else
        
            CPen lightpen(PS_SOLID, 1,  ::GetSysColor(COLOR_3DHIGHLIGHT)),
                darkpen(PS_SOLID,  1, ::GetSysColor(COLOR_3DDKSHADOW)),
                *pOldPen = pDC->GetCurrentPen();

            pDC->SelectObject(&lightpen);
            pDC->MoveTo(rect.right, rect.top);
            pDC->LineTo(rect.left, rect.top);
            pDC->LineTo(rect.left, rect.bottom);

            pDC->SelectObject(&darkpen);
            pDC->MoveTo(rect.right, rect.top);
            pDC->LineTo(rect.right, rect.bottom);
            pDC->LineTo(rect.left, rect.bottom);

            pDC->SelectObject(pOldPen);
            rect.DeflateRect(1,1);
        

    这是画线,看上去是画一个单元格的线;

    还有这句,

        DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX);

    这是绘制一个单元格内的文本;

这是一个简易型的,需要和可以设置单元格的行数和列数;

 

 如果是行列数量可以任意扩展,应该是使用链表类似的数据结构来存储每个单元格的文本;代码中没有发现链表;如果行列数有限不需要;

此处还有一个纯win32的自己写的grid控件,

https://blog.csdn.net/free_job/article/details/1762659#comments_1154970
自己写的GRID控件源码(源文件)

    它的StringLink_T结构体看上去是存储单个文本的结构体,用来形成链表;

看一下网格控件类设置单元格文本的函数,调用了单元格类的SetText()函数;

BOOL CGridCtrl::SetItemText(int nRow, int nCol, LPCTSTR str)

    if (GetVirtualMode())
        return FALSE;

    CGridCellBase* pCell = GetCell(nRow, nCol);
    if (!pCell)
        return FALSE;

    pCell->SetText(str);

    SetModified(TRUE, nRow, nCol);
    return TRUE;

单元格类的部分定义,
class CGridCell : public CGridCellBase

    friend class CGridCtrl;
    DECLARE_DYNCREATE(CGridCell)

// Construction/Destruction
public:
    CGridCell();
    virtual ~CGridCell();

// Attributes
public:
    void operator=( CGridCell& cell);

    virtual void  SetText(LPCTSTR szText)         m_strText = szText;   
......

    SetText只是设置成员变量m_strText;文本是绘制出来的;

它的实现方式是这样,整体网格界面是绘制线出来的;当点中一个单元格,在此单元格处显示一个编辑框控件,此时此单元格是可以编辑的;这就对了,不用到处都是编辑框;

有时间继续;

以上是关于初步了解如何自己写一个网格控件的主要内容,如果未能解决你的问题,请参考以下文章

如何通过代码生成 WPF 控件

WPF C# 如何在动态添加的grid控件中添加某个网格中的image控件的单击事件?

TADOConnection和TADQuery组件连接访问数据库总结

DataGridView的单元格如何嵌入多个按钮控件

c#如何让DataGridView控件在没有绑定数据源的情况下显示网格线?

Silverlight OLAP 数据网格? [关闭]