CWnd::GetStyle() 出错,COleControlSite 为非零无效值

daseny 2005-10-17 02:27:22
问题表现:

调用对话框时出现访问非法地址错误。
出问题的对话框有:文件对话框(包括 CFileDialog 和 OPENFILENAME )和消息对话框(包括 AfxMessageBox 和 MessageBoxA ),其他对话框只是没用到,可能也有问题。


我已经进行过的分析:

通过调用栈发现所有问题的调用都是相同的,如下:

CWnd::GetStyle()
_AfxPostInitDialog()
_AfxActivationWndProc()
user32.dll!……()


//=============================================================================
// 出问题时,正在处理 WM_INITDIALOG 消息,_AfxActivationWndProc 中进行如下调用:
case WM_INITDIALOG:
{
DWORD dwStyle;
CRect rectOld;
CWnd* pWnd = CWnd::FromHandle(hWnd);
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);//====================== 1
bCallDefault = FALSE;
lResult = CallWindowProc(oldWndProc, hWnd, nMsg, wParam, lParam);//= 2
_AfxPostInitDialog(pWnd, rectOld, dwStyle);//======================= 3
}
break;

// _AfxPostInitDialog 中又进行了这样的调用:
AFX_STATIC void AFXAPI _AfxPostInitDialog(
CWnd* pWnd, const RECT& rectOld, DWORD dwStyleOld)
{
// must be hidden to start with
if (dwStyleOld & WS_VISIBLE)
return;

// must not be visible after WM_INITDIALOG
if (pWnd->GetStyle() & (WS_VISIBLE|WS_CHILD))
return;
……
}

// GetStyle 定义如下:
DWORD CWnd::GetStyle() const
{
ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

if (m_pCtrlSite == NULL)//=============================================== 4
return (DWORD)GetWindowLong(m_hWnd, GWL_STYLE);
else
return m_pCtrlSite->GetStyle();//==================================== 5
}

//m_pCtrlSite 的声明如下(在 afxwin.h 中):
#ifndef _AFX_NO_OCC_SUPPORT
COleControlSite* m_pCtrlSite; // for wrapping an OLE control
#endif

//=============================================================================

出问题是在上述代码代附加注释5的那一行,m_pCtrlSite 为一个非零无效值,导致访问非法。

我已经查过,_AfxActivationWndProc 被调用,是 MFC 为了控制非 MFC 模态对话框的初始化而进行的,以保证以后切换活动窗体时的的正确响应,比如存在模态对话框时不能首先激活其父窗体。

其中,_AfxPreInitDialog 方法中也有对 GetStyle 的调用,跟踪中发现,在 Pre 中 m_pCtrlSite 的值还是 NULL ,调用默认的初始化方法之后在 Post 中就变成了 0xcdcdcdcd之类的值(也就是说还出现过其他类似“规则的”值)。


可能有用的相关环境:

我在程序里用了 CodeProject 上的一个 CSkinWin 的换肤组件,其中对软件的主窗体进行了子类化,以进行非客户区的自绘。但是 Hook 的操作是针对一个窗体进行的。
如果隔离皮肤代码,目前还没有出现过这种错误。

我用的是VS.net2003,XP sp2,简体中文;已经在简体和繁体2000上进行过,错误是一样的。但是2000发生的似乎更多。

错误在 Debug、Release 下都有,调试(Run)Release 版时本发生的情况更多。

文件对话框是自己调用的,消息对话框有自己调用的,也有断言失败MFC自己调用的。


我搜索过 MFC 中所有改变 m_pCtrlSite 的地方,但是没有跟踪到哪里改变了值。
断断续续已经忙了好些天了,仍然没有结果,所以只好求助大家,希望有能力的大侠帮忙,先行谢过了!
如果有哪些我没说明白的地方,我会再作说明。
...全文
455 点赞 收藏 3
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
daseny 2005-10-17
不是,MFC。
上面的细节只是跟踪到MFC源代码里罢了。

补充一下,文件对话框只是带位置栏(2000风格)的会出错,如果通过设定空Hook用旧风格(win3.1)就不会出错。
回复
菜牛 2005-10-17
你是在SDK下编程的?
回复
daseny 2005-10-17
新发现:
在 GetStyle 中,出错时 m_hWnd 和 m_pCtrlSite 的值是一样的。

另,消息对话框出错值是0xcdcdcdcd,而文件对话框是0xfeeefeee。
回复
相关推荐
CWnd::Create和CWnd::CreateEx 区别
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam /* = NULL */) { return Cre
CWnd::FromHandle与CWnd::FromHandlePermanent有什么区别
你可以参考 MFC 代码中 FromHandle 和 FromHandlePermanent 的实现,这两个函数都是在公共的 CMapHandle 中查找句柄对应的 CWnd 对象(通过一个CBT钩子,CWnd 对象将创建时得到的句柄和自己的指针纪录到...
error C2352: “CWnd::UpdateData”: 静态成员函数的非法调用
CString getinfo_un() { CString un,str; CWnd::UpdateData(TRUE);...error C2352: “CWnd::UpdateData”: 静态成员函数的非法调用 参见“CWnd::UpdateData”的声明 怎么办,找遍google,baidu,尚无结果
MFC定时器使用(CWnd::SetTimer)
地址:https://msdn.microsoft.com/zh-cn/library/49313fdf.aspx 语法 UINT_PTR SetTimer( UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK* lpfnTimer ... UINT,
CWnd::WindowProc的理解
先帖一段源代码 [cpp] view ...LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)  {   // OnWndMsg does most of the work, except for DefWindowP
CWnd::SetWindowPos
更改子项、弹出窗口以及顶级窗口大小、位置和Z顺序。... const CWnd* pWndInsertAfter,  int x,  int y,  int cx,  int cy,  UINT nFlags  ); 参数 pWndIns
浅析CWnd::GetClientRect和CWnd::GetWindowRect函数
今天在将一个位图加载到对话框中的一个picture控件时,调用StretchBlt函数绘制时,发现位图加载错位了(位图左上角粘在对话框左上角),查找原因,原来在函数StretchBlt的第1和第2个参数传值错误,这两个参数我是由调用...
解决 Warning: calling DestroyWindow in CWnd::~CWnd OnDestroy or PostNcDestroy in derived class will ...
转自:... 出现上面Warning,原因是,调用窗口类析构的时候,窗口对象还没有销毁. 具体表现在,当在一个窗口中生成另外一个窗口CTestDlg 时: CTestDlg *pTd = new CTestDlg(); pTd->Create(IDD_D...
CWnd::Attach()详解
CWnd::Attach Attaches a Windows window to a CWnd object. BOOL Attach(  HWND hWndNew ); Parameters hWndNew Specifies a handle to a Windows window. 一个概念:C++对象和Windows对象的区别...
error C2664: “int CWnd::GetWindowTextW(LPTSTR,int) const”: 不能将参数 1 从“char [15]”转换...
为了解决用户可能碰到关于"error C2664: “int CWnd::GetWindowTextW(LPTSTR,int) const”: 不能将参数 1 从“char [10]”转"相关的问题,经过收集整理用户提供相关的解决办法,请注意,解决办法仅供参考。...
error C2664: “CWnd::SetDlgItemTextW”: 不能将参数 2 从“const char [2]”转换“LPCTSTR”
解决方法很简单。 方法一: MessageBox(_T"你已经提交成功。"); ...选择“项目”-》“XXX项目属性”-》“配置属性”-》“常规”选项中,把“字符集”改“使用多字节字符集”,然后确定。
error C2660: 'CWnd::HtmlHelpW ' : function does not take 4 arguments
该问题是在VC6.0转VS2005产生的,问题的根源是我们没有加域控制,没有弄清楚要調用CWnd::HtmlHelpW還是要調用api,在前面加上::就可以。比如: ::HtmlHelp(m_hWnd, AfxGetApp()->m_pszHelpFilePath, HH_HELP_...
关于MFC CWND::Invalidate()使用的小结
 若默认值(TRUE),则不会调用onPaint函数;反之则调用。 3.特别注意  在一个函数内部调用该方法后,并不会立即更新窗口,而是等函数执行完后才更新。  也就意味着:如果你在Invalidate后马上画一张图,...
error C2664: 'int CWnd::MessageBoxW(LPCTSTR,LPCTSTR,UINT)' : cannot convert argument 1 fr
Error 1 error C2664: 'int CWnd::MessageBoxW(LPCTSTR,LPCTSTR,UINT)' : cannot convert argument 1 from 'const char [11]' to 'LPCTSTR'  解决办法: ①用函数MessageBoxA ②在内容前加上TEXT(对变量无效)...
error C2664: “CWnd::MessageBoxW”: 不能将参数 1 从“const char [17]”转换“LPCTSTR
error C2664: “CWnd::MessageBoxW”:  不能将参数 1 从“const char [17]”转换“LPCTSTR”   在vs2010的菜单的学习中,本人遇到如下问题: 给某个菜单项添加一
CWnd::MessageBoxW”: 不能将参数 1 从“const char [16]”转换“LPCTSTR
CWnd::MessageBoxW”: 不能将参数 1 从“const char [16]”转换“LPCTSTR  2011-06-30 10:27:50| 分类: VC学习 | 标签: |字号大中小 订阅 在外面用vs2005编写mfc程序的时候经常要MessageBox(...
CWnd::Create 出现afxwin1.inl line21出现问题
首先说下我是在regular mfc dll中调用这个cwnd::create方法的。而且这个代码不是我写的, 是别人写的代码。 ``` m_pWndMessageTarget->CWnd::Create(NULL, _T("cessocket_message_sink"), WS_CHILD, CRect(0, 0, ...
CWnd::NotifyWinEvent 函数不接受 4 个参数的解决方案
error C2039: “NotifyWinEvent”: 不是“`global namespace'”的成员error C2039: ...error C2660: “CWnd::NotifyWinEvent”: 函数不接受 4 个参数 解析: Debug模式编译正常 但是release模式编译
CWnd::OnLButtonUp详解
CWnd::OnLButtonUp   当用户松开鼠标左键时,框架调用该成员函数。语法 afx_msg void OnLButtonUp( UINT nFlags,CPoint point );参数nFlags 指示各种虚拟键是否按下。此参数可以是下列的任意组合: 如果按下...
error C2352: 'CWnd::MessageBoxW' : illegal call of non-static member function
该错误主要是因为将CWnd::MessageBox()用在CWnd派生类里或在静态成员函数里,在CWnd派生类里应使用AfxMessageBox()。MessageBox()是CWnd的static函数,在static类型的成员函数只能调用静态函数。
MFC-核心类库-CWnd的成员函数介绍(三)
CRect类数据成员有left,top,right,和bottom。left左上角X坐标,top左上角Y坐标,right右下角X坐标,bottom右下角Y坐标。...//修改CRect的x、y,每次增加5,5CWnd类中GetWindowRect(rect);MoveWind...
CWnd::CreateEX中HOOK函数作用
用最基本的一句话概述,钩子函数起了很大作用。故事是这样的,有些漫长,也需要些耐心。...标准消息:除WM_COMMAND之外的WM_xx消息都是标准消息,派生于CWnd的类都有能力处理该消息  3. 控件通知消息
CWnd::Create(EX)、CWnd::OnCreate和CreateWindow(EX)
Create(EX)是CWnd的成员函数,CWnd::OnCreate是wm_create的消息响应函数,CreateWindow(EX)是API,他们三者的调用关系是CWnd::Create(EX)调用CreateWindow(EX)来完成窗口的创建,CreateWindow(EX)会发送wm_create...
关于在MFC中调用AfxMessageBox、CWnd::MessageBox与::MessageBox的区别
假设我们在一程序Msg.exe内调用这三个函数,   那么,当我们调用::MessageBox时,会先在...   然而, 对于AfxMessageBox和CWnd::MessageBox这两个函数,或许你曾经听高人说过,实际上这两
自定义继承自CWnd类,在create时出错
当我在使用CWnd::Create时,发现有以下中断错误进入windows内部调试后,发现,是在以下位置出错的意思是:没有属于该类的类名。修改方式是:在.h声明文件中,定义一个类名static CString g_strWndClass;在.cpp中...
【MFC】error C2664: 'CWnd::MessageBoxW' 的解决方案
【摘自:... MessageBox("ddd"); 编译通不过显示错误 f:\draw\draw\drawview.cpp(108) : error C2664: 'CWnd::MessageBoxW' : cannot convert parameter
MFC —— CWnd::SetCapture
调用此函数后,接下来所有的鼠标事件都被发送到当前的CWnd对象,发送给CWnd对象的事件中不包括鼠标的坐标信息。 函数原型:  CWnd* SetCapture( ); 返回值: 返回一个指针,该指针指向之前接受所有鼠标输入的...
设计一个学生类Student,包括数据成员:姓名、学号、二门课程(面向对象程序设计、高等数学)的成绩。
(1)、设计一个学生类Student,包括数据成员:姓名、学号、二门课程(面向对象程序设计、高等数学)的成绩。 (2)、创建一个管理学生的类Management,包括实现学生的数据的增加、删除、修改、按课程成绩排序、保存...
比较两张图片差异
比较两张图片差异,代码收集于网上,码收集于网上
c#图片文字-字母-数字自动识别-深入代码-非常好
c#图片文字-字母-数字自动识别-深入代码-非常好
发帖
界面
创建于2007-09-28

1.5w+

社区成员

VC/MFC 界面
申请成为版主
帖子事件
创建了帖子
2005-10-17 02:27
社区公告
暂无公告