关于CGridCtrl让我极度郁闷的问题。

2shcm 2007-07-16 04:28:40
几年前,学习VC数据库编程时写了个“ACCESS数据库”浏览器。但时是单文档+ ADO + ClistCtrl写的,没什么致命BUG。去年,我用多文档+Ado+CGridCtrl2.25 重写的程序。因为VCKABSE上看了CGridCtrl的介绍,还是错。但程序基本功能写差不多后发现一个致命BUG--当打开数据库多个表格时,或者分页多个页面时程序崩溃出错。VC++ 在DEBUG下CGridCtrl出错。
也许对CGridCtrl了解不多,反正一年多也没能解决这个郁闷的问题。现诚心向各位朋友请教。关于这个错误,有个规律。就是打开22个页面时,程序无法显示数据,当打开23个数据页面(表格)时程序就崩溃了。可能是什么指针问题,就不知道怎么解决!-_-

先谢谢各位朋友进来看此贴,帮顶给分!
程序出错页面图:
http://www.sswhgz.cn/jiage2008/mysoft/err.jpg
程序+测试MDB数据库:
http://www.sswhgz.cn/jiage2008/mysoft/pandmdb.rar
VC++源程序:
http://www.sswhgz.cn/jiage2008/mysoft/sjk.rar

相关代码:
CListView::OnInitialUpdate();
if (m_pGridCtrl == NULL)
{
m_pGridCtrl = new CGridCtrl;
if (!m_pGridCtrl) return;

CRect rect;
GetClientRect(rect);
m_pGridCtrl->Create(rect, this, 10);
m_pGridCtrl->EnableTitleTips(FALSE);
m_pGridCtrl->SetEditable(TRUE);
m_pGridCtrl->EnableDragAndDrop(FALSE);
m_pGridCtrl->SetBkColor(16777214);
}

CSplitterWnd* pSplitter = (CSplitterWnd *)GetParentFrame()->GetActiveView()->GetParent();
CShowInfo *m_pViewInfo=(CShowInfo*)pSplitter->GetPane(0,0);
m_nShowPageNum = atoi(theApp.strSetDB[0]); //参数->每页显示记录数

if(m_pViewInfo->m_nNowConnectDB>0)
{
long ColCount,i,j;
_variant_t varValue;
_bstr_t bstrValue;
CString m_strTmp;
SYSTEMTIME ti,ti2; //执行时间 时间精确到分钟
int n =0,m_nSize,nColumnCount= 0,nRecordCount=0;
GV_ITEM Item;

//m_pGridCtrl->DeleteAllItems();
/*
if (m_pGridCtrl)
delete m_pGridCtrl;
m_pGridCtrl = NULL;
OnInitialUpdate();
*/
if(m_strNowSQL != InputSQL) //判断是否更改SQL语句,如果没有那么就是翻页操作!
m_nThePageNum = 1; //m_nThePageNum 保存当前正在浏览的页面,用于书签
else
m_nThePageNum = m_nNowPage; //m_nNowPage 保存目前页面

GetSystemTime(&ti); //计算SQL执行时间

//这里执行SQL语句:略
}
else
AfxMessageBox(_T("您没有连接数据库呢!"));
...全文
2510 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2010-05-19
  • 打赏
  • 举报
回复
您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知

见此回复三日内无回应
我们将强制结帖
相关规定详见界面界面版关于版主结帖工作的具体办法
gmp00 2010-05-11
  • 打赏
  • 举报
回复
知道怎么将已经初始化了的CGridCtrl里面更新数据吗?郁闷
jtg98g3 2008-10-23
  • 打赏
  • 举报
回复
学习。
度叶 2008-06-12
  • 打赏
  • 举报
回复
取得表格提示,可去除此bug,还有问题Q:32892802 本少也是一直用cgrid的.
ysq1026 2008-05-09
  • 打赏
  • 举报
回复
我也遇到同样的问题,我m_gridctl.SetRowCount(1000);就这1个就占用内存达到60M之多;
估计是这个内存问题没有处理好
gobest28 2007-12-27
  • 打赏
  • 举报
回复
2shcm,你好
问题解决了吗?
我将CGridCtrl控件换成了CListCtrl后,在第20页事也会出错啊
说明问题和控件的使用没关系了,可能分页处代码有问题吧
2shcm 2007-11-05
  • 打赏
  • 举报
回复
jhs1982419 朋友,您的意思是说我的数据库访问有问题吗?我以前的写的程序用这代码没问题,换了个CGridCtrl控件后就有问题了,不知道是不是内存泄露。目前还没有解决。有点郁闷.......
jhs1982419 2007-09-01
  • 打赏
  • 举报
回复
CRecordset::SetAbsolutePosition(pDispInfo->item.row)函数,把游标定位到那一行,然后获取每个字段的数据就可以了


对于ACCESS数据库的访问,VC中MFC类库提供专门的DAO类(CDaoDatabase和CDaoRecordset等),在这里,附带指出VC6.0还不能访问Access2000数据库(可以使用Access2000转换为能识别的低版本)。对于其他类型的数据库的访问,可以使用开放式数据源(ODBC),然后通过DAO访问ODBC也可以。恰恰CDaoRecordset支持双向游标,可以调用函数CDaoRecordset::SetAbsolutePosition()
raymonzhao 2007-08-31
  • 打赏
  • 举报
回复
没有环境不好测的.你有源码还是自己测吧.GRIDCTRL的源码我也看过一些,大概的框架也看了,并不是很难.既然你的错误是可以重现的,调起来应该可以的.相信自己.

我现在用的是另一个开源的列表,也是有一些或多或少的BUG,目前碰到的问题也都解决了.
加油加油.
cat3888 2007-08-30
  • 打赏
  • 举报
回复
只用过最简单的功能,没那么大数据量的,如果不是内存有泄漏
看看下面这个文章对你有没有帮助,现在没有链接了,就粘贴上来了



在VC中使用CGridCtrl控件实现数据库的显示、打印

摘 要 VC++6.0下使用控件CGridCtrl的虚模式实现显示、所见及所得打印数据库。

关键字 控件CGridCtrl 显示 打印 数据库

1 序言

在用vc开发数据库的项目时,通常要显示和打印数据库。一般用微软的DBGRID表格控件或列表控件显示[1],自己编写打印程序。微软的DBGRID控件没有一份好的帮助文档,界面不友好,比起C++Builder中的DBGRID来说是逊色不少;列表控件,界面单调,显示大量数据时速度很慢。打印数据库,自己还需要编写程序,费时费力。所以我就一直想找一个界面友好、显示大量数据库速度快、支持所见及所得打印的表格控件来显示和打印数据库。最近上网时无意中看到了CGridCtrl控件(如果你还没有用过,可以到http://www.codetools.com/miscctrl/gridctrl.asp/下载,上面还有详细的使用说明)。它是一个很漂亮的表格控件,不但满足我的要求,其功能接近Excel,而且源程序公开,可以修改,增加新的功能。如:清华大学黄伟增加了合并单元格的功能。

2 原理

DBGRID和一般的GRID的不同之处在于,一般的GRID并不适合显示大的数据量,如果一个表中有上万条记录都要插入到GRID中,这将是一个很慢的过程,并且在GRID中移动滚动条时,它的记录的滚动也是很慢。而DBGRID并不会真正把这些记录的数据全部插入到控件中,当DBGRID的滚动条滚动时,它会根据DBGRID的显示面积的大小和查询得到的总记录数计算出当前应该显示哪些行,然后插入到表格中,这样一来,速度肯定快,而且没有数据量多少的限制。幸运的是,CGridCtrl类已经为我们提供了这种机制,它是采用虚模式实现的。使用这种方式,即使你向这个该控件插入一百万条数据,它并不会真的生成一百万行,而是随着你的滚动条的滚动,计算出在屏幕上要显示的行和列,然后会向你提供一个接口,通过这个接口,你可以在这儿设置你要显示的数据。下面给出使用CGridCtrl控件的虚模式的步骤:

步骤一 初始化

在视图的初始化函数里添加如下代码:

void SetVirtualMode(TRUE)  设为虚模式

BOOL SetRowCount(int nRows) 设置总的行数。

BOOL SetFixedRowCount(int nFixedRows = 1) 设置固定的行数据

BOOL SetColumnCount(int nCols) 设置列数

BOOL SetFixedColumnCount(int nFixedCols = 1) 设置固定的列数

步骤二 响应消息 显示数据

我们假设CGridCtrl是放在单文档视图中,而且它关联的变量是m_GridCtrl,利用ClassWizard添加视图的OnNotify响应函数。这个响应函数的写法是固定的,类似下面的代码:

BOOL CGridCtrlTestView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{

if (wParam == (WPARAM)m_Grid.GetDlgCtrlID())

{

*pResult = 1;

GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;

if (GVN_GETDISPINFO == pDispInfo->hdr.code)

{

//这是添加的函数,在这个函数里设置当前要显示的数据

SetGridItem(pDispInfo);

return TRUE;

}

}

return CGridCtrlTestView::OnNotify(wParam, lParam, pResult);

}

在上面的代码中,SetGridItem(pDispInfo)是添加的函数,在这个函数里我们设置当前要显示的数据。pDispInfo是一个GV_DISPINFO的结构体对象,它包含了每个单元格的信息,如行号,列号,有没有位图,背景色,前景色等。CGRIDCTRL会把当前要显示那个单元格行号,列号传递给我们,我们只要设置里面显示的数据就可以了。如下面是一个显示数据的例子。

void CGridCtrlTestView::SetGridItem(GV_DISPINFO *pDispInfo)

{

pDispInfo->item.strText.Format("row%d,col%d",pDispInfo->item.row, pDispInfo->item.col);

}

通过上面的介绍,我们应该已经会使用CGridCtrl虚模式,下面说明一下用CGridCtrl虚模式做DBGRID的原理,大家知道,MFC的CRecordset类支持多种游标机制,如双向游标的,如果我们是用ClassWizard来生成一个CRecordset的派生类的,那么就可以调用函数CRecordset::SetAbsolutePosition(),用这种方式来实现显示真是太简单了,因为在上面的void CGridCtrlTestView::SetGridItem(GV_DISPINFO *pDispInfo)函数中,已经知道要显示哪一行,哪一列的数据。所以只要通过CRecordset::SetAbsolutePosition(pDispInfo->item.row)函数,把游标定位到那一行,然后获取每个字段的数据就可以了。但是使用上面的方法有一个不好的地方在于,我们必须用ClassWizard为每个表从CRecordset派生出新类,这样做很不方便,在VC知识库第六期上面有一篇介绍《单独使用Crecordset》文章,可是上面的CRecordset打开方式只能使用CRecordset::forwardOnly,游标只能向前滚动,我们不能使用CRecordset::SetAbsolutePosition()函数。而对于ACCESS数据库的访问,VC中MFC类库提供专门的DAO类(CDaoDatabase和CDaoRecordset等),在这里,附带指出VC6.0还不能访问Access2000数据库(可以使用Access2000转换为能识别的低版本)。对于其他类型的数据库的访问,可以使用开放式数据源(ODBC),然后通过DAO访问ODBC也可以。恰恰CDaoRecordset支持双向游标,可以调用函数CDaoRecordset::SetAbsolutePosition(),我们问题就不是就解决了吗。

步骤三 打印表格数据

打印显示在表格控件数据非常简单,重载视图函数OnPrint( )、OnBeginPrinting()和OnEndPringting(),分别调用控件的OnPrint(),OnBeginPrinting()和OnEndPrinting。其具体使用请看举例。

3 总结

使用CGRIDCTRl控件的好处在于不需要编写大量的程序,即可按照表格显示的效果打印,也不降低显示速度,方便,实用性强,提高用VC开发数据库项目的效率。同时,由于该控件已给出源代码,希望同行们继续完善、改进。

参考文献

[1] 杨宗长 VC中动态打开、显示数据库实现 电脑编程技巧与维护 中国电脑教育报社 第2期 2004

[2] 丛建刚 2000 Visual C++编程实战 青岛出版社

2shcm 2007-08-30
  • 打赏
  • 举报
回复
最后顶顶,万一没有理我。就自己静下心来慢慢研究。
2shcm 2007-07-22
  • 打赏
  • 举报
回复
哎,继续等待热心的朋友
cs_iceworld 2007-07-21
  • 打赏
  • 举报
回复
CGridCtrl最新版有bug,以前碰到过,就是刷新表格的时候,焦点不能在上面,否则会出断言错误。
2shcm 2007-07-20
  • 打赏
  • 举报
回复
多谢帮顶,等待热心的朋友.
GIS老王 2007-07-20
  • 打赏
  • 举报
回复
死是死了 不过没找出原因

期待!!
hurryboylqs 2007-07-18
  • 打赏
  • 举报
回复
帮顶
2shcm 2007-07-18
  • 打赏
  • 举报
回复
怎么好像没人看呀?是不是CGridCtrl没人用了.大家都用什么控件做表格?

15,981

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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