MoveWindow下出现Debug Assertion Failed!----

来源:互联网 发布:太极计算机 知乎 编辑:程序博客网 时间:2024/05/20 09:46

效果图:


代码:


---------------------------------------------------
问题为什么出现?
第1步:明确是哪种调试!-----------分2种:1.Debug 2.Release
      在Release版本运行正常!而在Debug版本调试错误!
第2步:启动调试(怎样调试?设置断点后调试,自然会找到)---->查找原因(详见原因截图)


第3步:总结是什么问题?----------->确定问题出自于:ASSERT(::IsWindow(m_hWnd));
----------
很高兴你通过Debug调试了,并进入下一步MSDN查找
第1步:检查ASSERT---->
      --->摘自MSDN:ASSERT tests an expression. If the expression is false, it breaks into the kernel debugger.
          很明显断言失败!停止了调试
      --->还是不够详细,继续查找--->
      --->摘自MSDN:If Expression evaluates to FALSE, a message will be displayed in the Debugger Command window. The

message contains the source-code string of Expression, as well as the path of the source-code file and the line

number in that file of the instruction that called the macro. In this event, ASSERT can be ignored and the process

or thread in which ASSERT occurred can be terminated. Alternatively, the debugger can be used to analyze the

situation or to edit memory. If ASSERT is ignored, execution continues as if the g command was entered.
翻译:如果表达式值为FALSE,调试器命令窗口将显示消息,消息内容包含出错的文件名与第几行出错.(备注:详见错误图,的确很详细)
     如果按下忽略将跳过继续执行(备注:这就是为什么你按下"忽略"为什么会能"正常运行"了的真正原因)
----找出真正原因:If the expression is false, it breaks into the kernel debugger.
////////////////////////////以上摘自MSDN,绝对官方权威数据!/////////////////////////////////
第2步:很明显ASSERT(::IsWindow(m_hWnd));----->::IsWindow(m_hWnd)返回值为FALSE
第3步:什么情况下::IsWindow(m_hWnd)返回值为FALSE?
      摘自MSDN:
              Return Values
              If the window handle identifies an existing window, the return value is nonzero.
              If the window handle does not identify an existing window, the return value is zero. 
       返回0(即FALSE)的情况----->参数句柄根本没有标识一个已存在的窗口!
----找出真正原因:m_hWnd根本无效!
////////////////////////////以上摘自MSDN,绝对官方权威数据!/////////////////////////////////
第4步:m_hWnd无效怎么办?------->定义2个试试:第1个:m_edit1.m_hwnd;第2个:if(m_edit1.m_hWnd)(当然MoveWindow包含在if中)
      测试结果:第1个无效;第2个有效
第5步:为什么第2个有效?加了if的那个
      分析原因:if保护了m_hWnd的有效,而没if的m_hWnd很明显被干掉了.
------------------------
冷战中....是不是if有问题?(回答:if绝对没错,错的原因m_hWnd)
很高兴你能进入最后一步,并进入Debug调试查找---->
第1步:通过MessageBox调试,如果你来过,一定会留下足迹.
      终于发现,不管m_hWnd有效无无效都会提示MessageBox,不过无效的m_hWnd只运行了一次,之后就在也没提示了?
第2步:为什么之后没有了?
      ---->既然m_hWnd标识的是窗口句柄,如果第1次无效,很明显窗口根本不存在----->
      ---->检测OnInitDialog().窗口是在这个初始化对话框函数完成之后显示的----->第1次的OnSize()的m_hWnd无效,很可能获得

          就是没创建窗口之前的,所以造成m_hWnd失效,直接导致::IsWindow(m_hWnd)返回值为0,造成失败
      ---->而if语句保护为真,让第1次的假避开          (备注:庐山真面目)
第3步:不放心,启动调试----->在次确认!目标:OnSize与OnInitDialog()(设置2个断点)
      调试结果:第1次运行OnSize--->第2次运行OnInitDialog()----->第3次运行OnSize
///////////////////////////////VC++编译器调试.绝对官方权威数据!////////////////////////////
---endl;
---问题解决,结束!

附代码:
////////////错误调试代码:
Winocc.cpp//错误文件目录名
void CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint)
{
ASSERT(::IsWindow(m_hWnd));//第279行

if (m_pCtrlSite == NULL)
   ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
else
   m_pCtrlSite->MoveWindow(x, y, nWidth, nHeight, bRepaint);
}
////////////处理代码:
void CMy55Dlg::OnSize(UINT nType, int cx, int cy) 
{
CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
/**/ CRect rect1;GetClientRect(rect1);
// this->m_edit1.MoveWindow(100,15,rect1.Width(),20); 
// if(m_edit1.GetSafeHwnd()!=NULL)   //注:GetSafeHwnd()与m_hWnd效果一样
// m_edit1.GetSafeHwnd();
// if(m_edit1.GetSafeHwnd()) 
// if(m_edit1.GetSafeHwnd()==NULL) 
if(m_edit1.m_hWnd==NULL)//当句柄为假时
{
MessageBox("第1次运行OnSize");
}
//if(m_edit1.m_hWnd)
//

if(m_edit1.m_hWnd!=NULL){MessageBox("第2次运行OnSize"); //当句柄为真时
//if(m_edit1.m_hWnd==NULL)
//m_edit1.m_hWnd!=NULL;
// m_edit1.MoveWindow(78,15,rect1.Width()-78-254,23);
m_edit1.MoveWindow(78,15,rect1.Width()-378,23);
//以上调试了很多次,所以代码写的有点乱,但每一行都有用的
}}


//////////////////////////////以下摘自CSDN网友发表//////////////
这就是网上所说的
--->MFC的某些程序,跳过程序运行时的第一次OnSize就可以了。
其实只要OnSize像下面这样 

CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here 
Invalidate(); 

然后把原本要在OnSize完成的内容放到OnPaint内去,你上面的两个问题就都解决掉了