关于OnInitDialog()与OnPaint()的问题

heartgoon2010 2011-04-12 09:45:27
要在窗口中输出文本,可以先创建一个基于对话框的工程,然后在对话框类的OnPaint函数中添加代码:
void CTestDlg::OnPaint() 
{
if (IsIconic())
{
... }
else
{
CDC *pDc=GetDC(); //added
pDc->TextOut(50,60,"Hello world"); //added

CDialog::OnPaint();
}
}

书上说:之所以在对话框的OnPaint函数中输出文本,是因为在对话框每次需要重绘时会产生WM_PAINT窗口消息,进而执行消息处理函数OnPaint,也就会在每次窗口重绘时执行代码,在窗口中输出文本...
我的疑问是:
(1)OnInitDialog()与OnPaint()在工程运行时的执行顺序是怎样的,它们分别负责什么工作(越具体越好)?当我把代码CDC *pDc=GetDC(); pDc->TextOut(50,60,"Hello world");加到OnInitDialog()而不是OnPaint()中时,为什么不能显示Hello world?
(2)“在对话框每次需要重绘时会产生WM_PAINT窗口消息”这里的“每次需要重绘时”指的是什么,也就是说OnPaint函数在什么情况下会被调用?
说到底就是函数OnInitDialog()与OnPaint()在工程运行时起的作用问题以及OnPaint()何时调用的问题,希望高手帮忙解答,谢了!
...全文
954 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2011-05-10
  • 打赏
  • 举报
回复
您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知

见此回复三日内无回应
我们将强制结帖
相关规定详见界面界面版关于版主结帖工作的具体办法
psbeond 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 xuddk727 的回复:]
1.oninitdlg 初始化对话框,LS都没有提及,此时对话框未创建,因此没有对话框DC供你使用,当此函数返回时完成创建, ONPAINT负责绘制。
2.onpaint在部分DC或全部无效时(例如遮盖后重置焦点等)触发,当然你也可以手动调用它。
[/Quote]

第一条是不对的。执行到OnInitDialog时,对话框已经完全创建出来了,这个虚函数是让你执行一些额外的工作,比如你可能想给对话框再创建几个子控件等等。
tanling_zero 2011-04-14
  • 打赏
  • 举报
回复
OnInitDialog 每次开启程序运行一次,做初始化工作。
OnPaint 窗口重绘,一般默认设置只有当窗口重新获取焦点或者放大缩小窗口,才会运行OnPaint。

你可以这样想想一下,OnInitDialog 在创建窗口OnPaint画出窗口

CDC *pDc=GetDC(); //added

pDc->TextOut(50,60,"Hello world"); //added
运行逻辑:
OnInitDialog先做初始化信息,然后调用OnPaint绘制窗口和Hello world
显示窗口和Hello world.但是没有获取窗口焦点。默认其他窗口挡住了,所以OnPaint不刷新,Hello world也就不现实出来了。

我以前也出现过这个问题,在Opaint中贴图,闪一下就不见了,我就只好这么理解了。
无水先生 2011-04-14
  • 打赏
  • 举报
回复
OnInitDialog()只执行一次
onpaint()经常执行
nanjingshenxiaobo 2011-04-14
  • 打赏
  • 举报
回复
onInitDialog()是用来进行初始化时调用的函数,它在对话框显示之前调用,那是对话框都没有显示,你输出文本肯定没有用,并且在对框显示的时候,会自动发消息WM_PAINT,调用onPaint();如果你没有在onPaint()中没有写对应的代码的话,就算之前有输出文本,也会被刷掉!
许文君 2011-04-14
  • 打赏
  • 举报
回复
1.oninitdlg 初始化对话框,LS都没有提及,此时对话框未创建,因此没有对话框DC供你使用,当此函数返回时完成创建, ONPAINT负责绘制。
2.onpaint在部分DC或全部无效时(例如遮盖后重置焦点等)触发,当然你也可以手动调用它。
psbeond 2011-04-14
  • 打赏
  • 举报
回复
OnInitDialog在前,OnPaint在后,界面上显示的东西,都是在OnPaint中绘制的。你在OnPaint中没有输出Hello world,当然看不到了。
QQ282881515 2011-04-14
  • 打赏
  • 举报
回复
1、OnInit.....是初始化的时候调用的 只调用一次
2、OnPaint 是绘制界面的,基本上界面动一下就调用一次的,百度之WM_PAINT
到底谁先谁后,设置个断点跟踪一下就OK了!跟踪代码是学编程必须的!
Eleven 2011-04-14
  • 打赏
  • 举报
回复
你可以在其它地方绘制图形,不过只要刷新,你的内容就没有,建议还是在OnPaint函数中去绘制图形~
tompaz 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 hkf314 的回复:]

引用 5 楼 heartgoon2010 的回复:
引用 4 楼 hkf314 的回复:
刷下当你的窗体需要时,例如,有一部分被挡住了,那就可能会产生WM_PAINT消息,至于,OnInitDoialog这个在WM_PAINT消息之前,而且是对话框第一次创建才产生,而WM_PAINT消息随时都有可能产生

OnInitDialog就像OnCreate,一样,当你创建成功时,才开始Show……
[/Quote]
神奇的思维
许文君 2011-04-14
  • 打赏
  • 举报
回复
Sent to the dialog box procedure immediately before a dialog box is displayed. Dialog box procedures typically use this message to initialize controls and carry out any other initialization tasks that affect the appearance of the dialog box.
哎,草,最近百说百错,郁闷了。
liujie250079934 2011-04-13
  • 打赏
  • 举报
回复
看看孙鑫的视频吧
菜鸟二号 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 heartgoon2010 的回复:]
引用 4 楼 hkf314 的回复:
刷下当你的窗体需要时,例如,有一部分被挡住了,那就可能会产生WM_PAINT消息,至于,OnInitDoialog这个在WM_PAINT消息之前,而且是对话框第一次创建才产生,而WM_PAINT消息随时都有可能产生

OnInitDialog就像OnCreate,一样,当你创建成功时,才开始ShowWindow;

hwnd = CreateWind……
[/Quote]

可以的

在OnInitDialog里面创建一个定时器,时间越短越好

在OnTimer()
{
CDC *pDc=GetDC();
pDc->TextOut(50,60,"Hello world");
//下面一句是释放的,我猜的,不知道是不是这么写的
pDc->ReleaseDC();
}


这样就ok了
heartgoon2010 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hkf314 的回复:]
刷下当你的窗体需要时,例如,有一部分被挡住了,那就可能会产生WM_PAINT消息,至于,OnInitDoialog这个在WM_PAINT消息之前,而且是对话框第一次创建才产生,而WM_PAINT消息随时都有可能产生

OnInitDialog就像OnCreate,一样,当你创建成功时,才开始ShowWindow;

hwnd = CreateWindowEx(...);
ShowWind……
[/Quote]
把代码CDC *pDc=GetDC(); pDc->TextOut(50,60,"Hello world");加到OnInitDialog()而不是OnPaint()中,能不能通过某种方式也想达到显示Hello world的效果呢?
菜鸟二号 2011-04-12
  • 打赏
  • 举报
回复
刷下当你的窗体需要时,例如,有一部分被挡住了,那就可能会产生WM_PAINT消息,至于,OnInitDoialog这个在WM_PAINT消息之前,而且是对话框第一次创建才产生,而WM_PAINT消息随时都有可能产生

OnInitDialog就像OnCreate,一样,当你创建成功时,才开始ShowWindow;

hwnd = CreateWindowEx(...);
ShowWindow(hwnd, cmd_show);

而ShowWindow时将产生WM_PAINT消息
heartgoon2010 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
(1)你的绘图代码放到OnInitDialog中被后面的刷新刷掉了,你可以分别在两个函数中加个断点,看看哪个先执行不就很清楚了

(2)看MSDN对WM_PAINT消息的说明
[/Quote]
绘图代码放到OnInitDialog中被后面的刷新刷掉了?请问一下这个在代码的哪儿有反映?刷新在什么时候进行?谢了!
两个函数的执行顺序很容易弄清楚。
HowToP2p 2011-04-12
  • 打赏
  • 举报
回复
OnInitDialog用于初始化
OnPaint每当窗口重绘都会被调用,所以绘图放在OnPaint中才能一直存在
Eleven 2011-04-12
  • 打赏
  • 举报
回复
(1)你的绘图代码放到OnInitDialog中被后面的刷新刷掉了,你可以分别在两个函数中加个断点,看看哪个先执行不就很清楚了

(2)看MSDN对WM_PAINT消息的说明

15,979

社区成员

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

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