| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 678 人关注过本帖
标题:mfc链接
只看楼主 加入收藏
xjyss33
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2012-8-2
收藏
 问题点数:0 回复次数:3 
mfc链接
第三步添加事件关联

关联一个左键双击事件

在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);

}








2.3实现各个分割区域的通信

■有文档相连的视图之间的通信

由AppWizard生成的CCuteFTPView是与文档相连的,同时我们也让CView2与文档相连,因此我们需要修改CCuteFTPApp的InitInstance()函数,我们将增加下面的部分。

view sourceprint?
1.AddDocTemplate (new CMultiDocTemplate(IDR_VIEW2TYPE,  
2.           
 
3.         
RUNTIME_CLASS(CMainDoc),  
4.         
RUNTIME_CLASS(CMDIChildWnd),  
5.         
RUNTIME_CLASS(CView2)));我们现在来实现CCuteFTPView与CView2之间的通信。由于跟文档类相连的视图类 是不能安全的与除文档类之外的其余的视图类通信的。因此我们只能让他们都与文档 类通信。在文档中我们设置相应的指针以用来获的各个视图。我们重载 CCuteFTPView::OnOpenDocument()函数;

view sourceprint?
01.CCuteFTPView* pCuteFTPView;
02.CView2* pView2;
03.POSITION pos;
04.CView* pView;
05.while(pos!=NULL)
06.{
07.      
pView=GetNextView(pos);  
08.      
if(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL)  
09.         
pCuteFTPView=(CCuteFTPView*)pView;  
10.      
else(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL)  
11.         
pView2=(CView2*)pView;  
12.}这样我们在文档类中就获的了跟它相连的所有的视图的指针。

如果需要在 CCuteFTPView中调用CView2中的一个方法DoIt()则代码如下:

view sourceprint?
1.CCuteFTPDoc* pDoc=GetDocument();
2.CView2* pView2=pDoc->pView3;
3.pView3.DoIt();■无文档视图与文档关联视图之间的通信

CView3和CView4都是不与文档相关联的。我们现在实现CView3与CView2的通信.正如前面所说,CView2只能安全的与CCuteFTPDoc通信,因此,CView3如果需要跟CView2通信,也必须借助于文档类。因此程序的关键是如何在CView3中获得文档的指针。视图类中没有这样的类成员可以用来直接访问文档类。但是我们知道在主窗口类MainFrame中我们可以获得程序的任意窗口类的指针。因此我们只要获得程序主窗口了的指针,就可以解决问题了。代码实现在CView3中访问CView2中的DoIt()方法。

CView3中的代码如下:

view sourceprint?
01.CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent();  
02.           
 
03.         
CCuteFTPDoc* Doc=(CCuteFTPDoc*)MainFrame->GetActiveDocument();
04.         
if(Doc!=NULL) Doc->DoIt();  
05.           
 
06.         
CCuteFTPDoc中的相应的处理函数DoIt()代码如下:  
07.           
 
08.         
CView2* pView2;  
09.         
POSITION pos;  
10.         
CView* pView;  
11.         
while(pos!=NULL)  
12.         
{  
13.                  
pView=GetNextView(pos);
14.                  
if(pView->IsKindOf(RUNTIME_CLASS(CView2))==NULL)  
15.                  
pView2=(CView2*)pView;  
16.         
}  
17.         
pView2->DoIt();■无文档关联视图之间的通信

CView3和CView4都是不跟文档相连的,如何实现他们之间的通信呢。 正如我们在上面所说的那样,由于在主框架中我们可以访问任意的视图,因此我们的主要任 务还是在程序中获得主框架的指针。在CView3中访问CView4中的方法DoIt()。

view sourceprint?
1.CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent();  
2.           
 
3.         
CView4* View4=(CView4*)MainFrame->m_wndSplitter1.GetPane(2,0);  
4.         
View4->DoIt();到现在我们已经实现了CuteFTP的主窗口的框架并且能够实现他们之间相互通信的框架。 同样的我们可以实现其他的一些流行界面例如NetAnts,Foxmail的分割。

三、关于对话框的分割

到目前为止,只有基于文档/视图的程序才能使用CSplitterWnd,而基于对话框的应用程序却不支持CSplitterWnd,但是如果我们在继承类中重载一些虚拟方法,也能使CSplitterWnd 在对话框程序中使用。从MFC的源程序WinSplit.cpp中可以看出,为了获得父窗口的地方程序都调用了虚拟方法GetParentFrame(),因此如果在对话框中使用,我们必须将它改为GetParent();因此我们将CSplitterWnd的下面几个方法重载。

view sourceprint?
1.virtual void StartTracking(int ht);  
2.virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol  = NULL);  
3.virtual void SetActivePane( int row, int col, CWnd* pWnd  = NULL );  
4.virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);  
5.virtual BOOL OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult );  
6.virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult );具体实现如下,实现中我将给出原有代码的主要部分以及修改后的代码以作对比。

在cpp文件中加入下面的枚举类型。

view sourceprint?
001.enum HitTestValue  
002.{  
003.                  
noHit = 0,//表示没有选中任何对象
004.                  
vSplitterBox = 1,
005.                  
hSplitterBox = 2,
006.                  
bothSplitterBox = 3,
007.                  
vSplitterBar1 = 101,//代表各个方向的水平分割条
008.                  
vSplitterBar15 = 115,
009.                  
hSplitterBar1 = 201,//代表垂直方向的各个分割条
010.                  
hSplitterBar15 = 215,
011.                  
splitterIntersection1 = 301,//代表各个交叉点
012.                  
splitterIntersection225 = 525
013.};
014.           
 
015.
 
016.CWnd* CxSplitterWnd::GetActivePane(int* pRow, int* pCol)
017.         
{
018.                  
ASSERT_VALID(this);  
019.                  
//获得当前的获得焦点的窗口
020.                  
//下面注释粗体的是原有的代码的主要部分。
021.                  
// CWnd* pView = NULL;
022.                  
//CFrameWnd* pFrameWnd = GetParentFrame();
023.                  
//ASSERT_VALID(pFrameWnd);
024.                  
//pView = pFrameWnd->GetActiveView();
025.                  
//if (pView == NULL)
026.                  
// pView = GetFocus();
027.                  
CWnd* pView = GetFocus();
028.                  
if (pView != NULL && !IsChildPane(pView, pRow, pCol))
029.                          
pView = NULL;
030.                  
return pView;  
031.}  
032.           
 
033.void CxSplitterWnd::SetActivePane( int row, int col, CWnd* pWnd)  
034.{
035.                  
CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;  
036.                  
//下面加注释粗体的是原有代码的主要部分。
037.                  
//FrameWnd* pFrameWnd = GetParentFrame();
038.                  
//ASSERT_VALID(pFrameWnd);  
039.                  
//pFrameWnd->SetActiveView((CView*)pPane);  
040.                  
pPane->SetFocus();//修改后的语句  
041.}
042.           
 
043.void CxSplitterWnd::StartTracking(int ht)
044.{
045.                  
ASSERT_VALID(this);  
046.                  
if (ht == noHit)  
047.                          
return;
048.                  
// GetHitRect will restrict ''''m_rectLimit'''' as appropriate  
049.           
 
050.                  
GetInsideRect(m_rectLimit);
051.                  
if (ht >= splitterIntersection1 && ht <= splitterIntersection225)  
052.           
 
053.                  
{  
054.                          
// split two directions (two tracking rectangles)  
055.           
 
056.                          
int row = (ht - splitterIntersection1) / 15;  
057.           
 
058.                          
int col = (ht - splitterIntersection1) % 15;  
059.           
 
060.                          
GetHitRect(row + vSplitterBar1, m_rectTracker);  
061.           
 
062.                          
int yTrackOffset = m_ptTrackOffset.y;  
063.                          
m_bTracking2 = TRUE;  
064.                          
GetHitRect(col + hSplitterBar1, m_rectTracker2);  
065.           
 
066.                          
m_ptTrackOffset.y = yTrackOffset;  
067.                  
}  
068.                  
else if (ht == bothSplitterBox)  
069.                  
{  
070.                  
// hit on splitter boxes (for keyboard)  
071.                  
GetHitRect(vSplitterBox, m_rectTracker);  
072.                  
int yTrackOffset = m_ptTrackOffset.y;  
073.                  
m_bTracking2 = TRUE;  
074.                  
GetHitRect(hSplitterBox, m_rectTracker2);  
075.                  
m_ptTrackOffset.y = yTrackOffset; // center it  
076.                  
m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2); m_rectTracker2.OffsetRect(m_rectLimit.Width()/2,  
077.         
0);  
078.                  
}  
079.                  
else
080.                  
{  
081.                  
// only hit one bar  
082.                  
GetHitRect(ht, m_rectTracker);  
083.                  
}  
084.           
 
085.         
//下面加注释的将从程序中删去。  
086.         
//CView* pView = (CView*)GetActivePane();  
087.         
//if (pView != NULL && pView->IsKindOf(RUNTIME_CLASS(CView)))  
088.         
//{  
089.         
// ASSERT_VALID(pView);  
090.         
// CFrameWnd* pFrameWnd = GetParentFrame();  
091.         
//ASSERT_VALID(pFrameWnd);  
092.         
//pView->OnActivateFrame(WA_INACTIVE, pFrameWnd);  
093.         
// }  
094.         
// steal focus and capture
095.                  
SetCapture();
096.                  
SetFocus();
097.                  
// make sure no updates are pending  
098.                  
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);  
099.           
 
100.                  
// set tracking state and appropriate cursor
101.                  
m_bTracking = TRUE;
102.                  
OnInvertTracker(m_rectTracker);  
103.                  
if (m_bTracking2)  
104.                          
OnInvertTracker(m_rectTracker2);  
105.                  
m_htTrack = ht;  
106.                  
SetSplitCursor(ht);  
107.}
108.           
 
109.BOOL CxSplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam)  
110.{  
111.                  
if (CWnd::OnCommand(wParam, lParam))  
112.                          
return TRUE;  
113.                  
//下面粗体的是原程序的语句  
114.         
//return GetParentFrame()->SendMessage(WM_COMMAND, wParam, lParam);  
115.           
return GetParent()->SendMessage(WM_COMMAND, wParam, lParam);  
116.           
 
117.}
118.BOOL CxSplitterWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
119.{
120.                  
if (CWnd::OnNotify(wParam, lParam, pResult))  
121.                          
return TRUE;  
122.                  
//下面粗体的是源程序的语句
123.                  
//*pResult = GetParentFrame()->SendMessage(WM_NOTIFY,  
124.         
wParam, lParam); *pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);
125.                  
return TRUE;
126.}  
127.           
 
128.BOOL CxSplitterWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)  
129.{  
130.                  
// The code line below is necessary if using CxSplitterWnd  
131.         
in a regular dll  
132.                  
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
133.                  
return CWnd::OnWndMsg(message, wParam, lParam, pResult);  
134.           
 
135.}这样我们就可以在对话框中使用CxSplitterWnd类了。

四、CSplitterWnd的扩展

CSplitterWnd扩展话题是很多的,我们可以通过对原有方法的覆盖或者增加新的方法来扩展CSplitterWnd。我们在此仅举两个方面的例子。

4.1锁定切分条

当用户创建好分割窗口后,有时并不希望通过拖动切分条来调节窗口的大小。这时就必须锁定切分条。锁定切分条的最简单的方法莫过于不让CSplitterWnd来处理WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_SETCURSOR消息,而是将这些消息交给CWnd窗口进行处理,从而屏蔽掉这些消息。拿WM_LBUTTONDOWN处理过程来说。修改为如下:

view sourceprint?
1.void CXXSplitterWnd::OnLButtonDown(UINT nFlags,CPoint point)  
2.{  
3.        
CWnd::OnLButtonDown(nFlags,point);
4.}其余的处理方法类似。

4.2切分条的定制

由Window自己生成的切分条总是固定的,没有任何的变化,我们在使用一些软件比如ACDSee的时候却能发现它们的切分条却是和自动生成的切分条不一样的。那么如何定制自己的切分条呢?通过重载CSplitterWnd的虚方法OnDrawSplitter和OnInvertTracker可以达到这样的目的。下面的代码生成的效果是分割窗口的边界颜色为红色,分割条的颜色为绿色.代码如下:

view sourceprint?01.void CSplitterWndEx::OnDrawSplitter(CDC *pDC, ESplitType nType, const CRect &rectArg)
02.{
03.                  
if(pDC==NULL)  
04.                  
{  
05.                  
RedrawWindow(rectArg,NULL,RDW_INVALIDATE|RDW_NOCHILDREN);
06.                  
return;
07.                  
}  
08.                  
ASSERT_VALID(pDC);
09.                  
CRect rc=rectArg;
10.                  
switch(nType)  
11.                  
{  
12.                  
case splitBorder:
13.                  
//重画分割窗口边界,使之为红色  
14.                          
pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0));
15.                          
rc.InflateRect(-CX_BORDER,-CY_BORDER);  
16.                          
pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0));  
17.           
 
18.                          
return;  
19.                  
case splitBox:
20.                          
pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
21.                          
rc.InflateRect(-CX_BORDER,-CY_BORDER);  
22.                          
pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
23.                          
rc.InflateRect(-CX_BORDER,-CY_BORDER);
24.                          
pDC->FillSolidRect(rc,RGB(0,0,0));  
25.                          
pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
26.                          
return;  
27.                  
case splitBar:  
28.                  
//重画分割条,使之为绿色  
29.                          
pDC->FillSolidRect(rc,RGB(255,255,255));
30.                          
rc.InflateRect(-5,-5);  
31.                          
pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0));  
32.           
 
33.                          
return;  
34.                  
default:  
35.                          
ASSERT(FALSE);  
36.                  
}  
37.                  
pDC->FillSolidRect(rc,RGB(0,0,255));
38.}  
39.void CSplitterWndEx::OnInvertTracker(CRect &rect)  
40.{  
41.                  
ASSERT_VALID(this);
42.                  
ASSERT(!rect.IsRectEmpty());  
43.                  
ASSERT((GetStyle()&WS_CLIPCHILDREN)==0);
44.                  
CRect rc=rect;  
45.                  
rc.InflateRect(2,2);
46.                  
CDC* pDC=GetDC();  
47.                  
CBrush* pBrush=CDC::GetHalftoneBrush();
48.                  
HBRUSH hOldBrush=NULL;
49.                  
if(pBrush!=NULL) hOldBrush=(HBRUSH)SelectObject(pDC->m_hDC,pBrush->m_hObject);
50.                  
pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),BLACKNESS);  
51.           
 
52.                  
if(hOldBrush!=NULL)  
53.                  
SelectObject(pDC->m_hDC,hOldBrush);
54.                  
ReleaseDC(pDC);  
55.}




搜索更多相关主题的帖子: void 
2012-08-02 09:10
waja
Rank: 2
等 级:论坛游民
帖 子:53
专家分:52
注 册:2012-7-27
收藏
得分:0 
    虽然不懂,但是分享自己的想法就值得称赞
2012-08-03 23:16
Vitens
Rank: 2
等 级:论坛游民
帖 子:38
专家分:47
注 册:2012-7-27
收藏
得分:0 
楼上+1
2012-08-04 08:45
xuexi005
Rank: 2
等 级:论坛游民
帖 子:30
专家分:10
注 册:2012-7-24
收藏
得分:0 
没看懂,我水平有限啊
2012-08-10 08:40
快速回复:mfc链接
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030817 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved