生成CListCtrl子类之后,如何解决当窗口的大小变化时出现了闪烁?

OracleJ 2011-08-24 05:33:10
我在VC++6.0环境下,新建了一个MFC单文档工程:工程名:TestList5,然后在CMainFrame类中声明一个CSplitterWnd m_splitter变量,重写了CMainFrame类的虚函数OnCreateClient 内容如下:部分代码省略
BOOL CMainFrame::OnCreateClient(......)
{
....
if(!m_splitter.CreateStatic(this,2,1))
return FALSE;
if(!m_splitter.CreateView(0,0,RUNTIME_CLASS(CTestList5FormView),paneSize,pContext)||
!m_splitter.CreateView(1,0,RUNTIME_CLASS(CTestList5View),paneSize,pContext))
{
m_splitter.DestroyWindow();
return FALSE;
}
return TRUE;
}
然后在项目中新建了一个类:CTestList5FormView : public CFormView 继承于CFormView类
在网上下载了:CHeaderCtrlCl : public CHeaderCtrl,CListCtrlCl : public CListCtrl这两个类,加载到工程中。
然后在CTestList5FormView类中实现了CTestList5FormView::OnInitialUpdate() 虚函数,内容如下:
void CTestList5FormView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
CRect r;
GetClientRect(&r);
m_ListCtrl.MoveWindow(r);
m_ListCtrl.SetBkColor(RGB(0,0,0)); //设置背景色
m_ListCtrl.SetRowHeigt(25); //设置行高度
m_ListCtrl.SetHeaderHeight(1.5); //设置头部高度
m_ListCtrl.SetHeaderFontHW(16,0); //设置头部字体高度,和宽度,0表示缺省,自适应
m_ListCtrl.SetHeaderTextColor(RGB(255,200,100)); //设置头部字体颜色
m_ListCtrl.SetTextColor(RGB(0,255,255)); //设置文本颜色
m_ListCtrl.SetHeaderBKColor(0,0,0,8); //设置头部背景色
m_ListCtrl.SetFontHW(15,0); //设置字体高度,和宽度,0表示缺省宽度
m_ListCtrl.SetColTextColor(2,RGB(255,255,100)); //设置列文本颜色
m_ListCtrl.SetItemTextColor(3,1,RGB(255,0,0)); //设置单元格字体颜色

m_ListCtrl.InsertColumn(0,_T("合约"),LVCFMT_CENTER,55);
m_ListCtrl.InsertColumn(1,_T("最新价"),LVCFMT_CENTER,60);
m_ListCtrl.InsertColumn(2,_T("买价"),LVCFMT_CENTER,60);
m_ListCtrl.InsertColumn(3,_T("卖价"),LVCFMT_CENTER,180);

m_ListCtrl.InsertItem(0,"CF201");
m_ListCtrl.SetItemText(0,1,"20905");
m_ListCtrl.SetItemText(0,2,"20900");
m_ListCtrl.SetItemText(0,3,"20905");

m_ListCtrl.InsertItem(1,"CF205");
m_ListCtrl.SetItemText(1,1,"21345");
m_ListCtrl.SetItemText(1,2,"21340");
m_ListCtrl.SetItemText(1,3,"21345");

m_ListCtrl.InsertItem(2,"SR201");
m_ListCtrl.SetItemText(2,1,"7419");
m_ListCtrl.SetItemText(2,2,"7419");
m_ListCtrl.SetItemText(2,3,"7420");

SetWindowLong(m_ListCtrl.m_hWnd ,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
m_ListCtrl.SetExtendedStyle(LVS_EX_HEADERDRAGDROP);
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
}
为了防止窗口大小发生变化,又实现了CTestList5FormView类的WM_SIZE消息:内容如下:
void CTestList5FormView::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
if(m_ListCtrl.GetSafeHwnd())
{
UpdateData(FALSE);
::InvalidateRect(m_ListCtrl.m_hWnd,NULL,TRUE);
m_ListCtrl.MoveWindow(0,0,cx,cy);
}
}
运行程序:出现如下界面:

代码如下链接:
http://download.csdn.net/source/3545487

请朋友们帮我看看那里出现了问题?谢谢
在线等
...全文
330 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
OracleJ 2011-08-26
  • 打赏
  • 举报
回复
研究了半天还是不行 唉 怎么回事呢 彻底崩溃了.........
ndy_w 2011-08-26
  • 打赏
  • 举报
回复
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, NULL);
gibsonboy 2011-08-26
  • 打赏
  • 举报
回复
看看这篇文章,你可以下载去研究研究,希望这种问题以后可以避免。
Suppress Flickering Scrollbars in Autosizing CListCtrl
OracleJ 2011-08-26
  • 打赏
  • 举报
回复
上面的方法全试过了,问题依然存在,我上面有工程的源代码,下载之后直接可以再vc++6.0上面运行,大家可以帮我调试一下,这几天这个问题把我整的晕头转向的,脑子不开窍了,都麻木了。谢谢各位了
OracleJ 2011-08-26
  • 打赏
  • 举报
回复
问题可能出现在这里,如果我新建一个基于对话框的mfc工程,然后基于这个页面添加一个CListCtrl的子类(CListCtrlCl),实现WM_SIZE消息,这个时候出现的页面就不会出现闪烁。
如果换成基于单文档的MFC工程,让那个view类无论继承CView还是CFormView添加的CListCtrl子类(CListCtrlCl)都会出现闪烁。
为什么基于对话框的工程不会出现闪烁,而基于单文档的就出现闪烁呢?请高手讲解?谢谢
xyytuo 2011-08-26
  • 打赏
  • 举报
回复
OracleJ 2011-08-26
  • 打赏
  • 举报
回复
只要能实现这种风格的列表,什么控件都可以,请求各位介绍一个也行。又处理了一天还是没有效果 都折磨疯了...... 求求各位了
cnzdgs 2011-08-25
  • 打赏
  • 举报
回复
再看一下父窗口有没有WS_CLIPCHILDREN风格,如果没有则加上。
cnzdgs 2011-08-25
  • 打赏
  • 举报
回复
把这行代码去掉:
::InvalidateRect(m_ListCtrl.m_hWnd,NULL,TRUE);
OracleJ 2011-08-25
  • 打赏
  • 举报
回复
这里只要显示期货品种价格的波动就可以了,CListCtrlCl这个效率我还没有测试,这个类我也是在网上找的(小弟刚接触vc半个月,对vc不是特别了解,所以有些东西只能从网上找了)。目前只看到这个CListCtrlCl类实现期货列表的页面外观,所以就先找个把结果整理出来然后在对他的效率进行测试。我已经在CListCtrlCl类中实现了WM_ERASEBKGND这个,闪烁问题还是存在。
::InvalidateRect(m_ListCtrl.m_hWnd,NULL,TRUE);把中间的null改成刷新区域测试过了,问题依旧存在。
Ginie 2011-08-25
  • 打赏
  • 举报
回复
::InvalidateRect(m_ListCtrl.m_hWnd,NULL,TRUE);可以把中间的NULL改成你刷新的区域。
ndy_w 2011-08-25
  • 打赏
  • 举报
回复
检查CListCtrlCl的绘制代码,源头上效率不高?
Eleven 2011-08-25
  • 打赏
  • 举报
回复
是不是你CListCtrl,CHeaderCtrl自绘的部分有问题啊?里面有处理WM_ERASEBKGND吗?
OracleJ 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cnzdgs 的回复:]
初始化时调用SetExtendedStyle给listctrl加上LVS_EX_DOUBLEBUFFER扩展风格。
[/Quote]
void CTestList5FormView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();

CRect r;
GetClientRect(&r);
DWORD exStyle = m_ListCtrl.GetExtendedStyle();
m_ListCtrl.SetExtendedStyle(exStyle | LVS_EX_DOUBLEBUFFER); m_ListCtrl.MoveWindow(r);
......
m_ListCtrl.InsertColumn(0,_T("合约"),LVCFMT_CENTER,55);
......
}
我已经加了这个LVS_EX_DOUBLEBUFFER扩展属性,但是问题还是没有解决?
#define LVS_EX_DOUBLEBUFFER 0x00010000
ndy_w 2011-08-25
  • 打赏
  • 举报
回复
闪烁原因一般是:
1 wm_paint中绘制时间过长。这个可以双缓冲解决。
2 wm_erasebkgnd中填充到wm_paint画完时间太长。这个可以在特定条件下不删除背景,直接return true。

cnzdgs 2011-08-24
  • 打赏
  • 举报
回复
初始化时调用SetExtendedStyle给listctrl加上LVS_EX_DOUBLEBUFFER扩展风格。
OracleJ 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 healer_kx 的回复:]
把背景绘制去掉,再去掉WS_HREDRAW | WS_VREDRAW 两个风格。
[/Quote]
试过了,还是没有解决闪烁问题
OracleJ 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ndy_w 的回复:]
::InvalidateRect(m_ListCtrl.m_hWnd,NULL,TRUE);
这句不用
[/Quote]
注释这句还是没有解决闪烁
OracleJ 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 ndy_w 的回复:]
引用 3 楼 oraclej 的回复:
双缓冲 不太了解?不知道如何实现,能给一个详细的代码吗?
把背景绘制去掉 是去掉黑色吗?还是其他的?谢谢楼上两位

你这个不是双缓冲的问题。要做的话是在listview的wm_paint里做。
意思是你处理消息,直接返回true。也是在listview的消息响应里做。
[/Quote]

我之前写了个子类继承CListView,然后把用CListCtrlCl生成列表,出现野指针的错误,所以就直接加载到formview中了。现在我在formview中处理了wm_erasebkgnd消息,直接返回true,但是还没有解决闪烁
ndy_w 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 oraclej 的回复:]
双缓冲 不太了解?不知道如何实现,能给一个详细的代码吗?
把背景绘制去掉 是去掉黑色吗?还是其他的?谢谢楼上两位
[/Quote]
你这个不是双缓冲的问题。要做的话是在listview的wm_paint里做。
意思是你处理wm_erasebkgnd消息,直接返回true。也是在listview的消息响应里做。
加载更多回复(4)

15,979

社区成员

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

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