本文迁移自本人网易博客,写于2012年1月9日,二维多段线绘制 - lysygyy的日志 - 网易博客 (163.com)
做符号化过程中,一开始发现控件下拉后导致死机,原来是资源切换的问题,使用CAcModuleResourceOverride resOverride;即可;
但后来发现使用sqlite保存数据到数据库后,导致如题错误;我一直以为是使用了事务的原因。
但始终找不出错在哪里,事务的使用的确好像没什么错误的。
我在下拉控件的selChange时间中添加了一个消息弹出框,发现只要选择一次之后,所有下拉控件就都不能响应change事件了。后来感觉又不是这里的问题,就将消息弹出框给去掉了,发现可以选择多次了。
难道是消息弹出框的原因?
而且事务完成时也弹出了消息框。
于是将消息弹出框都去掉,发现下拉控件可以正常使用了。
一直使用的是AfxMessageBox,将其换成MessageBox后便正确了。
原来是这么细节的问题,以前从没遇到过。不知AfxMessageBox和MessageBox的区别。
实际上这个问题应该归结为:
child对话框弹出模态对话框后如何获取焦点
在网上找到了暂时的解决方法:
发现当我在父类窗口中使用时钟并且打开一个模态文件对话框(CFileDialog 类)时当文件对话框返回时父类窗口失去了焦点,但是在软件中我自定义了一个对话框类使用的也是模态对话框就没有出现这种问题,稍微想了下发现自己在打开一个模态文件对话框时没有给这个对话框传递一个父类窗口指针,当然对于父类对话框的选择可以使用 theApp.GetMainWnd()->GetWindow (GW_HWNDPREV)进行选择,其中GW_HWNDPREV为参数,代表其在Z坐标轴中的位置即是顶层、底层还是最底层、最顶层,可以在MSDN查找到。在父类窗口指针设置好之后发现在模态对话框返回时父类窗口依旧失去焦点,这是因为当前焦点依旧是那个模态对话框虽然它已经看不到了,但它只是隐藏了而已。这时在函数返回之前调用SetFocus()就行了,而如果不设置父类指针SetFocus()是不起作用 的,因为他在设置已经隐藏的那个模态对话框为当前焦点。具体代码如下:
void CLEDImage::OnBtnLoadPicFile()
{
CString str = _T("jpgjpegJPGJPEGBMPbmp");
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,theApp.GetMainWnd()->GetWindow (GW_HWNDPREV),NULL);
或者:// CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,this,NULL);
IDOK == dlg.DoModal())
{
if (-1 !=str.Find(dlg.GetFileExt()))
{
return;
}
PicProccess(dlg.GetPathName());
ShowPic();
}
SetFocus();
}
我自己写的例子是:
CAcModuleResourceOverride resourceOverride;
CTuKuListDlg dlg(this);
dlg.m_sSelDwgFile = m_ctrlSet.GetItemText(nItem,5);
dlg.m_sBlockName = m_ctrlSet.GetItemText(nItem,nSubItem);
if(dlg.DoModal()==IDOK)
{
m_ctrlSet.SetItemText(nItem,5,dlg.m_sSelDwgFile);
m_ctrlSet.SetItemText(nItem,nSubItem,dlg.m_sBlockName);
SetFocus();
}
这样运行就不会出错了。
但是仍然有问题:在使用autocad自己的对话框时无法使用这个办法了,例如:
if(acedLineWeightDialog(AcDb::LineWeight(rValue),FALSE,retLineWeight)==FALSE)
{
return;
}
最终解决方法:
同事说让我把程序发给他,在他机器上测试一下,发现一切都正常。
同事说应该是我把程序放在监理程序目录下后,里面的dll冲突导致的,现在的符号化程序仅仅需要几个dll而已。
虽然问题解决了,但是为什么程序会出现这样的情况,还是不明白。