PreCreateWindow函数, PreSubClassWindow函数

MFC应用程序的初始化过程   一个MFC应用程序的生命周期(一)程序的进入点        MFC作为Win32 API的一种封装,它的程序进入点自然是WinMain。但是,这个WinMain也被封装起来,用户是看不到的,只是在编译器进行连接时会被自动连接。        下面我们就来寻找一下MFC程序被隐藏了的WinMain。搜索MFC的源文件,可以发现MFC的WinMain定义在 appmodul. 阅读详情

这两个函数是MFC的基类CWnd两个很重要的虚函数,万恶的MFC总是让人很烦恼。

class CWnd : public CCmdTarget
{
    
public:
    
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    virtual void PreSubclassWindow();
    BOOL SubclassWindow(HWND hWnd);
    
}
;
 

 父类中的虚拟函数是可以被子类重新实现的,以实现多态。一般基类会有一个默认的实现。

   msdn对这两个函数的定义。

  PreCreateWindow:
  Called by the framework before the creation of the Windows window 
  attached to this CWnd object.

  (译:在窗口被创建并attach到this指针所指的CWnd对象之前,被framework调用)

  PreSubclassWindow:
  This member function is called by the framework to allow other necessary 

  subclassing to occur before the window is subclassed.

  (译:在window被subclassed之前被framework调用,用来允许其它必要的subclassing发生)


虽然我已有译文,但还是让我对CWnd的attach和窗口的subclass作简单的解释吧!要理解attach,我们必须要知道一个C++的CWnd对象和窗口句柄(window)的区别:窗口句柄是windows的系统级的概念,代表着一个具体的窗口的句柄,可以通过操作这个句柄来修改窗口的属性已经行为。对应sdk编程

的HWND。

而CWnd就是MFC用类对window所进行C++封装。attach,就是在CWnd对象和窗口句柄建立一个关联。这样就可以用CWnd对象的接口来修改实际窗口的

属性和行为。

  好了,PreCreateWindow由framework在窗口创建前被调用,函数名也说明了这一点,Pre应该是previous的缩写,PreSubclassWindow由framework在subclass窗口前调用。 这段话说了等于没说,你可能还是不知道,什么时候该改写哪个函数。罗罗嗦嗦的作者,还是用代码说话吧!源码之前,了无秘密(候捷语)。我们就看看MFC中的这三个函数都是这样实现的吧!
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
                    LPCTSTR lpszWindowName, DWORD dwStyle,
                    
int x, int y, int nWidth, int nHeight,
                    HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
                    
{
    // allow modification of several common create parameters
    CREATESTRUCT cs;
    cs.dwExStyle = dwExStyle;
    cs.lpszClass = lpszClassName;
    cs.lpszName = lpszWindowName;
    cs.style = dwStyle;
    cs.x = x;
    cs.y = y;
    cs.cx = nWidth;
    cs.cy = nHeight;
    cs.hwndParent = hWndParent;
    cs.hMenu = nIDorHMenu;
    cs.hInstance = AfxGetInstanceHandle();
    cs.lpCreateParams = lpParam;
    
    if (!PreCreateWindow(cs))
        {
        PostNcDestroy();
        return FALSE;
    }

    
    AfxHookWindowCreate(this);
    HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
        cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
        cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
    
    
        return TRUE;
}


// for child windows
BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
    if (cs.lpszClass == NULL)
        {
        // make sure the default window class is registered
        VERIFY(AfxDeferRegisterClass(AFX_WND_REG));
        
        // no WNDCLASS provided - use child window default
        ASSERT(cs.style & WS_CHILD);
        cs.lpszClass = _afxWnd;
    }

    return TRUE;
}
  CWnd::CreateEx先设定cs(CREATESTRUCT),在调用真正的窗口创建函数::CreateWindowEx之前,调用了CWnd::PreCreateWindow函数,并把参数cs以引用的方式传递了进去。而CWnd的PreCreateWindow函数也只是给cs.lpszClass赋值而已。毕竟,窗口创建函数CWnd::CreateEx的诸多参数中,并没有哪个指定了所要创建窗口的窗口类,而这又是不可缺少的(请参考<<windows程序设计>>第三章)。所以当你需要修改窗口的大小、风格、窗口所属的窗口类等cs成员变量时,要改写PreCreateWindow函数。
// From VS Install PathVC98MFCSRCWINCORE.CPP
BOOL CWnd::SubclassWindow(HWND hWnd)
{
    if (!Attach(hWnd))
        return FALSE;
    
    // allow any other subclassing to occur
    PreSubclassWindow();
    
    // now hook into the AFX WndProc
    WNDPROC* lplpfn = GetSuperWndProcAddr();
    WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC,
        (DWORD)AfxGetAfxWndProc());
    ASSERT(oldWndProc != (WNDPROC)AfxGetAfxWndProc());
    
    if (*lplpfn == NULL)
        *lplpfn = oldWndProc;   // the first control of that type created
#ifdef _DEBUG
    else if (*lplpfn != oldWndProc)
        {
        
            ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc);
    }

#endif
    
    return TRUE;
}


void CWnd::PreSubclassWindow()
{
    // no default processing
}
  CWnd::SubclassWindow先调用函数Attach(hWnd)让CWnd对象和hWnd所指的窗口发生关联。接着在用::SetWindowLong修改窗口过程(subclass)前,调用了PreSubclassWindow。CWnd::PreSubclassWindow则是什么都没有做。
  在CWnd的实现中,除了CWnd::SubclassWindow会调用PreSubclassWindow外,还有一处。上面所列函数CreateEx的代码,其中调用了一个AfxHookWindowCreate函数,见下面代码:
// From VS Install PathVC98MFCSRCWINCORE.CPP
BOOL CWnd::CreateEx()
{
    // allow modification of several common create parameters
    
        
        if (!PreCreateWindow(cs))
            {
            PostNcDestroy();
            return FALSE;
        }

        
        AfxHookWindowCreate(this); 
        HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
            cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
            cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
        
        
            return TRUE;
}
  接着察看AfxHookWindowCreate的代码:

// From VS Install PathVC98MFCSRCWINCORE.CPP
void AFXAPI AfxHookWindowCreate(CWnd* pWnd)
{
    
        
        if (pThreadState->m_hHookOldCbtFilter == NULL)
            {
            pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT,
                _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
            if (pThreadState->m_hHookOldCbtFilter == NULL)
                AfxThrowMemoryException();
        }

        
}

  其主要作用的::SetWindowsHookEx函数用于设置一个挂钩函数(Hook函数)_AfxCbtFilterHook,每当Windows产生一个窗口时(还有许多其它类似,请参考<<深入浅出MFC>>第9章,563页),就会调用你设定的Hook函数。
  这样设定完成后,回到CWnd::CreateEx函数中,执行::CreateWindowEx进行窗口创建,窗口一产生,就会调用上面设定的Hook函数_AfxCbtFilterHook。而正是在_AfxCbtFilterHook中对函数PreSubclassWindow进行了第二次调用。见如下代码:
// From VS Install PathVC98MFCSRCWINCORE.CPP
/**//////////////////////////////////////////////////////////////////////////////
// Window creation hooks

LRESULT CALLBACK
_AfxCbtFilterHook(
int code, WPARAM wParam, LPARAM lParam)
{
           
        
        // connect the HWND to pWndInit
        pWndInit->Attach(hWnd);
    // allow other subclassing to occur first
    pWndInit->PreSubclassWindow();
    
        {
        // subclass the window with standard AfxWndProc
        oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)afxWndProc);
        ASSERT(oldWndProc != NULL);
        *pOldWndProc = oldWndProc;
    }

    
}

  也在调用函数SetWindowLong进行窗口subclass前调用了PreSubclassWindow.



MFC主框架和视类PreCreateWindow()函数学习 MFC中PreCreateWindow函数是在窗口启动之前做一些初始化; 阅读详情

相关推荐

二维otsu算法python_OpenCV-Python系列之OTSU算法

上一个教程中,我们谈到了关于图像二值化的两种方法,一种是固定阈值法,另一种是自适应阈值法,总的来说,自适应阈值法在某些方面要由于固定阈值法,但还没完,这次我们将隆重介绍我们的重量级选手,也就是OTSU算法(又称为大津算法和最大类间方差法)。最大类间方差法是1979年由日本学者大津提出的,是一种自适应阈值确定的方法,又叫大津法,简称OTSU,是一种基于全局的二值化算法,它是根据图像的灰度特性,将图像...

weixin_28834169的博客 1426

precreatewindow里面做了什么?

在现有应用程序中更改样式 如果是正在现有应用程序中更改窗口属性,则遵循本文其余部分的说明。 若要更改框架应用程序(用应用程序向导创建的)所使用的默认窗口属性,请重写窗口的 PreCreateWindow 虚拟成员函数。PreCreateWindow 允许应用程序访问通常由 CDocTemplate 类内部管理的创建进程。框架在即将创建窗口前调用 PreCreateWindow。通过修改传递给 Pr

zhoubaiwen的专栏 1191

PPO(Proximal Policy Optimization)算法原理及实现,详解近端策略优化

接着上面的讲,PG方法一个很大的缺点就是参数更新慢,因为我们每更新一次参数都需要进行重新的采样,这其实是中on-policy的策略,即我们想要训练的agent和与环境进行交互的agent是同一个agent;与之对应的就是off-policy的策略,即想要训练的agent和与环境进行交互的agent不是同一个agent,简单来说,就是拿别人的经验来训练自己。举个下棋的例子,如果你是通过自己下棋来不断提升自己的棋艺,那么就是on-policy的,如果是通过看别人下棋来提升自己,那么就是off-policy的。

weixin_41106546的博客 9万+

PreCreateWindow

1.MFC 单文档实现全屏BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.style=WS_POPUPWINDOW; //设置为屏幕大小 cs.cx=::GetSystemMetrics(SM_CXSCREEN); cs.cy

qq_34929774的博客 522

飞控芯片的隐形战场:传感器冗余与实时OS的可靠性革命

本文深入探讨飞控芯片在工业级无人机中的可靠性设计,聚焦传感器冗余架构与实时操作系统(RTOS)的容错机制。通过多IMU备份、自适应加权融合算法及NuttX、ChibiOS等RTOS的故障隔离技术,确保系统在极端环境下毫秒级自愈。文章还涵盖开源生态如PX4的跨平台移植及RISC-V架构的应用,为高可靠性飞控系统提供关键技术参考。

z5a6b的博客 877

【UG/NX二次开发】记录在二次开发中遇到的坑

【UG/NX二次开发】记录在二次开发中遇到的坑

Trust_MJ的博客 2708

PreCreateWindow、PreSubclassWindow、SubclassWin MFC

通常情况下窗口是由用户创建的 CWnd::Create(…) ,在此流程中,MFC提供一个机会"PreCreateWindow()供用户在创建前修改窗口的样式。 BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, int nWid...

sunmoon_one的博客 542

open3d将某一时间序列下的彩色图和深度图批量转换成点云(python)

必备条件需要3D相机生成的彩色图及深度图,注意要将深度图与彩色图对齐(一般3D相机自带对齐算子),以及3D相机的彩色图内参(相机自带内参获取功能)。有了此彩色图、对齐后的深度图以及相机内参就能使用open3d生成彩色点云了.

吾名招财的博客 315

CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别

MFC(VC6.0)的CWnd及其子类中,有如下三个函数:    // From VS Install PathVC98MFCIncludeAFXWIN.H    class CWnd : public CCmdTarget    ...{        ...    public:        ...        virtual BOOL PreCreateWindow(CREATE

swimmer2000的专栏 6496

HSM 网络安全 信息安全

HSM HSM信息安全功能 汽车电子网络安全中HSM 的应用场景 选择适合汽车电子网络安全的 HSM 符合汽车安全标准和法规要求的HSM HSM 在汽车电子网络安全中的可靠性和安全性 评估汽车电子网络的安全性 汽车 HSM(Hardware Security Module)模块开发 汽车 HSM(Hardware Security Module)模块测试

天赐好车的博客 1240

pandas教程:2012 Federal Election Commission Database 2012联邦选举委员会数据库

里面包含了支持者的名字,职业和雇主,地址,赞助金额。我们可以已经能想到如何切割、整理数据,来提取赞助者的统计数据,或提取宣传活动的模式,这里我们展示一些不同的分析方法。可以看到有些职业是同一种工作类型,指代的是同一个东西。这两个连续操作是分别独立执行的,一个结束后,另一个才开始。上,这里我是把数据集压缩成了ZIP格式,解压后能正常导入)。我觉得也有必要好好了解一下,这个网站做了很好的讲解,),所以我们最好添加这样的信息。这样的情况,即把两个索引操作连在一起。,发现映射关系被正常执行了,所以这里的。

Cachel Wood的博客 350

MFC:OnCreate PreCreateWindow PreSubclassWindow

OnCreate PreCreateWindow PreSubclassWindow PreCreateWindow和PreSubclassWindow是虚函数,而OnCreate是一个消息响应函数。 对比对话框的2种创建方式下,这3个函数的是否调用的状态: OnCreate PreCreateWin...

diaomo9737的博客 392

信号处理仿真:自适应信号处理_(8).自适应信道均衡

在无线通信系统中,信道的多径效应和时变特性会导致信号的失真,从而影响通信质量。自适应信道均衡技术通过实时调整均衡器的参数,以补偿信道失真,提高信号的质量和可靠性。本节将详细介绍自适应信道均衡的原理、算法和实现方法,并通过具体的仿真例子来说明其应用。

2401_87715305的博客 1039

OnCreate PreCreateWindow PreSubclassWindow什么时候调用

<br />OnCreatePreCreateWindowPreSubclassWindow<br />作者:chenyongsuda 和c/c++相关 2010/08/09<br /><br />简介:这是OnCreatePreCreateWindowPreSubclassWindow的详细页面,介绍了和c/c++,C++ OnCreate PreCreateWindow PreSubclassWindow有关的知识、技巧、经验,和一些c/c++源码等。<br /><br />oncreate precr

q1q2q3q4ln的专栏-随我一起研究程序 750

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OnCreate、PreCreateWindow、PreSubclassWindow的区别与联系

转自:http://biancheng.dnbcw.info/c/173658.html   PreCreateWindow和PreSubclassWindow是虚函数,而OnCreate是一个消息响应函数。 对比对话框的2种创建方式下,这3个函数的是否调用的状态:   OnCreate PreCreateWindow PreSubclassWindow CDialo...

只为龙舞的博客 485

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

PreCreateWindow、PreSubclassWindow、SubclassWindow 解析

CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别 1、函数原型 virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); virtual void PreSubclassWindow( ); BOOL SubclassWindow( HWND hWnd

Incremental Learning 1017

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

OnCreate PreCreateWindow PreSubclassWindow

OnCreate PreCreateWindow PreSubclassWindow PreCreateWindow和PreSubclassWindow是虚函数,而OnCreate是一个消息响应函数。 对比对话框的2种创建方式下,这3个函数的是否调用的状态:                                OnCreate PreCreateWindow Pre...

280

OnCreate PreCreateWindow PreSubclassWindow

<br /><br />PreCreateWindow和PreSubclassWindow是虚函数,而OnCreate是一个消息响应函数。<br />对比对话框的2种创建方式下,这3个函数的是否调用的状态:                              OnCreatePreCreateWindowPreSubclassWindowCDialog::Create是否是CDialog::DoModal是否是<br />对比控件的2种创建方式下,这3个函数的是否调用的状态:             

Polaris 666

PreSubclassWindow

PreSubclassWindow PreSubclassWindow是一个很好的定制控件的位置。如果我们通过重载CWnd::PreCreateWindow定制控件,而用户在对话框中使用控件。由于对话框中的控件窗口是通过CreateDlgIndirect创建,不经过CWnd::CreateEx函数,PreCreateWindow函数不会被调用。 其实,用户要在对话框中使用定制控件,必须用DDX

aafengyuan的专栏 669
上一篇: 心情小记
下一篇: DLL中GDIPlus初始化和退出时注意的问题
必成桂
博客等级 码龄18年 411粉丝 143原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值