【CSplitterWnd技巧一】改變分割窗口拖動(dòng)條的大小
作者:周焱
大家都知道默認(rèn)的CSplitterWnd的拖動(dòng)條很寬,看起來(lái)占地方,也不美觀。怎么改變它呢?
研究CSplitterWnd的構(gòu)造函數(shù)發(fā)現(xiàn),拖動(dòng)條的寬度是可以設(shè)置的。下面是我寫的一個(gè)簡(jiǎn)單的CMySplitter類。他的效果如下:
下面是CMySplitter的代碼:
=========================================================
//MySplitter.h
#pragma once
#include "stdafx.h"
class CMySplitter : public CSplitterWnd
{
public:
CMySplitter();
DECLARE_DYNCREATE(CMySplitter)
public:
~CMySplitter();
protected:
DECLARE_MESSAGE_MAP()
};
=========================================================
//MySplitter.cpp
#include "MySplitter.h"
IMPLEMENT_DYNCREATE(CMySplitter, CSplitterWnd)
//在構(gòu)造函數(shù)中改變分割條的寬度和屬性!
CMySplitter::CMySplitter()
{
m_cxSplitter = 4; //must >=4 ,拖動(dòng)時(shí)拖動(dòng)條的寬度
m_cySplitter = 4;
m_cxBorderShare = 0; //按下鼠標(biāo)時(shí)拖動(dòng)條的偏移量
m_cyBorderShare = 0;
m_cxSplitterGap= 1; //splitter拖動(dòng)條的寬度
m_cySplitterGap= 1;
}
CMySplitter::~CMySplitter()
{
}
BEGIN_MESSAGE_MAP(CMySplitter, CSplitterWnd)
END_MESSAGE_MAP()
=========================================================
使用時(shí),在主窗口中包含頭文件MySplitter.h,將CSplitterWnd改成CMySplitter就可以了。
【CSplitterWnd技巧二】使分割窗口不能改變大小
有時(shí)候,需要保持分割窗口中每個(gè)小窗口的尺寸或者比例,不允許用戶拖動(dòng)分割條。我考慮了有兩種方法可以實(shí)現(xiàn)。效果如下,鼠標(biāo)在分割條上,沒(méi)有出現(xiàn)可以改變大小的箭頭。
方法1:
================================================
//CMySplitter.h
#pragmaonce
#include"stdafx.h"
classCMySplitter:publicCSplitterWnd
{
DECLARE_DYNAMIC(CMySplitter)
public:
protected:
//{{AFX_MSG(CMySplitter)
afx_msg UINT OnNcHitTest(CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
================================================
//CMySplitter.cpp
#include"Cmysplitter.h"
IMPLEMENT_DYNAMIC(CMySplitter,CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter,CSplitterWnd)
ON_WM_NCHITTEST()
END_MESSAGE_MAP()
UINTCMySplitter::OnNcHitTest(CPointpoint)
{
//返回HTNOWHERE...
return HTNOWHERE;
}
================================================
方法2:
================================================
//CMySplitter.h
#pragmaonce
#include"stdafx.h"
classCMySplitter:publicCSplitterWnd
{
DECLARE_DYNCREATE(CMySplitter)
protected:
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()
};
================================================
//CMySplitter.cpp
#include"CMySplitter.h"
IMPLEMENT_DYNCREATE(CMySplitter,CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter,CSplitterWnd)
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
voidCMySplitter::OnLButtonDown(UINTnFlags,CPointpoint)
{
//直接返回
return;
}
BOOLCMySplitter::OnSetCursor(CWnd*pWnd,UINTnHitTest,UINTmessage)
{
//當(dāng)光標(biāo)進(jìn)入分割窗口時(shí),不允許改變樣子
return FALSE;
}
voidCMySplitter::OnMouseMove(UINTnFlags,CPointpoint)
{
//跳過(guò)調(diào)用CSplitterWnd::OnMouseMove,因?yàn)樗麜?huì)引起光標(biāo)的改變
CWnd::OnMouseMove(nFlags,point);
}
================================================
雖然上面兩種方法,一個(gè)繁一個(gè)易,但是從不同的角度分析和解決了問(wèn)題。其實(shí),面對(duì)一個(gè)想法,可能有多種處理方案。如果我們認(rèn)真思考,會(huì)發(fā)現(xiàn)有很多方法能夠達(dá)到我們的要求。
【CSplitterWnd技巧三】能拖動(dòng)的帶背景顏色的分割條
想實(shí)現(xiàn)這個(gè)功能,曾經(jīng)困擾了我一段時(shí)間,后來(lái)發(fā)現(xiàn)原來(lái)是犯了一些小錯(cuò)誤。
功能:
1,帶背景顏色
2,拖動(dòng)拖動(dòng)條,能拖動(dòng)窗口
效果如下:
程序:
==================================================
//MySplitter.h
#pragma once
#include "stdafx.h"
class CMySplitter : public CSplitterWnd
{
public:
CMySplitter();
DECLARE_DYNCREATE(CMySplitter)
public:
~CMySplitter();
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT,CPoint);
BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
HBRUSH m_hbr; //背景刷子
CString m_clsName; //窗口類名
DECLARE_MESSAGE_MAP()
};
==================================================
//MySplitter.cpp
#include "MySplitter.h"
IMPLEMENT_DYNCREATE(CMySplitter, CSplitterWnd)
CMySplitter::CMySplitter()
{
m_cxSplitter = 4; //must >=4 ,拖動(dòng)splitter時(shí)拖動(dòng)條的寬度
m_cySplitter = 4;
m_cxBorderShare = -4; //按下鼠標(biāo)時(shí)splitter拖動(dòng)條的偏移量
m_cyBorderShare = -4;
m_cxSplitterGap= 16;
m_cySplitterGap= 16; //splitter拖動(dòng)條的寬度
m_hbr = ::CreateSolidBrush(RGB(98,98,98));
m_clsName = "";
}
CMySplitter::~CMySplitter()
{
}
BEGIN_MESSAGE_MAP(CMySplitter, CSplitterWnd)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
void CMySplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
//拖動(dòng)splitter拖動(dòng)條,能夠拖動(dòng)窗口
::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
CWnd::OnLButtonDown(nFlags,point);
}
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
//跳過(guò)調(diào)用CSplitterWnd::OnMouseMove,因?yàn)樗麜?huì)引起光標(biāo)的改變
CWnd::OnMouseMove(nFlags, point);
}
BOOL CMySplitter::PreCreateWindow(CREATESTRUCT& cs)
{
//窗口類名必須在類的域類有效,否則::CreateWindowEx得到的是無(wú)效的類名。
//將會(huì)導(dǎo)致創(chuàng)建文檔失敗的錯(cuò)誤。
m_clsName = AfxRegisterWndClass(0, ::LoadCursor (NULL,
IDC_ARROW), ::CreateSolidBrush(RGB(255,95,17)));
cs.lpszClass = (const char* )m_clsName;
return CSplitterWnd::PreCreateWindow(cs);
}
==================================================
說(shuō)明:
1,要實(shí)現(xiàn)用拖動(dòng)條拖動(dòng)窗口,不能簡(jiǎn)單的用技巧2介紹的OnNcHitTest返回HTCAPTION來(lái)解決。因?yàn)檫@樣只能拖動(dòng)分割窗口,不能拖動(dòng)主窗口。這里用在左鍵按下的時(shí)候 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y)),通過(guò)給主窗口發(fā)送帶HTCAPTION的WM_NCLBUTTONDOWN消息來(lái)實(shí)現(xiàn)。
2,默認(rèn)的分割窗口的類名是AfxMDIFrame42d,它和MDI程序中的主窗口差不多,沒(méi)有背景刷。在這里注冊(cè)了一個(gè)新的窗口類,并指定了背景刷。要注意的是,窗口類名不能在PreCreateWindow中申明,應(yīng)該放在類的申明中,作為類的成員函數(shù)。
聯(lián)系客服