본문 바로가기

Windows/MFC

CSplitterWnd - Multiple FormView

[code]// AW_CMultiViewSplitter.h: interface for the AW_CMultiViewSplitter class.
//
// Written by Caroline Englebienne of AniWorld, Inc.
// Copyright (c) 2000 AniWorld, Inc.
/////////////////////////////////////////////////////////////////////////////


#if !defined(AFX_AW_CMULTIVIEWSPLITTER_H__464C08E9_8989_11D4_B4E3_005004D85AA1__INCLUDED_)
#define AFX_AW_CMULTIVIEWSPLITTER_H__464C08E9_8989_11D4_B4E3_005004D85AA1__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning(disable:4786)
#include <map>
using namespace std;

class AW_CMultiViewSplitter : public CSplitterWnd
{

public:
    AW_CMultiViewSplitter();
    virtual ~AW_CMultiViewSplitter();
    int AddView(int nRow, int nCol, CRuntimeClass * pViewClass,
                CCreateContext* pContext);
    void ShowView(int nViewID);
    CWnd* GetView(int nViewID);

protected:
    map<int, long> m_mapViewPane;
    map<long, int> m_mapCurrentViews;
    map<int, CWnd*> m_mapIDViews;

    int m_nIDCounter;

    CWnd* GetCurrentView(int nRow, int nCol, int * nCurID);
    void SetCurrentView(int nRow, int nCol, int nViewID);
    int HideCurrentView(int nRow, int nCol);
    void GetPaneFromViewID(int nViewID, CPoint * pane);
public:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);    
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);

    void SetFreeze(bool bType);
    bool m_bType;
    void RedrawingToLeft(void);
    // Splitter의 border값을 수정할 수 있다.
    void SetBorder(int nSplitterGap, int nBorder);
};

#endif // !defined(AFX_AW_CMULTIVIEWSPLITTER_H__464C08E9_8989_11D4_B4E3_005004D85AA1__INCLUDED_)
[/code]

[code]
// AW_CMultiViewSplitter.cpp: implementation of the AW_CMultiViewSplitter class.
//
// Written by Caroline Englebienne of AniWorld, Inc.
// Copyright (c) 2000 AniWorld, Inc.
/////////////////////////////////////////////////////////////////////////////

//
// NOTE        : July 13, 2006
// Modifier : aucd29 (aucd29@gmail.com)
// URL        : http://www.sarangnmau.net
// --------------------------------------------------------------------------
// * SetFreeze(bool);
// 나뒤어진 Frame을 고정 시킬 수 있게 한다.
// * RedrawingToLeft(void);
// Border 가 0 일 때 발생하는 문제(이미지가 깨진다는 ... ) 해결
// * SetBorder(int, int);
// Border 값을 수정할 수 있다.
//
// * 추가될 사항이라면.. 아직은 깜박임이 보인다는 것... 이걸 해결해야 할 듯.


#include "stdafx.h"
#include "AW_CMultiViewSplitter.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

AW_CMultiViewSplitter::AW_CMultiViewSplitter()
: m_bType(false)
{
    m_nIDCounter = 1;
    //m_cxSplitter = m_cySplitter = 1;    
    //m_cxBorderShare = m_cyBorderShare = 0;

    m_cySplitterGap = m_cxSplitterGap = 1;
    m_cyBorder = m_cxBorder = 1;
}

AW_CMultiViewSplitter::~AW_CMultiViewSplitter()
{

}

int AW_CMultiViewSplitter::AddView(int nRow, int nCol, CRuntimeClass * pViewClass,
                                 CCreateContext* pContext)
{
    // hide the current view of the pane
    int PreviousID = HideCurrentView(nRow, nCol);

    // create the new view, if fail, set the previous view current
    if (CreateView(nRow, nCol, pViewClass, CSize(10,10), pContext) == 0)
    {
        if (PreviousID != -1)
            SetCurrentView(nRow, nCol, PreviousID);
        return -1;
    }

    // get and store the niew view
    int NewViewID = m_nIDCounter;
    CWnd* pNewWnd = GetPane(nRow, nCol);
    CPoint pane(nRow, nCol);
    long paneID = MAKELONG(pane.x,pane.y);
    m_mapViewPane.insert(map<int, long>::value_type(NewViewID,paneID));
    m_mapIDViews.insert(map<int, CWnd*>::value_type(NewViewID, pNewWnd));

    // set the new view current
    SetCurrentView(nRow, nCol, NewViewID);

    RedrawWindow();
    m_nIDCounter ++;
    return NewViewID;
}

void AW_CMultiViewSplitter::ShowView(int nViewID)
{
    if (GetView(nViewID) == NULL)
        return;

    // find the pane containing the view
    CPoint pane;
    GetPaneFromViewID(nViewID, &pane);

    // switch views
    HideCurrentView(pane.x, pane.y);
    SetCurrentView(pane.x, pane.y, nViewID);
    
    RedrawingToLeft();
    RecalcLayout();
}

CWnd* AW_CMultiViewSplitter::GetView(int nViewID)
{
    map<int, CWnd*>::iterator itView;

    itView = m_mapIDViews.find(nViewID);
    if(itView==m_mapIDViews.end())
        return NULL;
    else
        return (*itView).second;
}

CWnd* AW_CMultiViewSplitter::GetCurrentView(int nRow, int nCol, int * nCurID)
{
    long paneID = MAKELONG(nRow,nCol);
    
    map<long, int>::iterator itCur;
    itCur = m_mapCurrentViews.find(paneID);
    if (itCur == m_mapCurrentViews.end())
        return NULL;
    else
    {
        int PreviousID = (*itCur).second;
        *nCurID = PreviousID;
        return GetView(PreviousID);
    }
}

void AW_CMultiViewSplitter::SetCurrentView(int nRow, int nCol, int nViewID)
{
    long paneID = MAKELONG(nRow,nCol);

    map<long, int>::iterator itCur;
    itCur = m_mapCurrentViews.find(paneID);
    if (itCur != m_mapCurrentViews.end())
        (*itCur).second = nViewID;
    else
        m_mapCurrentViews.insert(map<long,int>::value_type(paneID,nViewID));

    CWnd * pView = GetView(nViewID);    
    pView->SetDlgCtrlID(IdFromRowCol(nRow, nCol));
    pView->ShowWindow(SW_SHOW);
}

int AW_CMultiViewSplitter::HideCurrentView(int nRow, int nCol)
{
    int prevID;
    CWnd * pCurView = GetCurrentView(nRow, nCol, &prevID);
    if (pCurView == NULL)
        return -1;
    else
    {
        pCurView->SetDlgCtrlID(0);
        pCurView->ShowWindow(SW_HIDE);    
        return prevID;
    }
}

void AW_CMultiViewSplitter::GetPaneFromViewID(int nViewID, CPoint * pane)
{
    map<int, long>::iterator itPane;
    itPane = m_mapViewPane.find(nViewID);
    if (itPane==m_mapViewPane.end())
    {
        pane = NULL;
        return;
    }
    long paneID = (*itPane).second;
    CPoint p(paneID);    
    pane->x = p.x;
    pane->y = p.y;
}

BEGIN_MESSAGE_MAP(AW_CMultiViewSplitter, CSplitterWnd)
    ON_WM_SETCURSOR()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

// Splitter 윈도우를 고정 시키기 위해서 아래와 같이 함수를 추가하였다.
// 설정은 SetFreeze로 하며 true일 경우 크기가 고정된다.
// 기본 값은 false이다.
BOOL AW_CMultiViewSplitter::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    if(m_bType)
        return (BOOL)Default();
    else
        return CSplitterWnd::OnSetCursor(pWnd, nHitTest, message);
}

void AW_CMultiViewSplitter::OnMouseMove(UINT nFlags, CPoint point)
{
    if(m_bType)
        Default();
    else
        CSplitterWnd::OnMouseMove(nFlags, point);
}

void AW_CMultiViewSplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
    if(m_bType)
        Default();
    else
        CSplitterWnd::OnLButtonDown(nFlags, point);
}

void AW_CMultiViewSplitter::SetFreeze(bool bType)
{
    m_bType = bType;
}

BOOL AW_CMultiViewSplitter::OnEraseBkgnd(CDC* pDC)
{
    //return true;
    return CSplitterWnd::OnEraseBkgnd(pDC);
}

// NOTE : July 13, 2006
// ------------------------------------------------------------------------
//
void AW_CMultiViewSplitter::RedrawingToLeft(void)
{
    CWnd* pView = GetPane(0, 0);

    pView->SetDlgCtrlID(IdFromRowCol(0, 0));
    pView->ShowWindow(SW_HIDE);
    pView->ShowWindow(SW_SHOW);
}

// Splitter의 border값을 수정할 수 있다.
void AW_CMultiViewSplitter::SetBorder(int nSplitterGap, int nBorder)
{
    m_cySplitterGap = m_cxSplitterGap = nSplitterGap;
    m_cyBorder = m_cxBorder = nBorder;
}
[/code]

'Windows > MFC' 카테고리의 다른 글

CSerial  (0) 2013.10.02
CSerial  (0) 2013.10.02
VS BUG FIX  (0) 2013.10.02
CEdit Auto Create Scrollbar, 자동으로 Scrollbar 생성, GetLineCount ShowScrollBar  (0) 2013.10.02
CDialog (Changing the background color of a dialog)  (0) 2013.10.02