左右分割と上下分割が切り替え可能なスプリッタウィンドウ (CFlippableSplitterWindow) [WTL]

(2007.05.15)
#pragma once
 
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
 
// '07.05.14 : コードの整備 (sha)
 
#include <atlsplit.h>
#include <atlmisc.h>
 
 
////////////////////////////////////////////////////////////////////////////////
// CFlippableSplitterWindowT
 
template <class TSplitterWindow, class THorSplitterWindow>
class CFlippableSplitterWindowT :
#if _MSC_VER < 1400
    public CWindowImpl<CFlippableSplitterWindowT>,
#else
    public CWindowImpl<CFlippableSplitterWindowT<TSplitterWindow, THorSplitterWindow> >
#endif
{
protected:
    typedef CFlippableSplitterWindowT                    thisCLass;
#if _MSC_VER < 1400
    typedef CWindowImpl<CFlippableSplitterWindowT>    baseClass;
#else
    typedef CWindowImpl<CFlippableSplitterWindowT<TSplitterWindow, THorSplitterWindow> >        baseClass;
#endif
 
public:
    CFlippableSplitterWindowT()
    {
        m_bVertical = true;
    }
 
BEGIN_MSG_MAP(CFlippableSplitterWindowT)
    MSG_WM_SIZE(OnSize)
    MSG_WM_ERASEBKGND(OnEraseBkgnd)
END_MSG_MAP()
 
// ハンドラ プロパティ:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
 
// Window Message Handlers
public:
    void OnSize(UINT nType, CSize size)
    {
        ATLASSERT(m_hWnd != NULL);
 
        if ((HWND)m_wndSplitterV != NULL)
        {
            m_wndSplitterV.ResizeClient(size.cx, size.cy);
        }
        if ((HWND)m_wndSplitterH != NULL)
        {
            m_wndSplitterH.ResizeClient(size.cx, size.cy);
        }
    }
    BOOL OnEraseBkgnd(CDCHandle dc)
    {
        // handled, no background painting needed
        return 1;
    }
 
public:
    HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
        DWORD dwStyle = 0, DWORD dwExStyle = 0,
        UINT nID = 0, LPVOID lpCreateParam = NULL)
    {
        baseClass::Create(hWndParent, rcPos, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, nID, lpCreateParam);
        if (m_hWnd == NULL)
        {
            return NULL;
        }
 
        dwStyle ^= WS_VISIBLE;
 
        m_wndSplitterV.Create(m_hWnd, rcPos, szWindowName, dwStyle, dwExStyle);
        m_wndSplitterV.SetSplitterExtendedStyle(0);
 
        m_wndSplitterH.Create(m_hWnd, rcPos, szWindowName, dwStyle, dwExStyle);
        m_wndSplitterH.SetSplitterExtendedStyle(0);
 
        return m_hWnd;
    }
 
public:
    void SetSplitterPanes(HWND hWndLeftTop, HWND hWndRightBottom, bool bUpdate = true)
    {
        CRect rcClient;
        this->GetClientRect(rcClient);
 
        if (m_bVertical)
        {
            m_wndSplitterH.ShowWindow(SW_HIDE);
            m_wndSplitterH.SetSplitterPanes(NULL, NULL, bUpdate);
 
            if (hWndLeftTop != NULL)
            {
                ::SetParent(hWndLeftTop, m_wndSplitterV);
            }
            if (hWndRightBottom != NULL)
            {
                ::SetParent(hWndRightBottom, m_wndSplitterV);
            }
 
            m_wndSplitterV.SetSplitterPanes(hWndLeftTop, hWndRightBottom, bUpdate);
            m_wndSplitterV.ShowWindow(SW_SHOW);
            m_wndSplitterV.ResizeClient(rcClient.Width(), rcClient.Height());
        }
        else
        {
            m_wndSplitterV.ShowWindow(SW_HIDE);
            m_wndSplitterV.SetSplitterPanes(NULL, NULL, bUpdate);
 
            if (hWndLeftTop != NULL)
            {
                ::SetParent(hWndLeftTop, m_wndSplitterH);
            }
            if (hWndRightBottom != NULL)
            {
                ::SetParent(hWndRightBottom, m_wndSplitterH);
            }
 
            m_wndSplitterH.SetSplitterPanes(hWndLeftTop, hWndRightBottom, bUpdate);
            m_wndSplitterH.ShowWindow(SW_SHOW);
            m_wndSplitterH.ResizeClient(rcClient.Width(), rcClient.Height());
        }
    }
 
public:
    bool IsVertical()
    {
        return m_bVertical;
    }
    void SetVertical(bool newVal)
    {
        if (m_bVertical == newVal)
        {
            return;
        }
 
        CRect rcClient;
        this->GetClientRect(rcClient);
 
        double fPercent = 0;
        HWND hWnd[2] = { NULL, NULL };
 
        if (m_bVertical)
        {
            hWnd[0] = m_wndSplitterV.m_hWndPane[0];
            hWnd[1] = m_wndSplitterV.m_hWndPane[1];
 
            if (rcClient.Width() != 0)
            {
                int nPos = m_wndSplitterV.GetSplitterPos();
                fPercent = double(nPos) / rcClient.Width();
            }
        }
        else
        {
            hWnd[0] = m_wndSplitterH.m_hWndPane[0];
            hWnd[1] = m_wndSplitterH.m_hWndPane[1];
 
            if (rcClient.Height() != 0)
            {
                int nPos = m_wndSplitterH.GetSplitterPos();
                fPercent = double(nPos) / rcClient.Height();
            }
        }
 
        m_bVertical = newVal;
 
        if (m_bVertical)
        {
            int nPos = int(fPercent * rcClient.Height());
            m_wndSplitterV.SetSplitterPos(nPos);
        }
        else
        {
            int nPos = int(fPercent * rcClient.Width());
            m_wndSplitterH.SetSplitterPos(nPos);
        }
 
        this->SetSplitterPanes(hWnd[0], hWnd[1]);
    }
    void SetSplitterPos(int newVal)
    {
        if (m_bVertical)
        {
            m_wndSplitterV.SetSplitterPos(newVal);
        }
        else
        {
            m_wndSplitterH.SetSplitterPos(newVal);
        }
    }
    int GetSplitterPos() const
    {
        int nResult = 0;
 
        if (m_bVertical)
        {
            nResult = m_wndSplitterV.GetSplitterPos();
        }
        else
        {
            nResult = m_wndSplitterH.GetSplitterPos();
        }
 
        return nResult;
    }
 
protected:
    bool m_bVertical;
    TSplitterWindow m_wndSplitterV;                // vertical splitter
    THorSplitterWindow m_wndSplitterH;            // horizontal splitter
};
 
 
////////////////////////////////////////////////////////////////////////////////
// CFlippableSplitterWindow
 
class CFlippableSplitterWindow : public CFlippableSplitterWindowT<CSplitterWindow, CHorSplitterWindow>
{
public:
    DECLARE_WND_CLASS_EX(_T("WTL_FlippableSplitterWindow"), CS_DBLCLKS, COLOR_WINDOW)
};
一覧に戻る
© 2003 WAC.com All Right Reserved.