VC6搭配新SDK后,使用CFileDialog会出现析构异常的
2010-04-23 10:57
537 查看
1)问题的来源:
ISAutomationRunner程序中,主体功能(调用vbs)完成以后。由于这个软件需要在批处理中被调用,处于方便性考虑需要加入控制台输出功能。因为程序主体来自codeguru上别人的程序,而且是GUI的,无法直接进行控制台输出。首先试了试改成支持MFC的console程序的,结果报错,粗略分析了下是由于源码中有几个地方用到了窗口句柄。不得以采用了为GUI程序添加控制台输出的方法:
-------------------------------------
AttachConsole(-1); // 将当前程序附着到父进程上 freopen("CONIN$", "r+t", stdin); // 重定向 STDIN
freopen("CONOUT$", "w+t", stdout); // 重定向STDOUT -------------------------------------
其中AttachConsole需要用新的SDK,因而需要设置_WIN32_WINNT=0x0500,这么一设置后AttachConsole使用正常了。
编译,运行,出现文件选择框,确定。晕,出现异常了。
IDE中调试一番,发现是程序中使用的CTextFile类(Johan Rosengren所写的一个很实用的类)中调用的CFileDialog析构时出现异常了,源码如下
-------------------------------------
BOOL CTextFile::GetFilename( BOOL save, CString& filename )
/* ============================================================
Function : CTextFile::GetFilename
Description : The function will display a standard file
dialog. If the instance is created with an
extension, the extension will be used to
filter files.
Return : BOOL - TRUE if a file was
selected
Parameters : BOOL save - TRUE if the file
should be saved.
CString& filename - Placeholder for the
selected filename ============================================================*/
{
CString filter;
CString extension = GetExtension();
if( extension.GetLength() )
filter = extension + _T( "-files (*." + extension + ")|*." ) + extension + _T( "|All Files (*.*)|*.*||" ); BOOL result = FALSE;
CFileDialog dlg( !save, extension, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter ); if( dlg.DoModal() == IDOK )
{
filename = dlg.GetPathName();
result = TRUE;
} return result; } --------------------------------------
2)问题的原因:
首先注释了新入的AttachConsole函数,问题依旧。自己郁闷的折腾了好一番,没法只好暂时搁置了。刚才又想起来,于是开始google,一搜“ CFileDialog 析构 异常 ”,乖乖-总算让我碰上一个MFC的bug了。
问题的产生原因在
http://codeguru.earthweb.net/forum/printthread.php?t=320297&pp=50
有所解释,我认为大体可以理解为:
VC6 自带的SDK和 MFC42中的定义,再后来的SDK中更新了,从而导致在析构的时候多卸载了内容
3)问题的解决:
a)换回老SDK,手动加载AttachConsole
b)修改CTextFile源码,由在栈上分配CFileDialog改为在堆上分配
根据我的情况,我选择了a方法,手动加载AttachConsole的源码如下
--------------------------------------
//为了在不用PLATFORM SDK的情况下加载AttachConsole
BOOL myAttachConsole(DWORD dwProcessId)
{
typedef BOOL (WINAPI* _AttachConsole)(DWORD dwProcessId);
HINSTANCE hinstance = LoadLibrary(_T("kernel32.dll"));
if (hinstance == NULL)
{
return FALSE;
}
_AttachConsole AttachConsole = NULL;
AttachConsole = (_AttachConsole)GetProcAddress(hinstance , "AttachConsole");
if (AttachConsole == NULL)
{
return FALSE;
}
AttachConsole(dwProcessId);
return TRUE;
}
-------------------------------------- 4)感慨: 写程序就是这样的充满意外。。。
ISAutomationRunner程序中,主体功能(调用vbs)完成以后。由于这个软件需要在批处理中被调用,处于方便性考虑需要加入控制台输出功能。因为程序主体来自codeguru上别人的程序,而且是GUI的,无法直接进行控制台输出。首先试了试改成支持MFC的console程序的,结果报错,粗略分析了下是由于源码中有几个地方用到了窗口句柄。不得以采用了为GUI程序添加控制台输出的方法:
-------------------------------------
AttachConsole(-1); // 将当前程序附着到父进程上 freopen("CONIN$", "r+t", stdin); // 重定向 STDIN
freopen("CONOUT$", "w+t", stdout); // 重定向STDOUT -------------------------------------
其中AttachConsole需要用新的SDK,因而需要设置_WIN32_WINNT=0x0500,这么一设置后AttachConsole使用正常了。
编译,运行,出现文件选择框,确定。晕,出现异常了。
IDE中调试一番,发现是程序中使用的CTextFile类(Johan Rosengren所写的一个很实用的类)中调用的CFileDialog析构时出现异常了,源码如下
-------------------------------------
BOOL CTextFile::GetFilename( BOOL save, CString& filename )
/* ============================================================
Function : CTextFile::GetFilename
Description : The function will display a standard file
dialog. If the instance is created with an
extension, the extension will be used to
filter files.
Return : BOOL - TRUE if a file was
selected
Parameters : BOOL save - TRUE if the file
should be saved.
CString& filename - Placeholder for the
selected filename ============================================================*/
{
CString filter;
CString extension = GetExtension();
if( extension.GetLength() )
filter = extension + _T( "-files (*." + extension + ")|*." ) + extension + _T( "|All Files (*.*)|*.*||" ); BOOL result = FALSE;
CFileDialog dlg( !save, extension, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter ); if( dlg.DoModal() == IDOK )
{
filename = dlg.GetPathName();
result = TRUE;
} return result; } --------------------------------------
2)问题的原因:
首先注释了新入的AttachConsole函数,问题依旧。自己郁闷的折腾了好一番,没法只好暂时搁置了。刚才又想起来,于是开始google,一搜“ CFileDialog 析构 异常 ”,乖乖-总算让我碰上一个MFC的bug了。
问题的产生原因在
http://codeguru.earthweb.net/forum/printthread.php?t=320297&pp=50
有所解释,我认为大体可以理解为:
VC6 自带的SDK和 MFC42中的定义,再后来的SDK中更新了,从而导致在析构的时候多卸载了内容
3)问题的解决:
a)换回老SDK,手动加载AttachConsole
b)修改CTextFile源码,由在栈上分配CFileDialog改为在堆上分配
根据我的情况,我选择了a方法,手动加载AttachConsole的源码如下
--------------------------------------
//为了在不用PLATFORM SDK的情况下加载AttachConsole
BOOL myAttachConsole(DWORD dwProcessId)
{
typedef BOOL (WINAPI* _AttachConsole)(DWORD dwProcessId);
HINSTANCE hinstance = LoadLibrary(_T("kernel32.dll"));
if (hinstance == NULL)
{
return FALSE;
}
_AttachConsole AttachConsole = NULL;
AttachConsole = (_AttachConsole)GetProcAddress(hinstance , "AttachConsole");
if (AttachConsole == NULL)
{
return FALSE;
}
AttachConsole(dwProcessId);
return TRUE;
}
-------------------------------------- 4)感慨: 写程序就是这样的充满意外。。。
相关文章推荐
- CFileDialog 在使用sdk 后出现异常 Access violation
- windows驱动开发技术详解 VC6与DDK搭配使用的设置
- Android 使用 SDK Manager 下载SDK速度慢,容易丢包和异常的解决办法
- Android SDK开发常用工具的使用及其异常处理
- windows驱动开发技术详解 VC6与DDK搭配使用的设置
- (原)Lazarus 在 Thread 中使用 SQLQuery 查询Oracle 会出现异常
- 适合VC6使用的SDK下载[转]
- 让VC6使用最新SDK
- Pylon5 SDK搭配OpenCV使用入门
- ABB机器人上位机C#使用PC SDK搭配机器人程序实现自动化
- 在使用spring quartze进行任务调度的时候,会出现jobDetail的异常问题
- gecko-sdk的nsIGenericFactory和宏NS_IMPL_ISUPPORTS*在VC6下面会表现异常。
- Android使用SDKManager下载SDK速度慢 容易丢包和异常的解决办法
- 使用maven构建android工程时报找不到对应sdk版本异常
- 在使用百度地图的SDK时,出现.LocationDemo has leaked ServiceConnection 异常并且无法定位的时候
- ceph rgw java sdk 使用域名访问服务时需要设置s3client的配置项 PathStyleAccess 为true, 负责将报域名异常
- VC6使用Crypto++库执行对称加密运算时异常报错的解决办法
- IIS7.0 部署异常 【不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况】解决方法
- VC6中使用SDK中的Iphlpapi.h与Iphlpapi.lib
- windows驱动开发技术详解 VC6与DDK搭配使用的设置 .