原帖:http://luwenjie0904.blog.163.com/blog/static/9656154120113891022326/
一、基本的CSplitterWnd的使用
1. 在CMainFrame中添加一個(gè)CSplitterWnd成員:
CSplitterWnd m_splitterwnd1;
2. 基于CView創(chuàng)建兩個(gè)新的視圖類,CViewLeft和CViewRight,一個(gè)用于在左邊顯示,一個(gè)用于在右邊顯示。
3. 重載CMainFrame的OnCreateClient函數(shù),在并其中調(diào)用CSplitterWndr的CreateStatic函數(shù)創(chuàng)建該分割窗口,CreateView函數(shù)創(chuàng)建左右兩個(gè)視圖,SetColumnInfo設(shè)定分割窗口的列的寬度:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加專用代碼和/或調(diào)用基類
m_mysplitter1.CreateStatic(this, 1, 2); //創(chuàng)建一個(gè)一行二列的分割窗口
m_mysplitter1.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0),
pContext); //建立第0行第0列的視圖
m_mysplitter1.CreateView(0, 1, RUNTIME_CLASS(CViewRight), CSize(0, 0),
pContext); //建立第0行第1列的視圖
m_mysplitter1.SetColumnInfo(0, 250, 10); //設(shè)定某列的寬度,這里表示設(shè)定第0列的理想寬度為250像素,最小寬度為10像素(什么是最小寬度?沒弄明白)
return TRUE;
//return CFrameWnd::OnCreateClient(lpcs, pContext);
}
運(yùn)行后就可以看到生成了分割為左右兩個(gè)視圖的窗口。
二、為分割窗添加一些自己需要的功能
從系統(tǒng)的CSplitterWnd類派生一個(gè)新類。
在類視圖中右鍵,選擇“添加”->“類”,在彈出窗口中選擇MFC類,輸入新類的名字CMySplitter,基類選擇為CWnd(這里基類的選項(xiàng)里面沒有CSplitterWnd,所以要先選擇Cwnd)。然后把生成的MySplitter.h和MySplitter.cpp里面的三個(gè)地方的“Cwnd”改成“CSplitterWnd”。
MySplitter.h中:
class CMySplitter : public CSplitterWnd
Mysplitter.cpp中:
IMPLEMENT_DYNAMIC(CMySplitter, CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter, CSplitterWnd)
1. 雙擊分隔欄展開或者收起左邊的一欄
重載OnLButtonDblClk函數(shù):
void CMySplitterWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
//CSplitterWnd::OnLButtonDblClk(nFlags, point);
int left, min;
GetColumnInfo(0, left, min); //得到第0欄(即左邊的一欄)的寬度
if(left == 0 || left == min) //如果當(dāng)前已經(jīng)是收起的狀態(tài)
{
SetColumnInfo(0, 250, 10); //重新設(shè)置左邊一欄的寬度,這里設(shè)置為250,即展開
}
else
{
SetColumnInfo(0, 0, 10); //重新設(shè)置左邊一欄的寬度,這里設(shè)置為0,即收起
}
RecalcLayout(); //重新構(gòu)建窗口布局
}
2. 設(shè)置分隔欄的寬度
在CMySplitter的構(gòu)造函數(shù)中(這里是把寬度設(shè)為11像素):
m_cxSplitterGap = 11;
m_cxSplitter = 11;
幾個(gè)相關(guān)變量的意義:
//int m_cxSplitter, m_cySplitter; // size of splitter bar
//int m_cxBorderShare, m_cyBorderShare; // space on either side of splitter
//int m_cxSplitterGap, m_cySplitterGap; // amount of space between panes
//int m_cxBorder, m_cyBorder; // borders in client area
3. 禁止拖動(dòng)分隔欄的位置
(1)重載OnLButtonDown函數(shù),改成什么都不做:
void CMySplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
//CSplitterWnd::OnLButtonDown(nFlags, point);
}
(2)重載OnMouseMove函數(shù),也改成什么都不做:
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
//CSplitterWnd::OnMouseMove(nFlags, point);
}
4. 在分隔欄上添加一個(gè)”按鈕“
(1)在資源視圖中導(dǎo)入兩張位圖資源,分另是一個(gè)向左的箭頭和一個(gè)向右的箭頭,圖片大小為(6*31)像素:IDB_BITMAP_LEFT,IDB_BITMAP_RIGHT
(2)為CMySplitter類添加顯示該“按鈕”相關(guān)的成員:
CBitmap m_bitmapleft; //左箭頭位圖
CBitmap m_bitmapright; //右箭頭位圖
CDC m_dcMem; //
CRect m_rectImgBtn; //顯示該“按鈕”的矩形區(qū)域
(3)添加一個(gè)成員函數(shù)得到顯示該“按鈕”的矩形區(qū)域:
//這個(gè)函數(shù)用來得到顯示該按鈕的矩形區(qū)域
void CMySplitter::GetImgBtnRect(void)
{
CRect r;
int left, min;
GetWindowRect(&r);
GetColumnInfo(0, left, min);
m_rectImgBtn.SetRect(left+2+2, r.Height()/2-16,
left+2+8, r.Height()/2+15); //這里這么寫是根據(jù)WindowsXP顯示的分隔欄來確定的,要用繪圖軟件測(cè)一下
if(left == 250) //這里用到了正常顯示下的左欄是250像素寬
{
if(m_dcMem != NULL)
{
m_dcMem.SelectObject(m_bitmapleft); //這個(gè)DC選擇左箭頭的圖片
}
}
else
{
if(m_dcMem != NULL)
{
m_dcMem.SelectObject(m_bitmapright); //這個(gè)DC選擇右箭頭的圖片
}
}
}
(4)重載OnDrawSplitter函數(shù),畫出該按鈕:
void CMySplitter::OnDrawSplitter(CDC* pDC, ESplitType nType,
const CRect& rect)
{
// TODO: 在此添加專用代碼和/或調(diào)用基類
CSplitterWnd::OnDrawSplitter(pDC, nType, rect); //本來的畫分隔欄
if(pDC != NULL)
{
if(m_dcMem == NULL)
{
m_dcMem.CreateCompatibleDC(NULL); //CreateCompatibleDC參數(shù)為NULL表示創(chuàng)建一個(gè)與當(dāng)前顯示器兼容的DC
}
GetImgBtnRect();
pDC->BitBlt(m_rectImgBtn.left, m_rectImgBtn.top,
m_rectImgBtn.Width(), m_rectImgBtn.Height(),
&m_dcMem, 0, 0, SRCCOPY); //從m_dcMem中把圖片復(fù)制到pDC中并畫出來(大概是這個(gè)意思)
}
}
}
(5)重載OnLButtonUp函數(shù),使得點(diǎn)擊該“按鈕”時(shí)可以收起或者展開左欄
void CMySplitter::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
GetImgBtnRect();
if(m_rectImgBtn.PtInRect(point)) //如果鼠標(biāo)當(dāng)前是在“按鈕”區(qū)域內(nèi)
{
//這里判斷一下左欄是否收起了,如果是,隱藏左欄;不是則顯示左欄
//通過GetColumnInfo和SetColumnInfo
}
else
{
CSplitterWnd::OnLButtonUp(nFlags, point);
}
}
(6)重載OnMouseMove函數(shù),當(dāng)鼠標(biāo)移動(dòng)到“按鈕”上時(shí),把鼠標(biāo)形狀變成手形
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
GetImgBtnRect();
if(m_rectImgBtn.PtInRect(point))
{
::SetCursor(LoadCursor(NULL, IDC_HAND));
}
else
{
::SetCursor(LoadCursor(NULL, IDC_ARROW));
}
}
聯(lián)系客服