ON_NOTIFY : Comes from a child control to the parent. This macro goes in the parent's message map.
ON_NOTIFY_REFLECT: Comes from a child control, but is "reflected" back to the child (by the parent)so the child can handle its own notification. This macro goes in the child's message map.
ON_NOTIFY_REFLECT_EX: Same as previous, except that the handler function returns a BOOL, indicating whether or not the message should be routed on to parent classes for possible handlers. Note that the reflected message is handled before the notification message.
我的理解就是一般情况下,ON_NOTIFY是子控件把消息发送给父窗口,由父窗口来处理消息,消息处理函数在父控件的类里面。
如果用了ON_NOTIFY_REFLECT反射,就是说这个消息由子窗口自己来处理
最后再附赠你一个ON_NOTIFY_REFLECT_EX,你仔细观察的话的话会发现很多消息反射形如ON_COMMAND, ON_NOTIFY, ON_RANGE等等,它们都有个扩展形式ON_COMMAND_EX, ON_NOTIFY_EX, ON_RANGE_EX, 微软这么干有什么意图呢,就是这样的:如果你的ON_NOTIFY_REFLECT_EX(消息, 消息处理函数)中的第二个参数也就是消息处理函数的返回值是bool类型的,且返回值是TRUE,那么就是说这个消息会既发给子控件又发给父窗口,即又在子控件里处理该消息,又在父窗口里处理该消息,如果返回值是FLASE的话或者是其他类型的返回值的话,就只发给子控件了,这个时侯ON_NOTIFY_REFLECT_EX就相当于ON_NOTIFY_REFLECT。
ON_COMMAND_EX等同理。
说了这么多希望你能明白^-^,祝编程道路上一路坦途~
以上
Tab Control是一个标签控件,只有标签,标签下面的窗体要你自己创建的子窗体、并通过回调、或者消息的方式来实现隐藏、显示,从而实现标签+显示选中的子窗体的效果。MFC使用CTabCtrl进行封装,大致的流程是
1.创建TabCtrl
2.通过InsertItem方法添加页签
3.创建子窗体,指定这些窗体的父窗体为 上面创建的TabCtrl
4.在TabCtrl的父窗体类 或者 TabCtrl的继承类中 添加ON_NOTIFY响应消息, OnSize消息
5.实现消息响应函数
参考代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
... ...
int nCtrlID = 1, nTabIndex = 0
if ( !m_wndTab.Create( TCS_FOCUSNEVER|WS_VISIBLE|TCS_RIGHTJUSTIFY, CRect( 0, 0, 0, 0 ), &m_wndView, nCtrlID++ ) )
{
TRACE0("Failed to create m_wndTab \n")
return -1
}
CFont tabFont
tabFont.CreateFont(12,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,
"宋体")
m_wndTab.SetFont(&tabFont,true)
tabFont.Detach()
m_wndTab.InsertItem( nTabIndex++, "错误" )
if ( !m_wndErrEvent.Create( WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_NOSORTHEADER, CRect( 0, 0, 0, 0 ), &m_wndTab, nCtrlID++ ) )
{
TRACE0("Failed to create m_wndErrEvent \n")
return -1
}
m_wndErrEvent.SetExtendedStyle( LVS_EX_FULLROWSELECT )
m_wndErrEvent.InsertColumn( 0, "时间" )
m_wndErrEvent.InsertColumn( 1, "错误事件" )
m_wndErrEvent.ShowWindow( SW_SHOW )
m_wndTab.InsertItem( nTabIndex++, "调试" )
if ( !m_wndDebugEvent.Create( WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_NOSORTHEADER, CRect( 0, 0, 0, 0 ), &m_wndTab, nCtrlID++ ) )
{
TRACE0("Failed to create m_wndDebugEvent \n")
return -1
}
m_wndDebugEvent.SetExtendedStyle( LVS_EX_FULLROWSELECT )
m_wndDebugEvent.InsertColumn( 0, "时间" )
m_wndDebugEvent.InsertColumn( 1, "调试事件" )
m_wndErrEvent.ShowWindow( SW_HIDE )
m_wndDebugEvent.ShowWindow( SW_SHOW )
m_wndTab.SetCurSel( m_wndTab.GetItemCount() - 1 )
}
ChildView.h:
//{{AFX_MSG(CChildView)
afx_msg void OnPaint()
afx_msg void OnSize(UINT nType, int cx, int cy)
//}}AFX_MSG
afx_msg void OnSelChangeTab(NMHDR *pNotify,LRESULT *pResult)
DECLARE_MESSAGE_MAP()
ChildView.cpp:
BEGIN_MESSAGE_MAP(CChildView,CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_NOTIFY(TCN_SELCHANGE,1,OnSelChangeTab)
END_MESSAGE_MAP()
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd ::OnSize(nType, cx, cy)
if (IsWindow(((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.m_hWnd))
{
CRect viewRect
this->GetClientRect(viewRect)
((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.MoveWindow(viewRect)
CRect tabRect
((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.GetClientRect(tabRect)
((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.AdjustRect(FALSE,tabRect)
if (IsWindow(((CMainFrame*)theApp.m_pMainWnd)->m_wndDebugEvent.m_hWnd))
{
((CMainFrame*)theApp.m_pMainWnd)->m_wndDebugEvent.MoveWindow(tabRect)
}
if (IsWindow(((CMainFrame*)theApp.m_pMainWnd)->m_wndErrEvent.m_hWnd))
{
((CMainFrame*)theApp.m_pMainWnd)->m_wndErrEvent.MoveWindow(tabRect)
}
for ( int i = 0i <2i++ )
{
((CMainFrame*)theApp.m_pMainWnd)->m_wndDebugEvent.SetColumnWidth( i, LVSCW_AUTOSIZE_USEHEADER )
((CMainFrame*)theApp.m_pMainWnd)->m_wndErrEvent.SetColumnWidth( i, LVSCW_AUTOSIZE_USEHEADER )
}
}
}
void CChildView::OnSelChangeTab(NMHDR *pNotify,LRESULT *pResult)
{
int cursel=((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.GetCurSel()
if ( cursel == ((CMainFrame*)theApp.m_pMainWnd)->m_wndTab.GetItemCount() - 1 )
{
((CMainFrame*)theApp.m_pMainWnd)->m_wndDebugEvent.ShowWindow(SW_SHOW)
((CMainFrame*)theApp.m_pMainWnd)->m_wndErrEvent.ShowWindow(SW_HIDE)
}
else if ( cursel == 0 )
{
((CMainFrame*)theApp.m_pMainWnd)->m_wndDebugEvent.ShowWindow(SW_HIDE)
((CMainFrame*)theApp.m_pMainWnd)->m_wndErrEvent.ShowWindow(SW_SHOW)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)