PreSubclassWindow里面再次调用Create函数创建子控件

问题描述:here

我写了一个类继承CListCtrl,当然需要重写滚动条,滚动条是用CStatic的,初始化放在PresubClassWindow中(如调用cstatic的create创建滚动条),测试时使用MFC Dialog,在窗口上拉了一个CListCtrl,然后用向导生成了,然后手动修改,使其改成我自定义的CMyListCtrl,运行没有哦问题,但是我换一种方式使用ListCtrl的时候,问题出现了,我不是用MFC的向导,而是用m_ctrlMyList.Create(。。)函数,结果却导致程序崩了,这个现象很容易复现,但是将本来放在PresubClassWindow中初始化部分放到OnCreate中,程序就正常了,然而使用向导生成的(就是在MFC的DoDataExchange中让MFC自己处理),将不会调用OnCreate

问题分析:

当CListCtrl调用CreateEx函数时

1.CreateEx会调用CWnd的CreateEx,在该函数内部会依次调用PreCreateWindow,AfxHookWindowCreate(this),CreateWindowEx(SDK真正创建窗口的函数)

2.AfxHookWindowCreate(CWnd* pWnd)里面如果当前线程没有钩子函数会调用::SetWindowsHookEx(WH_CBT,_AfxCbtFilterHook, NULL, ::GetCurrentThreadId());设置_AfxCbtFilterHook钩子函数,WH_CBT类型的钩子会在激活、创建、销毁、最小化、最大化、移动等之前调用钩子函数(即当执行到第一步CreateWindowEx函数时会调用_AfxCbtFilterHook)。然后ASSERT(pThreadState->m_pWndInit == NULL);   // hook not already in progress,接着再pThreadState->m_pWndInit = pWnd;

3._AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)在钩子函数中会依次调用pWndInit->Attach(hWnd); (hWnd是该函数的第二个参数wParam传进来的值即HWND hWnd = (HWND)wParam;)再调用pWndInit->PreSubclassWindow();、SetWindowLongPtr(设置窗口过程)、pThreadState->m_pWndInit = NULL;,在调用pWndInit->PreSubclassWindow()时(还没有执行后面的SetWindowLongPtr和pThreadState->m_pWndInit = NULL;),正如问题中所述,在PresubClassWindow中调用Create创建CStatic,那么会回到第一步CreateEx一直执行,当执行到ASSERT(pThreadState->m_pWndInit == NULL);   // hook not already in progress 时pThreadState->m_pWndInit未清除是有值的在debug模式下必然会打印断言错误;在release模式下可以运行,但是CStatic未被成功创建。(注,我的电脑Windows7_64 vs2012下如此)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值