百分求教View中实时显示的问题!

AngryStone 2004-05-08 03:29:34
有这样一个问题,
当我按下界面中某个按钮(菜单)时,启动了一个处理函数(我将其放在Doc中),该函数持续的产生数据,需要将这些数据实时显示在View中,我该怎么做?
详细如下,

假如每次按键事件只产生一个数据,我可以在Doc类中产生的数据放在一块自己开辟的内存里,然后调用UpdateAllViews(),在View类中的OnDraw函数里显示这块内存中的数据。
但是现在在按键事件处理过程中,数据持续产生(类似与死循环),每产生一次数据,就算我调用了UpdateAllViews,由于没有跳出事件处理函数,显示也不能刷新,我该怎么办才可以让产生的数据实时显示呢?
...全文
125 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
AngryStone 2004-05-09
  • 打赏
  • 举报
回复
采用多线程来完成这个功能我也想过,惜乎麻烦了一些。

to ygzdev:在循环中UpdateAllViews是不可能完成这个功能的。

在按键事件中调用View类的Invalidate函数效果是否与UpdateAllViews一样,需要试一下,先谢过楼上回帖的朋友。
AngryStone 2004-05-09
  • 打赏
  • 举报
回复
那么我这样理解对不对?
UpdateAllViews本身直接调用了View类中的OnUpdate函数,所以可以进入OnUpdate。
而由OnUpdate到OnDraw函数,本身是通过发送消息-->响应消息来完成的。
所以对于单线程的MFC程序中的死循环如果调用UpdateAllViews,只能进入OnUpdate函数,虽然也发送了WM_PAINT消息,但由于CPU只能在循环中运行而不能响应消息而进入OnDraw函数,所以OnDraw函数中的代码是不会被运行的。
我在View类的OnUpdate函数中添加:
void CRTViewView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
CView::OnUpdate(pSender,lHint,pHint);
CDC *pDC=GetDC();
CRTViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(0,0,pDoc->m_Viewedstr);
}
实际上就可以完成实时显示的功能了。
但不知道这样将本该在OnDraw中处理的显示问题放到OnUpdate中来,会不会给程序整体带来什么不利影响?
菜牛 2004-05-09
  • 打赏
  • 举报
回复
OnUpdate从内部调用了OnDraw函数,而OnDraw函数调用了OnPaint,不知道对不对。
错。
基类CView::OnUpdate()本身调用Invalidate(TRUE);发出WM_PAINT消息,OnPaint()响应WM_PAINT消息,在OnPaint()里调用OnDraw()。

BEGIN_MESSAGE_MAP(CView, CWnd)
//{{AFX_MSG_MAP(CView)
ON_WM_PAINT()
ON_WM_MOUSEACTIVATE()
ON_WM_CREATE()
ON_WM_DESTROY()

// Standard commands for split pane
ON_COMMAND_EX(ID_WINDOW_SPLIT, OnSplitCmd)
ON_UPDATE_COMMAND_UI(ID_WINDOW_SPLIT, OnUpdateSplitCmd)

// Standard commands for next pane
ON_UPDATE_COMMAND_UI(ID_NEXT_PANE, OnUpdateNextPaneMenu)
ON_COMMAND_EX(ID_NEXT_PANE, OnNextPaneCmd)
ON_UPDATE_COMMAND_UI(ID_PREV_PANE, OnUpdateNextPaneMenu)
ON_COMMAND_EX(ID_PREV_PANE, OnNextPaneCmd)
//}}AFX_MSG_MAP
// special command for Initial Update
ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
END_MESSAGE_MAP()

void CView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/)
{
ASSERT(pSender != this);
UNUSED(pSender); // unused in release builds

// invalidate the entire pane, erase background too
Invalidate(TRUE);
}

void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}

MFC默认是单线程的。多线程需要自己创建。
seasol 2004-05-09
  • 打赏
  • 举报
回复
在循环中
PeekMessage,如果发现有WM_PAINT事件,让其执行
AngryStone 2004-05-09
  • 打赏
  • 举报
回复
谢谢Mackz,我用单步调了一下,发现程序运行时只是进入了OnUpdate函数,并没有进入OnDraw,所以不能显示数据。加上UpdateWindow()也没用。
但是根据我以前所了解的,OnUpdate从内部调用了OnDraw函数,而OnDraw函数调用了OnPaint,不知道对不对。
另外,一个MFC程序是本身只有一个线程吗,还是有多个线程组成?

上面我写的死循环只是简化的写法,是一个从外部端口读入数据的循环,加上一些判断就可以跳出。
菜牛 2004-05-09
  • 打赏
  • 举报
回复
死循环是肯定的,要采取别的办法解决。
对于你的显示没有更新,在Invalidate()后面加一句:UpdateWindow()试试。
AngryStone 2004-05-09
  • 打赏
  • 举报
回复
昨天看了朋友们的回复,我按下面代码改写:
消息响应函数:
void CRTViewDoc::OnTest()
{
CString MSG_Str;
int i=0;
for(;;i++)
{
MSG_Str.Format("%d",i);
m_Viewedstr="Hello" +MSG_Str;//m_Viewedstr是一个CString型公有变量,用来存储并显示。
UpdateAllViews(NULL);
}
}
在View中重载OnUpdate():
void CRTViewView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
Invalidate();
}
重载Ondraw():
void CRTViewView::OnDraw(CDC* pDC)
{
CRTViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->TextOut(0,0,pDoc->m_Viewedstr);
}
但是运行的结果是程序陷入循环,界面上没有任何内容显示。当然,如果不加循环,是可以正常显示的。
请朋友们指点。
AngryStone 2004-05-09
  • 打赏
  • 举报
回复
多谢大家的帮助,由于Mackz朋友非常仔细的告诉了我解决办法。如我所言,给分100。
对其他的朋友也致以非常的感谢!
菜牛 2004-05-09
  • 打赏
  • 举报
回复
在循环中UpdateAllViews是可能完成这个功能的。
你在CView中的OnUpdate()里调用Invalidate()了吗?
countryboy 2004-05-09
  • 打赏
  • 举报
回复
up
菜牛 2004-05-09
  • 打赏
  • 举报
回复
不如这样:
void CRTViewView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
//CView::OnUpdate(pSender,lHint,pHint);
CDC *pDC=GetDC();
OnDraw(pDC);
ReleaseDC(pDC);
}
ygzdev 2004-05-08
  • 打赏
  • 举报
回复
那就在你的循环里面UpdateAllViews啊
UDX协议 2004-05-08
  • 打赏
  • 举报
回复
把处理放在线程中,每产生一个新数据,对view发一个消息,重新绘制新数据。

最好,每按一次按扭是通知线程去产生新数据,而不是在按扭事件里做事情。
byry 2004-05-08
  • 打赏
  • 举报
回复
在你按键事件处理过程中,每产生一次数据,需要刷新一次视图,所以,在你的按键事件中,当数据更新完毕后,你要加上:
CMainFrame *pMainFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
C***View* pView = (C***View*)pMainFrame->GetActiveView();
pView->Invalidate();

15,979

社区成员

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

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