[[[[[[[ 大家来说说OnOK()与OnClose()的根本区别 ]]]]]]]

yo_jo 2004-10-13 04:09:00
本人在平时使用时,二者从来没有注意过区别,但在这两天写的一段代码中就出现了一个问题(编译没有报任何错误,但在调试时最后就会出现 的错误),之后将原来的 CDialog::OnClose(); 替换为 CDialog::OnOK(); 就不再出现这个问题了,所以就想看看他们之间到底有什么区别,以下是我在调试时copy的源码,欢迎大家各抒己见!

--------------------------------------------------------------------------------

// OnOK()的.....
void CDialog::OnOK()
{
if (!UpdateData(TRUE))
{
TRACE0("UpdateData failed during dialog termination.\n");
// the UpdateData routine will set focus to correct item
return;
}
EndDialog(IDOK);
}

void CDialog::EndDialog(int nResult)
{
ASSERT(::IsWindow(m_hWnd));

if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
EndModalLoop(nResult);

::EndDialog(m_hWnd, nResult);
}

void CWnd::EndModalLoop(int nResult)
{
ASSERT(::IsWindow(m_hWnd));

// this result will be returned from CWnd::RunModalLoop
m_nModalResult = nResult;

// make sure a message goes through to exit the modal loop
if (m_nFlags & WF_CONTINUEMODAL)
{
m_nFlags &= ~WF_CONTINUEMODAL;
PostMessage(WM_NULL);
}
}

#define WM_NULL 0x0000

--------------------------------------------------------------------------------

// OnClose()的.....
_AFXWIN_INLINE void CWnd::OnClose()
{ Default(); }

LRESULT CWnd::Default()
{
// call DefWindowProc with the last message
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
return DefWindowProc(pThreadState->m_lastSentMsg.message,
pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam);
}

LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (m_pfnSuper != NULL)
return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);

WNDPROC pfnWndProc;
if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)
return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);
else
return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);
}
...全文
582 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
trustyourself 2005-05-27
  • 打赏
  • 举报
回复
mark
yo_jo 2004-10-19
  • 打赏
  • 举报
回复

最后总结一下
-------------------------------------------------------------------------
正如 rivershan(笨猫)(www.rivershan.com) ToWeightAnchor(ddd) crystal521(水晶泪) yszmax(两广~早餐是南瓜饼鸡蛋豆浆炒米饭) 4位的分析,OnClose()和OnOK()的主要区别在于:
1. OnOK()是CDialog的对象机制。首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框;
2. OnClose()是消息机制。它是CWnd的成员函数,WM_CLOSE消息将触发它,::OnClose()调用DefWindowProc的默认处理,只是关闭了一个窗口。
-------------------------------------------------------------------------
关于“什么情况下会产生消息阻塞?在实际中应如何避免?”的问题我已另外开贴,地址在:
http://community.csdn.net/Expert/topic/3470/3470961.xml?temp=.9333002
希望大家继续关注。

最后,谢谢大家的支持与关注!!
yo_jo 2004-10-18
  • 打赏
  • 举报
回复
╭═══╮ ╭═══╮ ╭══════╮   
╰╮ ╭╯ ╰╮ ╭╯ ╰╮ ╭══╮╰╮  
 ║ ║  ║ ║   ║ ║  ╰╮╰╮ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║  ╭╯╭╯ 
 ║ ║  ║ ║   ║ ╰══╯╭╯  
 ║ ║  ║ ║   ║ ╭═══╯   
 ║ ║  ║ ║   ║ ║       
 ║ ║  ║ ║   ║ ║       
 ║ ║   ║ ║   ║ ║       
 ╰╮╰╮ ╭╯╭╯   ║ ║       
  ╰╮╰═╯╭╯   ╭╯ ╰╮      
   ╰═══╯    ╰═══╯

自己顶一下
seekingman 2004-10-15
  • 打赏
  • 举报
回复
ToWeightAnchor(ddd)说的很正确,基本上就是这样子!
fun1357 2004-10-15
  • 打赏
  • 举报
回复
楼上说的有道理
Mr-Chen 2004-10-15
  • 打赏
  • 举报
回复
OnClose()是响应 WM_CLOSE , 所以消息有可能发生阻塞而是你的窗体关闭不了
但OnOK()是调用EndDialog的,所以一定能够关闭的
ToWeightAnchor 2004-10-15
  • 打赏
  • 举报
回复
CDialog::OnOK首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框

CDialog::OnCancel只调用CDialog::EndDialog
OnClose()是响应 WM_CLOSE 的.
yo_jo 2004-10-15
  • 打赏
  • 举报
回复
自己顶一下,大家对这样的问题没有兴趣吗?:(

╭═══╮ ╭═══╮ ╭══════╮   
╰╮ ╭╯ ╰╮ ╭╯ ╰╮ ╭══╮╰╮  
 ║ ║  ║ ║   ║ ║  ╰╮╰╮ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║  ╭╯╭╯ 
 ║ ║  ║ ║   ║ ╰══╯╭╯  
 ║ ║  ║ ║   ║ ╭═══╯   
 ║ ║  ║ ║   ║ ║       
 ║ ║  ║ ║   ║ ║       
 ║ ║   ║ ║   ║ ║       
 ╰╮╰╮ ╭╯╭╯   ║ ║       
  ╰╮╰═╯╭╯   ╭╯ ╰╮      
   ╰═══╯    ╰═══╯
yo_jo 2004-10-15
  • 打赏
  • 举报
回复
谢谢大家的指教,现在对于OnClose()和OnOK()的区别已经有了大致的了解

------------------------------------------------------------------------------
但现在还有个问题就是:一般什么情况下会产生消息阻塞吗?我在实际中应如何避免呢?
------------------------------------------------------------------------------
还希望大家继续支持!

╭═══╮ ╭═══╮ ╭══════╮   
╰╮ ╭╯ ╰╮ ╭╯ ╰╮ ╭══╮╰╮  
 ║ ║  ║ ║   ║ ║  ╰╮╰╮ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║   ║ ║ 
 ║ ║  ║ ║   ║ ║  ╭╯╭╯ 
 ║ ║  ║ ║   ║ ╰══╯╭╯  
 ║ ║  ║ ║   ║ ╭═══╯   
 ║ ║  ║ ║   ║ ║       
 ║ ║  ║ ║   ║ ║       
 ║ ║   ║ ║   ║ ║       
 ╰╮╰╮ ╭╯╭╯   ║ ║       
  ╰╮╰═╯╭╯   ╭╯ ╰╮      
   ╰═══╯    ╰═══╯
yszmax 2004-10-15
  • 打赏
  • 举报
回复
CDialog默认按下OK按钮触发CDialog::OnOK,
ON_COMMAND(IDOK, OnOK)这一句出现在DLGCORE.CPP中
CDialog::OnOK()的行为则是:
if (!UpdateData(TRUE))
{
TRACE0("UpdateData failed during dialog termination.\n");
// the UpdateData routine will set focus to correct item
return;
}
EndDialog(IDOK);
做了对话框的数据交换才退出。
而OnClose()是CWnd的成员函数,WM_CLOSE消息将触发它,而CWnd::OnClose()调用DefWindowProc的默认处理而已,只是关闭了一个窗口,
很显然,在对话框中,OnClose()因该是不提倡的。
提倡重载OnOK()或者以OnCommand宏为你的Ok按钮指定新的动作。
Wenxy1 2004-10-15
  • 打赏
  • 举报
回复
这是一个基本常识,对于Windows程序的整个运行过程,fcf128(Hacker)似乎不是很熟。
Wenxy1 2004-10-15
  • 打赏
  • 举报
回复
To fcf128(Hacker)
WM_CLOSE消息是如何处理的,调用OnClose(),
huazaimh 2004-10-15
  • 打赏
  • 举报
回复
搬个梯子来好好学习!
yo_jo 2004-10-15
  • 打赏
  • 举报
回复
to crystal521(水晶泪):

可以说说一般什么情况下会产生消息阻塞吗?我在实际中应如何避免呢?
yo_jo 2004-10-14
  • 打赏
  • 举报
回复
那就是说一个是消息机制,一个是CDialog的对象机制,这就是他们的本质区别?

看来我前面遇到的OnClose()关闭不了是由于消息没有接收到造成的,而用OnOK()就可以了,这就是说在MFC下对于CDialog最好还是使用OnOK()和OnCannel()来关闭窗体喽?

不知道我的理解对不对,还望高手指点!

*---------------------------------------------------------------------------
另: rivershan(笨猫)(www.rivershan.com)的信誉只有 1 ,真是佩服!!!!
等我结贴,我来做FAQ给你加点信誉吧~~~~
windywalk 2004-10-14
  • 打赏
  • 举报
回复
关闭按钮发送WM_CLOSE消息
同意笨猫
用模式对话框的时候就知道,OnOk将返回一个结果IDOK
而OnClose不会返回值
fcf128 2004-10-13
  • 打赏
  • 举报
回复
wenxy1(周末了,极速飙车) ( ) 信誉:100


OnClos()是当用单击窗本的关闭按钮时调用的。

这句不对吧??

OnClose()是响应 WM_CLOSE 的.

不知道 单击窗本的关闭按钮时调用 了什么。谁知道??
rivershan 2004-10-13
  • 打赏
  • 举报
回复
OnClose是响应WM_CLOSE消息吧。。。
OnOK是对话框关闭时返回一个IDOK
Jarrylogin 2004-10-13
  • 打赏
  • 举报
回复
UP
sjdf 2004-10-13
  • 打赏
  • 举报
回复
学习。
加载更多回复(6)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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