[MFC] splitter UI 바꾸기

C++ 2010. 12. 9. 00:37


미려하게 변경된 splitter UI




작성된 Splitter 클래스
(CWnd를 상속받는 MFC 클래스 생성후 CWnd를 CSplitterWnd로 직접 변경)

// SplitterWnd2.h
#pragma once

class CSplitterWnd2 : public CSplitterWnd
{
DECLARE_DYNAMIC(CSplitterWnd2)

public:
CSplitterWnd2();
virtual ~CSplitterWnd2();

protected:
DECLARE_MESSAGE_MAP()
public:
virtual void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rect);

public:
afx_msg void OnPaint();
};


// SplitterWnd2.cpp

#include "stdafx.h"
#include "DataManager.h"
#include "SplitterWnd2.h"

#define X_BORDER 1
#define Y_BORDER 1

IMPLEMENT_DYNAMIC(CSplitterWnd2, CSplitterWnd)
CSplitterWnd2::CSplitterWnd2(){}
CSplitterWnd2::~CSplitterWnd2(){}

BEGIN_MESSAGE_MAP(CSplitterWnd2, CSplitterWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()

//실제 splitter 를 그리는 함수 : OnDrawSplitter 를 오버라이딩하여 작성
void CSplitterWnd2::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rect)
{
// TODO: Add your specialized code here and/or call the base class
//작성
//pDC가 NULL 값이면 invalidate
if (!pDC)
{
RedrawWindow(rect, NULL, RDW_INVALIDATE | RDW_NOCHILDREN);
return;
}

CRect rec = rect; //rect가 상수이므로 수정을 위해서 객체 복사
ASSERT_VALID(pDC);
switch( nType )
{
case splitBorder:
pDC->Draw3dRect(rec, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_BTNFACE));
rec.InflateRect(-X_BORDER, -Y_BORDER);
pDC->Draw3dRect(rec, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
return;

case splitIntersection:
break;

case splitBox:
pDC->Draw3dRect(rec, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_WINDOWFRAME));
rec.InflateRect(-X_BORDER, -Y_BORDER);
pDC->Draw3dRect(rec, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
rec.InflateRect(-X_BORDER, -Y_BORDER);
break;
case splitBar:
break;

default:
ASSERT(FALSE);
}
pDC->FillSolidRect(rect, GetSysColor(COLOR_BTNFACE));

//CSplitterWnd::OnDrawSplitter(pDC, nType, rect);
}

void CSplitterWnd2::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here

//작성
CRect rcInside;
GetInsideRect(rcInside);
// extend split bars to window border (past margins)
DrawAllSplitBars(&dc, rcInside.right, rcInside.bottom);
}




splitter를 사용하는 뷰의 코드

CSplitterWnd2 m_wndSplitter;

void CXXXView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
if (m_wndSplitter.GetSafeHwnd())
{
int nCX = ::GetSystemMetrics(SM_CXEDGE);
int nCY = ::GetSystemMetrics(SM_CYEDGE);

m_wndSplitter.MoveWindow(-nCX, -nCY, cx+(nCX*2), cy+(nCY*2));
//m_wndSplitter.MoveWindow(0, 0, cx, cy);  //기본 형태
}
}

//Splitter 생성
int CXXXView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO:  Add your specialized creation code here
CCreateContext *pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
if (!m_wndSplitter.CreateStatic(this, 2, 1))
{
TRACE0("Failed to create splitter windows \n");
return FALSE;
}
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CXXXTOPView), CSize(0, 200), pContext) ||
!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CXXXBOTTOMView), CSize(0, 0), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
return 0;
}