zoukankan      html  css  js  c++  java
  • Create和CreateEx 区别

    先来看CreateEx函数:

    BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
      LPCTSTR lpszWindowName, DWORD dwStyle,
      const RECT& rect, CWnd* pParentWnd, UINT nID,
      LPVOID lpParam /* = NULL */)
    {
     return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
      rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
      pParentWnd->GetSafeHwnd(), (HMENU)nID, lpParam);
    }

    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);

    #ifdef _DEBUG
     if (hWnd == NULL)
     {
      TRACE1("Warning: Window creation failed: GetLastError returns 0x%8.8X/n",
       GetLastError());
     }
    #endif

     if (!AfxUnhookWindowCreate())
      PostNcDestroy();        // cleanup if CreateWindowEx fails too soon

     if (hWnd == NULL)
      return FALSE;
     ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
     return TRUE;
    }

    可以看到,这两个重载函数的实现原理是让第一个函数调用了第二个函数。在第二个CreateEx中实际是通过调用Win32 SDK平台的ateWindowEx(CWnd没有此函数)来创建窗口的。

    再来看Create函数:

    BOOL CWnd::Create(LPCTSTR lpszClassName,
     LPCTSTR lpszWindowName, DWORD dwStyle,
     const RECT& rect,
     CWnd* pParentWnd, UINT nID,
     CCreateContext* pContext)
    {
     // can't use for desktop or pop-up windows (use CreateEx instead)
     ASSERT(pParentWnd != NULL);
     ASSERT((dwStyle & WS_POPUP) == 0);

     return CreateEx(0, lpszClassName, lpszWindowName,
      dwStyle | WS_CHILD,
      rect.left, rect.top,
      rect.right - rect.left, rect.bottom - rect.top,
      pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)pContext);
    }

    注意这两行:

     ASSERT(pParentWnd != NULL);
     ASSERT((dwStyle & WS_POPUP) == 0);  // 该行说明Create函数不允许窗口风格为WS_POPUP

    可以看到,在Create函数之中又调用了CreateEx的第二个重载版本。

    总结:

    归根到底,MFC是通过CreateEx函数调用CreateWindowEx函数来创建窗口的。

    注意一点:这个新创建的窗口是如何与我们的窗口对象进行绑定的呢?看第二个CreateEx的return上面的那一行:

    ASSERT(hWnd == m_hWnd); // should have been set in send msg hook

    在这里这只是进行判断。看它的注释:// should have been set in send msg hook

    奥,它说在

    if (!AfxUnhookWindowCreate())
      PostNcDestroy();        // cleanup if CreateWindowEx fails too soon

    处设置了m_hWnd的值。

  • 相关阅读:
    WebSocket属性的简介及使用
    JAVA_基础逻辑运算符与位运算符使用
    JAVA_基础数据类型介绍与基本数据类型之间的运算规则
    ES6特性整理
    Vue-cli中的安装方法
    Kubernetes核心原理(一)之API Server
    Kubernetes核心原理(四)之Kubelet
    kubernetes-整体概述和架构详解
    Kubernetes dashboard认证访问
    kubeadm HA master(v1.14.0)离线包 + 自动化脚本 + 常用插件 For Centos/Fedora
  • 原文地址:https://www.cnblogs.com/lidabo/p/2576832.html
Copyright © 2011-2022 走看看