CWnd::Create和CWnd::CreateEx 区别

1. CWnd::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没有此函数)来创建窗口的。

2. 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的值。

 

参考来源:http://www.cnblogs.com/lidabo/archive/2012/07/04/2576832.html                  博主:SurpassLi

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值