一种做法是:
第一层是基于对话框的主窗体;
第二层是主窗体上的TabContrl,TabContrl在设计时创建,在程序中添加多个Item;
第三层是在TabContrl上的通过程序创建工具条。这种做法存在一个问题,第一层主窗体接收不到第三层的工具条发送的消息。还有一种做法就是:
第一层是基于对话框的主窗体;
第二层是主窗体上的TabContrl,TabContrl在设计时创建,在程序中添加多个Item;
第三层是TabContrl上的用于放置工具条或其它控件的对话框,为这个对话框创建一个自定义的对话框类,
并在这个自定义的对话框类中创建了工具条;
第四层是放置工在对话框上的工具条。直接在第一层主窗体对第四层工具条的按钮消息进行处理是不行的,好像是第一层的主窗体
接收不到第四层工具条发送的消息。好像是工具条只向它的父类(第三层的对话框)发送消息。
所以我在自定义的对话框类中处理工具条上按钮的消息,并发送自定义消息到第一层的主窗体。这样的做法好像也不太好,现在我要问的问题是:
有没有更好的处理消息的做法,比如在第三层接收到第四层的消息后把消息映射到第一层的主窗体中,
这样在主窗体中直接处理第四层的工具条上的按钮消息就可以了。另外要问的问题是:
::PostMessage()跟PostMessage()有什么不同?
如何在第N层的子窗中直接向顶层的基于对话框的主窗发送消息?
在基于对话框的主窗中除了在PreTranslateMessage(MSG* pMsg)中处理消息外,还可以怎样处理来自子窗的用户自定义消息?
如何获得基于对话框的主窗的句柄handle?以下是实现的关键代码片断。
各个对话框和工具条像平常一样在设计状态创建就可以了。ToolDialog0.h
-------------------------------------------------------
class CToolDialog0 : public CDialog
{
// Implementation
protected:
CToolBar m_wndtoolbar0; // Generated message map functions
//{{AFX_MSG(CToolDialog0)
virtual BOOL OnInitDialog();
afx_msg void OnTab0But1();
afx_msg void OnTab0But2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
=======================================================ToolDialog0.cpp
-------------------------------------------------------
BEGIN_MESSAGE_MAP(CToolDialog0, CDialog)
//{{AFX_MSG_MAP(CToolDialog0)
ON_COMMAND(ID_BUTTON32777, OnTab0But1)
ON_COMMAND(ID_BUTTON32778, OnTab0But2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()BOOL CToolDialog0::OnInitDialog() 
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here
if (!m_wndtoolbar0.CreateEx( this,TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
      ,CRect(0,0,0,0),IDR_TOOLBAR0) || !m_wndtoolbar0.LoadToolBar(IDR_TOOLBAR0) )
{
TRACE0("failed to create toolbar\n");
return FALSE;
}

m_wndtoolbar0.ShowWindow(SW_SHOW);
m_wndtoolbar0.MoveWindow(0,0,100,30,TRUE);

return TRUE;  // return TRUE unless you set the focus to a control
              // EXCEPTION: OCX Property Pages should return FALSE
}void CToolDialog0::OnTab0But1() 
{
// TODO: Add your command handler code here
//两个PostMessage都可以起作用, 但参数不一样
::PostMessage(GetParent()->GetSafeHwnd(), MSG_TAB0BUT1_CLICK, 1, NULL);
// PostMessage(MSG_TAB0BUT1_CLICK, NULL, NULL);}void CToolDialog0::OnTab0But2() 
{
// TODO: Add your command handler code here
::PostMessage(GetParent()->GetSafeHwnd(), MSG_TAB0BUT1_CLICK, 2, NULL);

}
=======================================================Dlg_Base_FormDlg.h
-------------------------------------------------------
class CDlg_Base_FormDlg : public CDialog
{
// Dialog Data
//{{AFX_DATA(CDlg_Base_FormDlg)
enum { IDD = IDD_DLG_BASE_FORM_DIALOG };
CTabCtrl m_tab1;
CEdit m_edit;
//}}AFX_DATA // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlg_Base_FormDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL// Implementation
protected:
HICON m_hIcon;
CToolBar m_wndtoolbar;
CMyTabCtrl m_wndTabCtrl;
CToolDialog0 m_dlgTab0;
CToolDialog1 m_dlgTab2; // Generated message map functions
//{{AFX_MSG(CDlg_Base_FormDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
afx_msg void OnTab0But1Click();
afx_msg void OnTab0But2Click();
DECLARE_MESSAGE_MAP()
};
=======================================================Dlg_Base_FormDlg.cpp
-------------------------------------------------------
BOOL CDlg_Base_FormDlg::OnInitDialog()
{
// TODO: Add extra initialization here
MoveWindow(0,0,1000,760,TRUE);
m_tab1.InsertItem(0,"文件Tab1");
m_tab1.InsertItem(1,"绘图Tab2");
m_tab1.InsertItem(2,"捕捉");
m_tab1.InsertItem(3,"标注");
m_tab1.InsertItem(4,"测量");

CWnd* pWnd = (CWnd*)GetDlgItem(IDC_TAB1); m_dlgTab0.Create(IDD_DIALOG0,pWnd);
m_dlgTab0.ShowWindow(SW_SHOW);
m_dlgTab0.MoveWindow(10,30,500,100,TRUE); m_dlgTab2.Create(IDD_DIALOG1,pWnd);
m_dlgTab2.ShowWindow(SW_HIDE);
m_dlgTab2.MoveWindow(10,30,500,100,TRUE); return TRUE;  // return TRUE  unless you set the focus to a control
}void CDlg_Base_FormDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) 
{
// TODO: Add your control notification handler code here
int nPage;
nPage=m_tab1.GetCurSel();
switch (nPage)
{
case 0:
m_edit.SetWindowText(CString("page 0"));
m_dlgTab0.ShowWindow(SW_SHOW);
m_dlgTab2.ShowWindow(SW_HIDE);
break;
case 1:
m_edit.SetWindowText(CString("page 1"));
m_dlgTab2.ShowWindow(SW_SHOW);
m_dlgTab0.ShowWindow(SW_HIDE);
break;
case 2:
m_edit.SetWindowText(CString("page 2"));
break;
case 3:
m_edit.SetWindowText(CString("page 3"));
break;

} *pResult = 0;
}void CDlg_Base_FormDlg::OnTab0But1Click() 
{
// TODO: Add your command handler code here
MessageBox("OnTab0But1Click\n主窗体中接收对话框类中发出的自定义消息:\nTab0的Button[01]按下了!");}void CDlg_Base_FormDlg::OnTab0But2Click() 
{
// TODO: Add your command handler code here
MessageBox("OnTab0But2Click\n主窗体中接收对话框类中发出的自定义消息:\nTab0的Button[02]按下了!");}BOOL CDlg_Base_FormDlg::PreTranslateMessage(MSG* pMsg) 
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message==MSG_TAB0BUT1_CLICK)
switch (pMsg->wParam)
{
case 1:
OnTab0But1Click();
break;
case 2:
OnTab0But2Click();
break;
} //MessageBox("主窗体中接收嵌入对话框里的工具条上按钮消息处理:\nTab0的第1键[0]按下了!"); return CDialog::PreTranslateMessage(pMsg);
}