1.更新窗口

即采用UpdateWindow()函数立即发送WM_PAINT消息更新整个窗口。

void CEditTestDlg::OnBnClickedBtnSysUpdate()
{
CString csTmp;
int i = ;
while (i < )
{
Sleep();
i += ;
csTmp.Format(_T("%d"),i);
m_value = csTmp;//无法更新只显示结果
//m_editNum.SetWindowText(csTmp);//无法更新也不显示结果
UpdateData(FALSE);
UpdateWindow();//能更新但再次操作会卡死
//Invalidate(FALSE);//无法更新只显示结果
//RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);//RDW_INVALIDATE和Invalidate()效果一样,RDW_ERASE导致闪烁
}
}

但是这会导致界面假死,更新过程中无法对窗口进行任何操作。控件的Control变量有时候无法更新Invalidate()一般都在多文档对话框里使用,RedrawWindow()是前两个都会去调用的函数,方式更多。详情见:MFC重绘函数

2. 定时器实现

在需要更新的位置调用SetTimer()启动定时器,在定时器响应函数OnTimer()里面来处理更新,可以同时启用多个定时器更新多个位置。

启动定时器:

void CEditTestDlg::OnBnClickedBtnTimerUpdate()
{
this->SetTimer(,,NULL);
this->SetTimer(,,NULL);
}

定时器内部处理:

void CEditTestDlg::OnTimer(UINT_PTR nIDEvent)
{
switch (nIDEvent)
{
case :
if (tmp >= )
{
this->KillTimer();
MessageBox(_T("定时器1停止!"), NULL, NULL);
return;
}
Sleep();
tmp += ;
m_value.Format(_T("%d"),tmp);
UpdateData(FALSE);
break;
case :
if (tmp1 >= )
{
this->KillTimer();
MessageBox(_T("定时器2停止!"), NULL, NULL);
return;
}
Sleep();
tmp1 += ;
m_value2.Format(_T("%d"),tmp1);
UpdateData(FALSE);
default:
break;
}
CDialog::OnTimer(nIDEvent);
}

通过定时器界面不会假死,实现也简单明了。

3. 线程更新

创建一个新的线程来更新界面,创建线程:

void CEditTestDlg::OnBnClickedBtnThreadUpdate()
{
CWinThread* pThread;
pThread = AfxBeginThread(UpdateThread,this);
}

线程内部实现:

static UINT UpdateThread(LPVOID lpParam)
{
CEditTestDlg *dlg = (CEditTestDlg*) lpParam;
int i = ;
while (i < )
{
Sleep();
i += ;
dlg->m_value2.Format(_T("%d"), i);
//dlg->UpdateData(FALSE);//release下可行
dlg->m_editCtl.SetWindowText(dlg->m_value2);//使用control变量
//dlg->GetDlgItem(IDC_EDIT2)->SetWindowText(dlg->m_value2);
}
return ;
}

在这里,最好不要用UpdateData(FALSE)来显示到界面,在Debug下回奔溃,而Release模式下没有任何问题,具体见:线程调用UpdateData函数出错

4. 线程中发送自定义消息更新

在线程中给窗口发送自定义的更新界面的消息,让消息加入系统消息队列达到更新界面的目的。自定义消息可参照:MFC添加自定义消息

void CEditTestDlg::OnBnClickedBtnMsgUpdate()
{
CWinThread* pThread;
pThread = AfxBeginThread(SendMsgThread,this);
}
static UINT SendMsgThread(LPVOID lpParam)
{
CEditTestDlg *dlg = (CEditTestDlg*) lpParam;
int i = ;
while (i < )
{
Sleep();
i += ;
dlg->m_value2.Format(_T("%d"), i);
//PostMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
//SendMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
SendMessageTimeout(dlg->m_hWnd, WM_UPDATEDATA, FALSE,NULL, SMTO_BLOCK, , NULL);
}
return ;
}

发送消息的时候PostMessage(),SendMessage()SendMessageTimeout()都可以实现,具体区别见:SendMessage和PostMessage区别

5. 设备绘制更新

直接在界面中不停的绘制变化的部分,这种方法也会造成假死。

void CEditTestDlg::OnBnClickedBtnDrawUpdate()
{
CString csTmp;
int i = ;
CDC* pDC = this->GetDC();
while (i < )
{
Sleep();
i += ;
csTmp.Format(_T("%d"),i);
pDC->TextOut(, , csTmp);
}
ReleaseDC(pDC);
}

6. STATIC控件更新

给STATIC控件赋值更新,同样会造成假死现象。(值得一提的是以前在VC6.0中可以对EIDT控件使用同样的方法更新而现在去测试却不行,希望有经验的人给予指导。)

void CEditTestDlg::OnBnClickedBtnStaticUpdate()
{
CString csTmp;
int i = ;
while (i < )
{
Sleep();
i += ;
csTmp.Format(_T("%d"),i);
m_csStaticNum = csTmp;//能更新但再次操作会卡死
//m_staticCtlNum.SetWindowText(csTmp);//不更新也不显示结果
UpdateData(FALSE);
}
}

7. 发送系统消息更新

直接给系统消息循环发送WM_PAINT消息来更新界面,但是同样会出现假死情况,所以可以创建一个函数DoEvent()实现:在有系统消息,如拖动点击等消息时,暂停处理我们发送的消息而优先去处理系统消息。

void CEditTestDlg::OnBnClickedBtnMsg()
{
CString csTmp;
int i = ;
while (i < )
{
Sleep();
i += ;
csTmp.Format(_T("%d"),i);
m_value = csTmp;//能更新但再次操作会卡死
//m_editNum.SetWindowText(csTmp);//无法更新也不显示结果
UpdateData(FALSE);
GetDlgItem(IDC_EDIT1)->SendMessage(WM_PAINT);//能更新但再次操作会卡死
DoEvents();//转出处理系统消息
}
}
//有系统消息时暂停处理系统消息
void DoEvents()
{
MSG msg; //定义一个MSG类型的变量
while(PeekMessage(&msg,NULL,,,PM_REMOVE)) //获取消息并把该消息从消息队列中移除(防止重复响应)。
{
TranslateMessage(&msg);//翻译消息 在合适的机会产生char消息
DispatchMessage(&msg); //将消息移交给过程函数
}
}

但是出现的问题是,我们在拖动对话框的时候,界面停止了更新。

所以比较而言,线程发送消息和定时器效果相对较好,界面不会假死,在进行拖动等操作的时候也不会出现停止等待的现象。

 

MFC界面更新实现方法的更多相关文章

  1. 【转】MFC界面更新实现方法

    原文网址:http://www.cnblogs.com/skywatcher/p/3572311.html 1.更新窗口 即采用UpdateWindow()函数立即发送WM_PAINT消息更新整个窗口 ...

  2. windows程序消息机制(Winform界面更新有关)

    windows程序消息机制(Winform界面更新有关) 转自:http://www.cnblogs.com/blosaa/archive/2013/05/31/3109586.html 1. Win ...

  3. 201709025工作日记--更新UI方法

    1.handler+Thread 和 runOnUIThread 和 handler.post 方法 区别: 从实现原理上,两者别无二致,runOnUiThread也是借助Handler实现的.  对 ...

  4. C# Winform频繁刷新导致界面闪烁解决方法

    C#Winform频繁刷新导致界面闪烁解决方法 一.通过对窗体和控件使用双缓冲来减少图形闪烁(当绘制图片时出现闪烁时,使用双缓冲) 对于大多数应用程序,.NET Framework 提供的默认双缓冲将 ...

  5. winform频繁刷新导致界面闪烁解决方法

    转自龙心文 原文 winform频繁刷新导致界面闪烁解决方法 一.通过对窗体和控件使用双缓冲来减少图形闪烁(当绘制图片时出现闪烁时,使用双缓冲) 对于大多数应用程序,.NET Framework 提供 ...

  6. C++做四则运算的MFC计算器(一)MFC界面创建

    学习最有效的方法就是实战,这两篇文章写了做MFC加减乘除计算器的过程. 第一写前台MFC界面搭建,第二写后台计算原理及代码. MFC编程参考教程:http://www.jizhuomi.com/sch ...

  7. solo升级以及自动化更新的方法

    使用solo过程总涉及到更新问题,所以就在这里把solo更新的方法总结一下.希望能给小伙伴们一些帮助.如何选择更新方法主要是跟你的部署方式有关,如果你是通过 docker方式进行部署,那么你可以还可以 ...

  8. windows核心编程课程实践---多线程文件搜索器(MFC界面)

    课上完了连老师见都没见一面QAQ....记录一下该小项目 效果如下: 1.实现文件搜索功能,并封装为类 1)首先是文件搜索类Rapidfinder的构造函数和析构函数和文件信息初始化函数和文件路径规格 ...

  9. ListView使用自定义适配器的情况下实现适配器的控件点击事件执行Activity界面中的方法

    如果ListView使用的是自定义的适配器,比如MyArrayAdapter extends ArrayAdapter<String> 那么,如何实现适配器中的点击事件执行activity ...

随机推荐

  1. 【mac开发.NET】No installed provisioning profiles match the installed iOS signing identities

    编译错误提示 /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets: Er ...

  2. PHP安全编程:register_globals的安全性 全局变量注册(转)

    如果你还能记起早期Web应用开发中使用C开发CGI程序的话,一定会对繁琐的表单处理深有体会.当PHP的register_globals配置选项打开时,复杂的原始表单处理不复存在,公用变量会自动建立.它 ...

  3. [转] 看懂UML类图和时序图

    PS: 组合关系:实心,一个类A属于另一个类,或多个类,但是类A不能单独存在去使用,A一般是一种抽象的东西 聚合关系:空心,一个类A可以单独存在使用 不论组合聚合,A的方法都会被直接调用. 看懂UML ...

  4. iTerm2和oh-my-zsh的个性化定制

    终于在某东做活动新入手了一台air,看身边小伙伴的mac的终端感觉好炫酷,于是乎准备自己也捯饬捯饬,google了一下,发现了osx平台上的终端神器iTerm2和用来代替bash的oh-my-zsh, ...

  5. NYOJ-744蚂蚁的难题(一)

    这个题都说是水题,楞是没做出来,看了好多题解,感觉这个规律没看懂,后来在讨论区看到了一个题解,感觉有点懂了,写一下自己的理解 首先要明白异或的意思,简单一句话: 同0异1,既然这样,让求区间a,b 中 ...

  6. shell 数组(in_array)

    if [[ ! "${array[@]}" =~ $val ]] ; then fi

  7. CSS权威指南学习笔记系列(1)CSS和文档

    题外话:HTML是一种结构化语言,而CSS是它的补充:这是一种样式语言.CSS是前端三板斧之一,因此学习CSS很重要.而我还是菜鸟,所以需要加强学习CSS.这个是我学习CSS权威指南的笔记,如有不对, ...

  8. ASP.NET中的MD5加密

    新人冒泡,打今起在园子里算是开博了,先来写点关于基础性的东西 为以后的写其他的文章做准备. 今天就先来说说MD5加密与在ASP.NET中如何实现MD5加密. MD5加密简单的说就是把一段明文 通过某种 ...

  9. SQL函数:用于将小写的数值翻译成大写的字符串

    --功能:  用于将小写的数值翻译成大写的字符串(支持到分,即小数点后两位)       --入口参数:@decNum------数字型变量    --返回:字符串    --举例:select db ...

  10. 关于Aspose对于Word操作的一些扩展及思考

    Aspose.word Aspose.Words是一款先进的类库,通过它可以直接在各个应用程序中执行各种文档处理任务.Aspose.Words支持DOC,OOXML,RTF,HTML,OpenDocu ...