现在的位置: 首页 > 综合 > 正文

PreCreateWindow改窗口类型无效原因

2014年11月27日 ⁄ 综合 ⁄ 共 1306字 ⁄ 字号 评论关闭

由于

BOOL CView::PreCreateWindow(CREATESTRUCT & cs) 

... 
cs.dwExStyle |= WS_EX_CLIENTEDGE; 
cs.style &= ~WS_BORDER; 
... 

如果这样处理 
CYourView::PreCreateWindow(CREATESTRUCT & cs) 

cs.dwExStyle &= ~WS_EX_CLIENTEDGE; 
return CView::PreCreateWindow(cs); 

尽管先取消了WS_EX_CLIENTEDGE,但接下来的 
CView::PreCreateWindow(cs);又把它加回去了,所以无效。 

可以这样: 
CYourView::PreCreateWindow(CREATESTRUCT & cs) 

BOOL bResult = CView::PreCreateWindow(cs); 
cs.dwExStyle &= ~WS_EX_CLIENTEDGE; 
return bResult; 

用spy查看CYourView,可以发现确实没有WS_EX_CLIENTEDGE风格了, 
但外观上好象没有变化,还是凹陷的。 
其实CYourView是平的,但CChildFrame发现这种情况后又给它自己加上了 
WS_EX_CLIENTEDGE风格,如下面的MFC源码所示: 

CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID) 

... 
if (afxData.bWin4 && (pView->GetExStyle() & WS_EX_CLIENTEDGE)) 

// remove the 3d style from the frame, since the view is 
// providing it. 
// make sure to recalc the non-client area 
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED); //就是这里 

return pView; 

所以,为了阻止这种幕后黑手,必须同时改写CChildFrame::PreCreateWindow 
BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs) 

BOOL bResult = CMDIChildWnd::PreCreateWindow(cs); 
cs.dwExStyle &= ~WS_EX_CLIENTEDGE; 
return bResult; 

道理大概是这样,至于在CYourView::OnInitialUpdate()里用modifyStyleEx去掉 
WS_EX_CLIENTEDGE,自然可以,因为此时MFC已经不再阻挠风格的改变了

当然也可以在PreCreateWindow中用注册窗口类函数把窗口类字符串赋给cs.lpszClass(通过调用 AfxRegisterWndClass 全局函数然后将已注册的类传递到 CWnd 的 Create 成员函数,可以注册其他注册类)。(貌似没有必要。。。)

抱歉!评论已关闭.