前两天做了一个视图拆分和多文档通信的小程序.
实现:
将单文档分成三个视图,如图片所示.左上为CView1,左下为CDilView1,右边为Cdesktop2View(也就是工程生成的视图)
在view1里创建一个树控件.然后在点击页结点的时候由CDilView1中的一个Edit框和Cdesktop2View视图来显示内容
参考了不少文章,发现需要做这个的人确实不少,所以做出来以后希望和大家共享.也希望大家多提意见.本文参考
http://www.vckbase.com/document/viewdoc/?id=192http://www.vckbase.net/document/viewdoc/?id=560还有几篇,并引用了上面的代码....网址找不到了.
我的程序是这样的.
首先创建一个单文档工程desktop2
在用类向导创建两个新类一个CView1继承自CView一个CDilView1继承自CFormView.注意由CFormView派生的类,必须指定一个对话框资源,而这个对话框必须是WS_CHILD=On,WS_BORDER=Off,WS_VISIBLE=Off,WS_CAPTION=Off,即无标题、无边框、不可见的子窗口满足以上要求的.如果不满足编译会通过但运行时将会出现断言ASSERT错误;
第一步,切分窗口.
用到类CSplitterWnd的方法来切分.所以在CMainFrame声名两个变量 CSplitterWnd m_wndSpli1,m_wndSpli2;
为什么是两个呢?因为先把一个窗口切分成左右两个然后在把左边切分成上下两个当然要用两上变量
然后在CMainFrame的OnCreateClient中
- BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
- {
- // TODO: Add your specialized code here and/or call the base class
- if (!m_wndSpli1.CreateStatic(this,1,2))
- {
- return FALSE;
- }
- if(!m_wndSpli2.CreateStatic(&m_wndSpli1,2,1,WS_CHILD|WS_VISIBLE| WS_BORDER,
- m_wndSpli1.IdFromRowCol(0,0)))
- {
- return FALSE;
- }
- m_wndSpli2.CreateView(0,0,RUNTIME_CLASS(CView1),CSize(0,0), pContext);
- m_wndSpli2.CreateView(1,0,RUNTIME_CLASS(CDilView1),CSize(0,0), pContext);
- m_wndSpli1.CreateView(0,1,RUNTIME_CLASS(CDesktop2View),CSize(0,0), pContext);
- m_wndSpli1.SetColumnInfo(0,220,0);
- m_wndSpli2.SetRowInfo(0,300,0);
- return TRUE;
- }
程序的第四行将当前窗口切分成左右两个第9行将左侧窗口切分成上下两个,这样就得到了三个窗口,所以必须为这三个窗口都关联视图类.所以在第14-16行为每个视图关联视图类,第18-19行为视图设置宽和高.
运行一下.基本的框架已经出来了.
第二步在CView1中添加一个树控件
在.h文件中添加变量CTreeCtrl m_TreeCtrl;
然后在OnInitialUpdate中创建这棵树代码如下
m_TreeCtrl.Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD
| TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES
| TVS_DISABLEDRAGDROP|TVS_EDITLABELS|TVS_TRACKSELECT,
CRect(10, 10, 150, 300), this, ID_TREERECORD);
// m_TreeCtrl.SetImageList(&m_images,TVSIL_NORMAL);
// set "normal" GUI-font
CFont *font = CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT));
m_TreeCtrl.SetFont(font);
HTREEITEM root = m_TreeCtrl.InsertItem("VCKBASE",0,0);
HTREEITEM subroot1=m_TreeCtrl.InsertItem("程序员社区",1,1,root);
HTREEITEM subroot2=m_TreeCtrl.InsertItem("文档中心",1,1,root);
HTREEITEM subroot3=m_TreeCtrl.InsertItem("代码仓库",1,1,root);
HTREEITEM subroot4=m_TreeCtrl.InsertItem("工具和资源",1,1,root);
HTREEITEM subroot5=m_TreeCtrl.InsertItem("客服中心",1,1,root);
HTREEITEM subroot6=m_TreeCtrl.InsertItem("个人专栏",1,1,root);
m_TreeCtrl.InsertItem("开发论坛",1,1,subroot1);
m_TreeCtrl.InsertItem("开发联盟",1,1,subroot1);
m_TreeCtrl.InsertItem("人才交流",1,1,subroot1);
m_TreeCtrl.InsertItem("用户注册",1,1,subroot1);
m_TreeCtrl.InsertItem("VCity",1,1,subroot1);
m_TreeCtrl.InsertItem("在线杂志",1,1,subroot2);
m_TreeCtrl.InsertItem("个人专辑",1,1,subroot2);
m_TreeCtrl.InsertItem("论坛精华",1,1,subroot2);
m_TreeCtrl.InsertItem("酷库",1,1,subroot2);
m_TreeCtrl.InsertItem("所有文章",1,1,subroot2);
m_TreeCtrl.InsertItem("所有代码",1,1,subroot3);
m_TreeCtrl.InsertItem("程序工具箱",1,1,subroot4);
m_TreeCtrl.InsertItem("程序工具箱",1,1,subroot5);
m_TreeCtrl.InsertItem("用户注册",1,1,subroot5);
m_TreeCtrl.InsertItem("修改信息",1,1,subroot5);
m_TreeCtrl.InsertItem("取回密码",1,1,subroot5);
m_TreeCtrl.InsertItem("问题解答",1,1,subroot5);
m_TreeCtrl.InsertItem("投稿",1,1,subroot5);
m_TreeCtrl.InsertItem("联系我们",1,1,subroot5);
m_TreeCtrl.SelectItem(root);
m_TreeCtrl.Expand(root, TVE_EXPAND);
第三步添加事件关联
关联一个左键双击事件
在CView.h中添加
afx_msg void OnTreeDblClk(LPNMHDR,LRESULT* pResult);
在.cpp文件的消息映射中添加
BEGIN_MESSAGE_MAP(CView1, CView)
//{{AFX_MSG_MAP(CView1)
ON_NOTIFY(NM_DBLCLK,ID_TREERECORD,OnTreeDblClk) //此行为自己添加.其余是生成的.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
然后在写OnTreeDblClk(LPNMHDR,LRESULT* pResult)的代码就可以了.
第四步实现通信
其实实现通信很简单,只要有一个关联就可以了网上有很多方法就不一一说了我的实现是这样的
void CView1::OnTreeDblClk(LPNMHDR,LRESULT* pResult)
{
HTREEITEM m_hTreeSel = m_TreeCtrl.GetSelectedItem();
if (m_TreeCtrl.GetChildItem( m_hTreeSel )==NULL) {
//获取CMainFrame指针,然后通过这个指针取得里面的数据成员也就是我们切分窗口时用的变量
//然后用它来获取view类的指针.有了指针我们就可以随便做了
CMainFrame * pMainFrm = (CMainFrame*)AfxGetMainWnd();
CDilView1 *m_divew = (CDilView1*)pMainFrm->m_wndSpli2.GetPane(1,0);
CDesktop2View *m_this = (CDesktop2View*)pMainFrm->m_wndSpli1.GetPane(0,1);
m_this->DrawText(m_TreeCtrl.GetItemText(m_hTreeSel));//为CDesktop2View设置显示文字,当然了要在CDesktop2View类中添加
//一个DrawText(CString str)函数.
m_divew->SetDlgItemText(IDC_EDIT1,m_TreeCtrl.GetItemText(m_hTreeSel));//为CDilView1设置显示文字
}
}
DrawText函数实现
void CDesktop2View::DrawText(CString str)
{
CDC *pDC;
pDC = this->GetDC();
CRect rect;
pDC->Rectangle(10,10,100,100);
rect.top=100;
rect.left=100;
rect.right=250;
rect.bottom=250;
pDC->TextOut(15,15,str);
ReleaseDC(pDC);
}
希望对大家有用.