通过timer实现edit滚动显示文本时的问题

wuruijing 2010-06-15 09:20:13
vc程序上在对话框建立edit,然后让其水平(或垂直)滚动显示文本。
以垂直滚动(我的思路就是不停的把第一行显示到最后)为例:
在对话框类中定义
CEdit testedit;
在界面上放一个按钮,其单击事件写入下面代码:
testedit.Create(WS_VISIBLE|ES_MULTILINE,CRect(0,100,200,200),this,25001);
CString teststr;
teststr = teststr + "a" + "\r\n";
teststr = teststr + "bb" + "\r\n";
teststr = teststr + "ccc" + "\r\n";
teststr = teststr + "dddd" + "\r\n";
teststr = teststr + "eeeee" + "\r\n";
teststr = teststr + "ffffff" + "\r\n";
teststr = teststr + "ggggggg" ;
testedit.SetWindowText(teststr);
SetTimer(2,150,NULL);
ontimer事件写入下面代码:
KillTimer(nIDEvent);
CString s;
int position;
testedit.SetRedraw(FALSE);//这句和下面那句testedit.SetRedraw(TRUE);都是按照网上的建议加上的,但加上似乎没什么用处,且水平滚动时,加上此代码还会让屏幕看不出滚动效果
testedit.GetWindowText(s);
position=s.Find("\r\n");
s=s.Right(s.GetLength()-position-2)+"\r\n"+s.Left(position);
testedit.SetWindowText("");
testedit.SetWindowText(s);
testedit.UpdateWindow();
CDialog::OnTimer(nIDEvent);
testedit.SetRedraw(TRUE);
SetTimer(2,150,NULL);


在对话框的OnCtlColor事件写入下面的代码:
int l_iCtrlID = pWnd->GetDlgCtrlID();


if(l_iCtrlID>25000 && l_iCtrlID<=30000)//我的程序中edit的控件id都是在此范围内
{
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,255));
}


但现在的问题是,我启动程序,点击测试按钮(就是创建并显示edit,启动timer),然后程序运行一段时间后(不超过1小时),界面的显示就乱了,望高手指点代码错误之处,多谢!
...全文
252 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuruijing 2010-06-22
  • 打赏
  • 举报
回复
哦,刚才没注意,贴OnCtlColor代码时贴出了大量测试代码,抱歉!
我现在手头没有最终代码,回头整理一份再贴出来吧
wuruijing 2010-06-22
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 visualeleven 的回复:]
你上面贴的CEditEx类他的背景是有颜色的,不是透明的。。。你没有注意吗??
[/Quote]
这样写有矛盾吗?我的edit有背景色,我开始测试时没有设透明,看显示的字有白背景,所以才加的。那为什么换了控件就可以?还有,程序是在长时间运行后才开始乱的(我说的乱就是edit的背景色,字体、字色都时有时无),运行时间和我的timer设置有关,如设成150毫秒,程序大约可正常运行40-50分钟,如设成1秒,程序大约可运行4小时左右,然后乱了。
vc水平很差,望高手指教!
Eleven 2010-06-22
  • 打赏
  • 举报
回复
你上面贴的CEditEx类他的背景是有颜色的,不是透明的。。。你没有注意吗??
wuruijing 2010-06-22
  • 打赏
  • 举报
回复
我再重新粘贴一下修改后的OnCtlColor代码:
HBRUSH CTest2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (1==editflag)
{
KillTimer(m_timerID2);
}
hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_DLG)
{
hbr = m_hBrush;
}
int l_iCtrlID = pWnd->GetDlgCtrlID();


if(l_iCtrlID>25000 && l_iCtrlID<=30000)
{
if (l_iCtrlID==25002)
{
l_iCtrlID=25002;
}

int testcolor;
testcolor =screen_play_array[l_iCtrlID-25001][screen_current_file_id[l_iCtrlID-25001]].backcolor;
pDC->SetBkColor(screen_play_array[l_iCtrlID-25001][screen_current_file_id[l_iCtrlID-25001]].backcolor);

testcolor =screen_play_array[l_iCtrlID-25001][screen_current_file_id[l_iCtrlID-25001]].fontcolor;
pDC->SetTextColor(screen_play_array[l_iCtrlID-25001][screen_current_file_id[l_iCtrlID-25001]].fontcolor);

}
if (1==editflag)
{
m_timerID2=SetTimer(2,150,NULL);
}
return hbr;
}
wuruijing 2010-06-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xianglitian 的回复:]
你OnCtlColor里的代码不全吧
全贴出来看看
[/Quote]
OnCtlColor里面的代码都在这里了。
实际上,这个问题我已经解决了,解决的办法是从网上下了一个名叫“CEditEx”的控件,然后将edit换成CEditEx控件即可,但我迟迟没有结贴的原因在于我不清楚我原来那样写错在哪里,为什么CEditEx控件就可以了?这个控件代码如下:
CEditEx.cpp:
// EditEx.cpp : implementation file
//
#include "stdafx.h"
#include "CEditEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEditEx
CEditEx::CEditEx()
{
}
CEditEx::~CEditEx()
{
}

BEGIN_MESSAGE_MAP(CEditEx, CEdit)
//{{AFX_MSG_MAP(CEditEx)
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditEx message handlers
HBRUSH CEditEx::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here

// TODO: Return a non-NULL brush if the parent's handler should not be called
// TODO: Return a non-NULL brush if the parent's handler should not be called

//set text color
pDC->SetTextColor(m_crText);
//set the text's background color
pDC->SetBkColor(m_crBackGnd);
//return the brush used for background this sets control backgroun
return m_brBackGnd;
}

void CEditEx::SetBackColor(COLORREF rgb)
{
//set background color ref (used for text's background)
m_crBackGnd = rgb;

//free brush
if (m_brBackGnd.GetSafeHandle())
m_brBackGnd.DeleteObject();
//set brush to new color
m_brBackGnd.CreateSolidBrush(rgb);

//redraw
// Invalidate(TRUE);
}

void CEditEx::SetTextColor(COLORREF rgb)
{
//set text color ref
m_crText = rgb;
//redraw
// Invalidate(TRUE);
}
void CEditEx::SetTextFont(int nSize)
{
CClientDC dc(this);
CFont* font = new CFont;
font->CreatePointFont(nSize, _T("System"), &dc);

SetFont(font, TRUE);
delete font;
}




CEditEx.h代码:
#if !defined(AFX_EDITEX_H__9B5C9C39_B497_4EBB_91BC_8D23F5BFEDBE__INCLUDED_)
#define AFX_EDITEX_H__9B5C9C39_B497_4EBB_91BC_8D23F5BFEDBE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditEx.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CEditEx window
class CEditEx : public CEdit
{
// Construction
public:
CEditEx();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditEx)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEditEx();
void SetTextColor(COLORREF rgb);
void SetBackColor(COLORREF rgb);
void SetTextFont(int nSize);
// Generated message map functions
protected:
//text and text background colors
COLORREF m_crText;
COLORREF m_crBackGnd;
//background brush
CBrush m_brBackGnd;
//{{AFX_MSG(CEditEx)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EDITEX_H__9B5C9C39_B497_4EBB_91BC_8D23F5BFEDBE__INCLUDED_)

再次感谢!
wuruijing 2010-06-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 visualeleven 的回复:]
if(l_iCtrlID>25000 && l_iCtrlID<=30000)//我的程序中edit的控件id都是在此范围内
{
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,255));
}
-----------……
[/Quote]
能否具体讲一下怎么刷新?问的很幼稚,见笑了
Eleven 2010-06-22
  • 打赏
  • 举报
回复
if(l_iCtrlID>25000 && l_iCtrlID<=30000)//我的程序中edit的控件id都是在此范围内
{
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,255));
}
-------------------------------------------------------
你这里设置了背景透明,而你在显示文本的时候,并没有先刷新显示区域,所以先前显示的文本并没有被擦掉,后面写入的内容会把先前的内容覆盖,所以就乱了。。。
向立天 2010-06-22
  • 打赏
  • 举报
回复
你OnCtlColor里的代码不全吧
全贴出来看看
wuruijing 2010-06-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 visualeleven 的回复:]
还没搞定???
[/Quote]
不知道怎么搞定,紧急求救啊!!!!!!
应该是timer中的问题
Eleven 2010-06-16
  • 打赏
  • 举报
回复
还没搞定???
wuruijing 2010-06-16
  • 打赏
  • 举报
回复
用其他编程语言实现这个功能应该是非常容易的,但vc怎么就这么麻烦呢。挺急的,望高手帮忙!只要能实现循环滚屏显示即可。
wuruijing 2010-06-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xsgluozi 的回复:]
我这里试了一下,Ontimer里面这样写是可以滚动的啊

C/C++ code

void CTestMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default

CString s;
int positio……
[/Quote]
这样确实可以滚动,但程序连续运行一段时间后(应该不超过1小时),edit的背景色,字体等就乱了
wuruijing 2010-06-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xsgluozi 的回复:]
你的界面乱是因为这里
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
你create了之后没有释放,而这个消息响应函数是一直在调用的,GDI资源耗完了就乱了
[/Quote]
能不能说具体一点,怎样释放?一释放,背景色不就没了吗?刚开始用vc,对vc的内部工作机制不了解,希望高手能说具体一点,谢谢
我的测试程序的OnCtlColor完整代码如下,应该改成什么样?
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

// TODO: Return a different brush if the default is not desired
int l_iCtrlID = pWnd->GetDlgCtrlID();


if(l_iCtrlID>25000 && l_iCtrlID<=30000)
{
hbr=CreateSolidBrush(RGB(0,255,0));
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,255));
}


return hbr;
}
还有,我曾实验,把timer中的代码停掉(也就是先不让edit滚动),OnCtlColor中的代码不变,然后程序运行了较长一段时间(当时我试了大约2-3小时)也没出问题。
再次感谢!
晒月光的青蛙 2010-06-15
  • 打赏
  • 举报
回复
我这里试了一下,Ontimer里面这样写是可以滚动的啊

void CTestMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default

CString s;
int position;
m_testEdit.SetRedraw(FALSE);//这句和下面那句testedit.SetRedraw(TRUE);都是按照网上的建议加上的,但加上似乎没什么用处,且水平滚动时,加上此代码还会让屏幕看不出滚动效果
m_testEdit.GetWindowText(s);
position=s.Find(_T("\r\n"));
s=s.Right(s.GetLength()-position-2)+_T("\r\n") +s.Left(position);
m_testEdit.SetWindowText(_T(""));
m_testEdit.SetWindowText(s);
m_testEdit.UpdateWindow();

m_testEdit.SetRedraw(TRUE);


CDialog::OnTimer(nIDEvent);
}

kakaximodo 2010-06-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xsgluozi 的回复:]
你的界面乱是因为这里
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
你create了之后没有释放,而这个消息响应函数是一直在调用的,GDI资源耗完了就乱了
[/Quote]
资源在用了之后要记得释放
晒月光的青蛙 2010-06-15
  • 打赏
  • 举报
回复
你的界面乱是因为这里
hbr=CreateSolidBrush(RGB(0,255,0));//设置背景色、字色
你create了之后没有释放,而这个消息响应函数是一直在调用的,GDI资源耗完了就乱了

15,980

社区成员

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

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