您的位置:首页 > 其它

VC 界面窗口,静态分割后如何锁定分隔条或限制分隔条的移动范围

2013-08-27 14:29 561 查看
锁定分隔条,其中一种方法是直接截获一个消息,我们知道,其实 CsplitterWnd 是从CWnd 派生出来的,所以其实很容易截获Window的消息,在这里我们应该关注的其实仅仅只有一个消息WM_NCHITTEST ,其作用大致就是当你的鼠标在这个划分出的区域中移动时为CWnd捕捉你的鼠标输入的,所以,换言之,如果我们截获了这个消息,直接返回为HTNOWHERE(参考MSDN),那么当你的鼠标停留在Splitter上时就不会出现任何反应,从而锁定的目的就达到了

另一种是重载:OnLButtonDown(UINT nFlags, CPoint point),OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 以及OnMouseMove(UINT nFlags, CPoint point)几个函数,前两个函数的重载也可以达到锁定的效果,第三个函数也就是OnMouseMove()的重载则是为了限定移动的范围(这种情况可能需要的更多一些)下面贴上这两种方法的代码:

两种方法有一个共同点就是需要自己从CSplitterWnd类中派生一个自己的类就叫 MySplitterWnd 好了,先采用第一种方法,来锁定,MySplitterWnd.h中代码如下:


#if !defined(AFX_MYSPLITTERWND_H__A2E77A4F_BB34_4622_8178_ED5FB394208E__INCLUDED_)


#define AFX_MYSPLITTERWND_H__A2E77A4F_BB34_4622_8178_ED5FB394208E__INCLUDED_




#if _MSC_VER > 1000


#pragma once


#endif // _MSC_VER > 1000


// MySplitterWnd.h : header file


//






/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd frame with splitter




#ifndef __AFXEXT_H__


#include <afxext.h>


#endif




class MySplitterWnd : public CSplitterWnd






{


DECLARE_DYNCREATE(MySplitterWnd)


protected:


// protected constructor used by dynamic creation




// Attributes


protected:


CSplitterWnd m_wndSplitter;


public:




MySplitterWnd();




public:




// Overrides


// ClassWizard generated virtual function overrides


//{{AFX_VIRTUAL(MySplitterWnd)


protected:


virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);


afx_msg UINT OnNcHitTest(CPoint point); //新加的




//}}AFX_VIRTUAL




// Implementation


public:


virtual ~MySplitterWnd();




// Generated message map functions


//{{AFX_MSG(MySplitterWnd)


// NOTE - the ClassWizard will add and remove member functions here.


//}}AFX_MSG


DECLARE_MESSAGE_MAP()


};






/**//////////////////////////////////////////////////////////////////////////////




//{{AFX_INSERT_LOCATION}}


// Microsoft Visual C++ will insert additional declarations immediately before the previous line.




#endif // !defined(AFX_MYSPLITTERWND_H__A2E77A4F_BB34_4622_8178_ED5FB394208E__INCLUDED_)



其中关键的语句就是 加一句 afx_msg UINT OnNcHitTest(CPoint point)的定义,然后再在MySplitterWnd.cpp具体实现这个函数,如下


// MySplitterWnd.cpp : implementation file


//




#include "stdafx.h"


#include "GL.h"


#include "MySplitterWnd.h"




#ifdef _DEBUG


#define new DEBUG_NEW


#undef THIS_FILE


static char THIS_FILE[] = __FILE__;


#endif






/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd




IMPLEMENT_DYNCREATE(MySplitterWnd, CSplitterWnd)




MySplitterWnd::MySplitterWnd()






{


}




MySplitterWnd::~MySplitterWnd()






{


}






BOOL MySplitterWnd::OnCreateClient(LPCREATESTRUCT /**//*lpcs*/, CCreateContext* pContext)






{


return m_wndSplitter.Create(this,


2, 2, // TODO: adjust the number of rows, columns


CSize(10, 10), // TODO: adjust the minimum pane size


pContext);


}






afx_msg UINT MySplitterWnd::OnNcHitTest(CPoint /**//*point*/)






{


return HTNOWHERE;


}








/**//*BEGIN_MESSAGE_MAP(MySplitterWnd, CSplitterWnd)


//{{AFX_MSG_MAP(MySplitterWnd)


// NOTE - the ClassWizard will add and remove mapping macros here.


//}}AFX_MSG_MAP


END_MESSAGE_MAP()*/






BEGIN_MESSAGE_MAP(MySplitterWnd, CSplitterWnd)


ON_WM_NCHITTEST()


END_MESSAGE_MAP()








/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd message handlers



可以看到,具体实现就一句话,return HTNOWHERE。现在就OK了,我的表述已经尽可能清楚了,如果实在不理解也没关系,你们可以直接将上面的.h和.cpp直接复制过去,直接加入到你的工程中,到时候用的时候直接 定义用 MySplitterWnd这个类定义 自己的变量,如 MySplitterWnd XXX(自己随便取名)

下面介绍另一种方法,也是同上面一样需要自己建立一个类,还是叫MySplitterWnd好了,基类还是CSplitterWnd

然后 在MySplitterWnd.h中添加如下代码(位置 和添加OnNcHitTest(...)函数一样)

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

在MySplitterWnd.cpp中添加三个函数的具体实现代码如下:

void MySplitterWnd::OnLButtonDown(UINT nFlags, CPoint point)

{

// 直接返回,不处理

return;

}

BOOL MySplitterWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)

{

// 当光标进入分割窗口时,不允许改变样子,不处理

return FALSE;

}

void MySplitterWnd::OnMouseMove(UINT nFlags, CPoint point)

{

//将CSplitter类的处理改为由CWnd处理

//CSplitterWnd::OnMouseMove(nFlags, point);

if(point.x<250||point.x>500) CWnd::OnMouseMove(nFlags, point);

else CSplitterWnd::OnMouseMove(nFlags, point);

}

好了,其实到了这里还没有完,刚说到锁定的问题,大家可以发现如果三个函数这样子写你的分隔条直接不能动了,和刚才的截取消息的锁定效果一摸一样,但是关于第三个函数OnMouseMove()的实际作用其实是限定范围,if(point.x<250||point.x>500) CWnd::OnMouseMove(nFlags, point);

else CSplitterWnd::OnMouseMove(nFlags, point); 这两句的意思是说将移动范围锁定在250和500之间(这个数值大家可以随便设置),为了要使得这个函数生效,大家可以把前面两个也就是OnLButtonDown()和OnSetCursor()屏蔽掉,只留下第三个OnMouseMove()就可以达到限制范围的效果了,当然只屏蔽掉OnLButtonDown()函数也是可以的,因为OnSetCursor()函数只是改变光标样子用的,(锁定的另一个方法其实就是只用前面两个,既屏蔽掉OnMouseMove(),这个函数,大家可以自己试试,分别屏蔽看会出现什么效果)

MySplitterWnd.h和MySplitterWnd.cpp分别如下:

MySplitterWnd.h:


#if !defined(AFX_MYSPLITTERWND_H__7AA280DC_82F5_4FF5_95A6_036C8A20B50D__INCLUDED_)


#define AFX_MYSPLITTERWND_H__7AA280DC_82F5_4FF5_95A6_036C8A20B50D__INCLUDED_




#if _MSC_VER > 1000


#pragma once


#endif // _MSC_VER > 1000


// MySplitterWnd.h : header file


//






/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd frame with splitter




#ifndef __AFXEXT_H__


#include <afxext.h>


#endif




class MySplitterWnd : public CSplitterWnd






{






public:




MySplitterWnd();


// Operations


public:




// Overrides


// ClassWizard generated virtual function overrides


//{{AFX_VIRTUAL(MySplitterWnd)








//}}AFX_VIRTUAL




// Implementation


public:


virtual ~MySplitterWnd();








DECLARE_DYNCREATE(MySplitterWnd)






afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //新加的


afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); //新加的


afx_msg void OnMouseMove(UINT nFlags, CPoint point); //新加的




DECLARE_MESSAGE_MAP() //后加的






};






/**//////////////////////////////////////////////////////////////////////////////




//{{AFX_INSERT_LOCATION}}


// Microsoft Visual C++ will insert additional declarations immediately before the previous line.




#endif // !defined(AFX_MYSPLITTERWND_H__7AA280DC_82F5_4FF5_95A6_036C8A20B50D__INCLUDED_)



MySplitterWnd.cpp:


// MySplitterWnd.cpp : implementation file


//




#include "stdafx.h"


#include "GL.h"


#include "MySplitterWnd.h"




#ifdef _DEBUG


#define new DEBUG_NEW


#undef THIS_FILE


static char THIS_FILE[] = __FILE__;


#endif






/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd






IMPLEMENT_DYNCREATE(MySplitterWnd, CSplitterWnd)






BEGIN_MESSAGE_MAP(MySplitterWnd, CSplitterWnd)


//ON_WM_LBUTTONDOWN()


//ON_WM_SETCURSOR()


ON_WM_MOUSEMOVE()




END_MESSAGE_MAP()










MySplitterWnd::MySplitterWnd()






{


}




MySplitterWnd::~MySplitterWnd()






{


}






/**//*void MySplitterWnd::OnLButtonDown(UINT nFlags, CPoint point)


{


// 直接返回,不处理


return;


}




BOOL MySplitterWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)


{


// 当光标进入分割窗口时,不允许改变样子,不处理


return FALSE;


}*/




void MySplitterWnd::OnMouseMove(UINT nFlags, CPoint point)






{




//将CSplitter类的处理改为由CWnd处理


//CSplitterWnd::OnMouseMove(nFlags, point);




if(point.x<250||point.x>500) CWnd::OnMouseMove(nFlags, point);


else CSplitterWnd::OnMouseMove(nFlags, point);




}












/**//*


BEGIN_MESSAGE_MAP(MySplitterWnd, CSplitterWnd)


//{{AFX_MSG_MAP(MySplitterWnd)


// NOTE - the ClassWizard will add and remove mapping macros here.


//}}AFX_MSG_MAP


END_MESSAGE_MAP()*/






/**//////////////////////////////////////////////////////////////////////////////


// MySplitterWnd message handlers



说的可能有些不清楚,不清楚的也没关系,可以直接将上面的MySplitterWnd.h和MySplitterWnd.cpp导入到自己的工程中,直接用就行了,将你要锁定或者限制移动范围的分割区域用MySplitterWnd定义,不做限制,锁定的区域用CSplitterWnd类定义,这样子就可以做到有选择的限制锁定某几个分割区域的效果.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: