金山界面库源码

bkwnddlg.h

#pragma once

#include "bkwndpanel.h"

class CBkDialog
    : public CBkPanel
{
    BKOBJ_DECLARE_CLASS_NAME(CBkDialog, "dlg")

public:

	void OnLButtonDown(UINT nFlags, CPoint point)
	{
		POSITION pos = m_lstWndChild.GetHeadPosition();

		while (pos != NULL)
		{
			CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

			if(pBkWndChild->IsClass("slider") )
			{
				pBkWndChild->BkSendMessage(WM_LBUTTONDOWN, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));
			}
		}
	}

	void OnLButtonUp(UINT nFlags, CPoint point)
	{
		POSITION pos = m_lstWndChild.GetHeadPosition();

		while (pos != NULL)
		{
			CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

			if(pBkWndChild->IsClass("slider"))
			{
				pBkWndChild->BkSendMessage(WM_LBUTTONUP, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));
			}
		}
	}


	void OnMouseLeave()
	{
		POSITION pos = m_lstWndChild.GetHeadPosition();

		while (pos != NULL)
		{
			CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

			if(pBkWndChild->IsClass("slider"))
			{
				pBkWndChild->BkSendMessage(WM_MOUSELEAVE, NULL, NULL);
			}
		}
	}


	void OnMouseMove(UINT nFlags, CPoint point)
	{
		POSITION pos = m_lstWndChild.GetHeadPosition();

		while (pos != NULL)
		{
			CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

			if(pBkWndChild->IsClass("slider"))
			{
				pBkWndChild->BkSendMessage(WM_MOUSEMOVE, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));
			}
		}
	}

	void OnLButtonDblClk(UINT nFlags, CPoint point)
	{
		POSITION pos = m_lstWndChild.GetHeadPosition();

		while (pos != NULL)
		{
			CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

			if(pBkWndChild->IsClass("slider"))
			{
				pBkWndChild->BkSendMessage(WM_LBUTTONDBLCLK, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));
			}
		}
	}

    void OnWindowPosChanged(LPWINDOWPOS lpWndPos)
    {
        CBkWindow::OnWindowPosChanged(lpWndPos);

        _RepositionChilds();
    }

    virtual BOOL Load(TiXmlElement* pTiXmlElem)
    {
        BOOL bRet = __super::Load(pTiXmlElem);

        return bRet;
    }

    virtual void RepositionChilds()
    {
        _RepositionChilds();
    }

    virtual void RepositionChild(CBkWindow *pBkWndChild)
    {
        BKDLG_POSITION dlgPos;
        WINDOWPOS WndPos = {0};
        CRect rcDlg = m_rcWindow;

        rcDlg.DeflateRect(m_style.m_nMarginX, m_style.m_nMarginY);

        pBkWndChild->GetDlgPosition(&dlgPos);

        if (dlgPos.Left.bCenter)
            WndPos.x = rcDlg.left + rcDlg.Width() / 2 + (dlgPos.Left.bMinus ? -1 : 1) *  dlgPos.Left.nPos;
        else if (dlgPos.Left.bMinus)
            WndPos.x = rcDlg.left + rcDlg.Width() - dlgPos.Left.nPos;
        else
            WndPos.x = rcDlg.left + dlgPos.Left.nPos;

        if (dlgPos.Top.bCenter)
            WndPos.y = rcDlg.top + rcDlg.Height() / 2 + (dlgPos.Top.bMinus ? -1 : 1) *  dlgPos.Top.nPos;
        else if (dlgPos.Top.bMinus)
            WndPos.y = rcDlg.top + rcDlg.Height() - dlgPos.Top.nPos;
        else
            WndPos.y = rcDlg.top + dlgPos.Top.nPos;

        WndPos.cx = rcDlg.Width();
        WndPos.cy = rcDlg.Height();
        pBkWndChild->BkSendMessage(WM_WINDOWPOSCHANGED, NULL, (LPARAM)&WndPos);
    }

protected:

    void _RepositionChilds()
    {
        POSITION pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            RepositionChild(pBkWndChild);
        }
    }

protected:

    BKWIN_BEGIN_MSG_MAP()
		MSG_WM_LBUTTONDOWN(OnLButtonDown)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_MOUSELEAVE(OnMouseLeave)
		MSG_WM_MOUSEMOVE(OnMouseMove)
        MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
    BKWIN_END_MSG_MAP()
};



bkwnddlgfile.h

#pragma once

#include "bkwnddlg.h"

/*
使用另外一个资源XML来加载子元素

<dlgfile src=16 />
*/
class CBkDialogFile
    : public CBkDialog
{
    BKOBJ_DECLARE_CLASS_NAME(CBkDialogFile, "dlgfile")

public:

    virtual BOOL Load(TiXmlElement* pTiXmlElem)
    {
		if (!CBkWindow::Load(pTiXmlElem))
			return FALSE;

		CStringA	strSrc = pTiXmlElem->Attribute("src");

		ATLASSERT( !strSrc.IsEmpty() );

		if (strSrc.IsEmpty())
			return FALSE;

		CStringA	strXML;
		UINT		uResId = atoi(strSrc);
		BOOL		bRet   = BkResManager::LoadResource(uResId,strXML);
		
		ATLASSERT(bRet);

		if (!bRet)
			return TRUE;

		TiXmlDocument xmlDoc;
		{
			xmlDoc.Parse(strXML, NULL, TIXML_ENCODING_UTF8);
		}
		if (xmlDoc.Error())
		{
			ATLASSERT(NULL);
			return FALSE;
		}

		TiXmlElement *pSubTiElement = xmlDoc.RootElement();
        bRet = __super::LoadChilds(pSubTiElement);

        return bRet;
    }

protected:

};

bkdlgview.h

//
//  Class Name: CBkDlgView
// Description: Dialog View, Real Container of BkWindow
//     Creator: ZhangXiaoxuan
//     Version: 2010.3.12 - 1.0 - Create
// modified by gaoyang in CBkDialogImpl::Load(UINT uResID) for adding m_richView.RepositionItems();
//

#pragma once

#include <atlconv.h>

#include "bkwndnotify.h"
#include "bkwndpanel.h"

///
// Classes in this file:
//
// BkWinManager
// CBkViewImpl
// CBkDialogViewTraits
// CBkDialogViewImpl
// CBkDialogView
// CBkDialogImpl
// CBkSimpleDialog

//
// BkWinManager

class BkWinManager
{
public:
    BkWinManager()
    {
        if (NULL == ms_mangager)
            ms_mangager = this;

        ::InitializeCriticalSection(&m_lockRepaint);
		::InitializeCriticalSection(&m_lockMapActive);
    }

    virtual ~BkWinManager()
    {
        if (this == ms_mangager)
            ms_mangager = NULL;

        ::DeleteCriticalSection(&m_lockRepaint);
		::DeleteCriticalSection(&m_lockMapActive);
   }

    static HWND SetActive(HWND hWnd)
    {
        HWND hWndLastActive = NULL;

        if (ms_mangager)
        {
            return ms_mangager->_SetActive(hWnd);
        }

        return hWndLastActive;
    }

    static HWND GetActive()
    {
        if (ms_mangager)
			return ms_mangager->_GetActive();

        return NULL;
    }

    static void EnterPaintLock()
    {
        if (ms_mangager)
            ::EnterCriticalSection(&(ms_mangager->m_lockRepaint));
    }

    static void LeavePaintLock()
    {
        if (ms_mangager)
            ::LeaveCriticalSection(&(ms_mangager->m_lockRepaint));
    }

protected:
	HWND _SetActive(HWND hWnd)
	{
		::EnterCriticalSection(&m_lockMapActive);

		HWND	hWndLastActive	= NULL;
		DWORD	nCurTID			= ::GetCurrentThreadId();

		CAtlMap<DWORD,HWND>::CPair*	 pairx = m_mapHwnd.Lookup( nCurTID );
		if (pairx)
		{
			hWndLastActive = pairx->m_value;
		}
		m_mapHwnd.SetAt(nCurTID,hWnd);

		::LeaveCriticalSection(&m_lockMapActive);

		return hWndLastActive;
	}

	HWND _GetActive()
	{
		::EnterCriticalSection(&m_lockMapActive);

		HWND	hWndAct = NULL;
		CAtlMap<DWORD,HWND>::CPair*	 pairx = m_mapHwnd.Lookup( ::GetCurrentThreadId() );
		if (pairx)
		{
			hWndAct = pairx->m_value;
		}
		::LeaveCriticalSection(&m_lockMapActive);
		return hWndAct;
	}

protected:
    static BkWinManager*	ms_mangager;

	CRITICAL_SECTION		m_lockMapActive;
	CAtlMap<DWORD,HWND>		m_mapHwnd;
    CRITICAL_SECTION		m_lockRepaint;
};

__declspec(selectany) BkWinManager* BkWinManager::ms_mangager = NULL;

//

template <class T>
class ATL_NO_VTABLE CBkViewImpl
{
public:

    BOOL SetRichText(UINT uItemID, UINT uResID)
    {
        CStringA strXml;
        BOOL bRet = BkResManager::LoadResource(uResID, strXml);
        if (!bRet)
            return FALSE;

        return SetRichText(uItemID, strXml);
    }

    BOOL SetRichText(UINT uItemID, LPCWSTR lpszXml)
    {
        CStringA strXml = CW2A(lpszXml, CP_UTF8);

        return SetRichText(uItemID, strXml);
    }

    BOOL SetRichText(UINT uItemID, LPCSTR lpszXml)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkRichText::GetClassName()))
            return FALSE;

        TiXmlDocument xmlDoc;

        { // Free stack
            CStringA strXml;
            strXml = L'<';
            strXml += CBkRichText::GetClassName();
            strXml += L'>';
            strXml += lpszXml;
            strXml += L'<';
            strXml += L'/';
            strXml += CBkRichText::GetClassName();
            strXml += L'>';
            xmlDoc.Parse(strXml, NULL, TIXML_ENCODING_UTF8);
        }

        if (xmlDoc.Error())
            return FALSE;

        CBkRichText *pWndRichText = (CBkRichText *)pWnd;
        pWndRichText->LoadChilds(xmlDoc.RootElement());

        pT->_InvalidateControl(pWnd);

        if (pWnd->IsVisible(TRUE))
            pWnd->BkSendMessage(WM_SHOWWINDOW, TRUE);

        return TRUE;
    }

	CString GetItemText(UINT uItemID)
	{
		T* pT = static_cast<T*>(this);
		CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

		if (pWnd)
			return 	pWnd->GetInnerText();

		return _T("");
	}

    BOOL SetItemText(UINT uItemID, LPCTSTR lpszText)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
        {
            pT->_InvalidateControl(pWnd);

			pWnd->TestMainThread();

			pWnd->SetInnerText(lpszText);

            pT->_InvalidateControl(pWnd);

            return TRUE;
        }

        return FALSE;
    }

    BOOL SetItemAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCSTR lpszValue)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
        {
            pT->_InvalidateControl(pWnd);

			pWnd->TestMainThread();

            pWnd->SetAttribute(lpszAttrib, lpszValue, FALSE);

            pT->_InvalidateControl(pWnd);

            return TRUE;
        }

        return FALSE;
    }

    BOOL SetItemStringAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCTSTR lpszValue)
    {
        return SetItemAttribute(uItemID, lpszAttrib, CT2A(lpszValue, CP_UTF8));
    }

    BOOL SetItemIntAttribute(UINT uItemID, LPCSTR lpszAttrib, int nValue)
    {
        CStringA strValue;
        strValue.Format("%d", nValue);

        return SetItemAttribute(uItemID, lpszAttrib, strValue);
    }

    BOOL SetItemDWordAttribute(UINT uItemID, LPCSTR lpszAttrib, DWORD dwValue)
    {
        CStringA strValue;
        strValue.Format("%u", dwValue);

        return SetItemAttribute(uItemID, lpszAttrib, strValue);
    }

	int GetSliderAttribute(UINT uItemID, LPCSTR lpszAttrib)
	{
		T* pT = static_cast<T*>(this);
		CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
		CBkSlider *pSlider = dynamic_cast<CBkSlider *>(pWnd); 
		int value = -1;
		if (pSlider)
		{
			value = pSlider->GetValue();
		}

		return value;
	}

    BOOL SetItemColorAttribute(UINT uItemID, LPCSTR lpszAttrib, COLORREF crValue)
    {
        CStringA strValue;
        strValue.Format("%02X%02X%02X", GetRValue(crValue), GetGValue(crValue), GetBValue(crValue));

        return SetItemAttribute(uItemID, lpszAttrib, strValue);
    }

    BOOL GetItemCheck(UINT uItemID)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
            return pWnd->IsChecked();

        return FALSE;
    }

    BOOL SetItemCheck(UINT uItemID, BOOL bCheck)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
        {
            if (bCheck)
                pWnd->ModifyState(BkWndState_Check, 0);
            else
                pWnd->ModifyState(0, BkWndState_Check);

            pT->_InvalidateControl(pWnd);

            return TRUE;
        }

        return FALSE;
    }

    BOOL EnableItem(UINT uItemID, BOOL bEnable)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
        {
            if (bEnable)
                pWnd->ModifyState(0, BkWndState_Disable);
            else
                pWnd->ModifyState(BkWndState_Disable, BkWndState_Hover);

            pT->_InvalidateControl(pWnd);

            return TRUE;
        }

        return FALSE;
    }

    BOOL IsItemEnable(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
            return !pWnd->IsDisabled(bCheckParent);

        return FALSE;
    }

    BOOL SetItemVisible(UINT uItemID, BOOL bVisible)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
        {
            pWnd->BkSendMessage(WM_SHOWWINDOW, (WPARAM)bVisible);

            pT->_InvalidateControl(pWnd, FALSE);

            return TRUE;
        }

        return FALSE;
    }

    BOOL IsItemVisible(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);

        if (pWnd)
            return pWnd->IsVisible(bCheckParent);

        return FALSE;
    }

    BOOL GetItemRect(UINT uItemID, RECT &rcItem)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        pWnd->GetRect(&rcItem);

        return TRUE;
    }

    BOOL SetTabCurSel(UINT uItemID, int nPage)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkTabCtrl::GetClassName()))
            return FALSE;

		pWnd->TestMainThread();

        BOOL bRet = ((CBkTabCtrl *)pWnd)->SetCurSel(nPage);

        return bRet;
    }

    BOOL SetTabTitle(UINT uItemID, int nPage, LPCTSTR lpszTitle)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkTabCtrl::GetClassName()))
            return FALSE;

		pWnd->TestMainThread();

        BOOL bRet = ((CBkTabCtrl *)pWnd)->SetTabTitle(nPage, lpszTitle);

        return bRet;
    }

    int GetTabCurSel(UINT uItemID)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return -1;

        if (!pWnd->IsClass(CBkTabCtrl::GetClassName()))
            return -1;

        return ((CBkTabCtrl *)pWnd)->GetCurSel();
    }

    BOOL IsTabPageVisible(UINT uItemID, int nPage)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkTabCtrl::GetClassName()))
            return FALSE;

        return ((CBkTabCtrl *)pWnd)->IsPageVisible(nPage);
    }

    BOOL SetTabPageVisible(UINT uItemID, int nPage, BOOL bVisible)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkTabCtrl::GetClassName()))
            return FALSE;

		pWnd->TestMainThread();

        ((CBkTabCtrl *)pWnd)->SetPageVisible(nPage, bVisible);

        return TRUE;
    }

    BOOL SetItemIconHandle(UINT uItemID, HICON hIcon)
    {
        T* pT = static_cast<T*>(this);
        CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkIconWnd::GetClassName()))
            return FALSE;

        ((CBkIconWnd *)pWnd)->AttachIcon(hIcon);

		pWnd->TestMainThread();

        pT->_InvalidateControl(pWnd);

        return TRUE;
    }

	BOOL SetItemPaintHook(UINT uItemID, IBkWindowPaintHook* pPaintHook)
	{
		T* pT = static_cast<T*>(this);
		CBkWindow *pWnd = pT->FindChildByCmdID(uItemID);
		if (!pWnd)
			return FALSE;

		pWnd->TestMainThread();

		pWnd->SetPaintHook(pPaintHook);

		return TRUE;
	}

    BOOL FormatRichText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return SetRichText(uItemID, strText);
    }

    BOOL FormatItemText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return SetItemText(uItemID, strText);
    }
};

// NOTICE: WS_TABSTOP needed for accept focus
//         WS_CLIPSIBLINGS may cause IE Control Redraw Error
typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_TABSTOP, 0> CBkDialogViewTraits;

//
// CBkDialogViewImpl

template <class T, class TBkWin = CBkDialog, class TBase = ATL::CWindow, class TWinTraits = CBkDialogViewTraits>
class ATL_NO_VTABLE CBkDialogViewImpl
    : public ATL::CWindowImpl<T, TBase, TWinTraits>
    , public CBkViewImpl<T>
{
    friend CBkViewImpl;

public:
    DECLARE_WND_CLASS_EX(NULL, CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, COLOR_WINDOW)

public:
    CBkDialogViewImpl()
        : m_hBkWndHover(NULL)
        , m_hBkWndPushDown(NULL)
        , m_bTrackFlag(FALSE)
        , m_bPushDownFlag(FALSE)
        , m_dwDlgStyle(0)
        , m_dwDlgExStyle(0)
        , m_bHasHeader(FALSE)
        , m_bHasBody(FALSE)
        , m_bHasFooter(FALSE)
        , m_bXmlLoaded(FALSE)
        , m_bCaptureSetted(FALSE)
        , m_bCanMaximize(FALSE)
        , m_bNeedRepaint(FALSE)
        , m_bNeedAllRepaint(TRUE)
    {
    }

    ~CBkDialogViewImpl()
    {
        m_bkHeader.BkSendMessage(WM_DESTROY);
        m_bkBody.BkSendMessage(WM_DESTROY);
        m_bkFooter.BkSendMessage(WM_DESTROY);
    }

protected:

    typedef ATL::CWindowImpl<T, TBase, TWinTraits>  __baseClass;
    typedef CBkDialogViewImpl<T, TBase, TWinTraits> __thisClass;

    TBkWin m_bkHeader;
    TBkWin m_bkBody;
    TBkWin m_bkFooter;

    // Double Cached
    CBkImage m_imgMem;

    // Only one hover control
    HBKWND m_hBkWndHover;
    // Only one pushdown control
    HBKWND m_hBkWndPushDown;

    // Tracking flag
    BOOL m_bTrackFlag;

    // Pushdown flag
    BOOL m_bPushDownFlag;

    BOOL m_bCaptureSetted;

    CString m_strWindowCaption;
    SIZE m_sizeDefault;

    DWORD m_dwDlgStyle;
    DWORD m_dwDlgExStyle;

    BOOL m_bHasHeader;
    BOOL m_bHasBody;
    BOOL m_bHasFooter;

    BOOL m_bCanMaximize;

    BOOL m_bXmlLoaded;
    BOOL m_bNeedRepaint;
    BOOL m_bNeedAllRepaint;

    CRgn m_rgnInvalidate;

public:
	CToolTipCtrl m_wndToolTip;

    HWND Create(
        HWND hWndParent, _U_RECT rect = NULL, DWORD dwStyle = 0, 
        DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
    {
        if (NULL != m_hWnd)
            return m_hWnd;

        HWND hWnd = __baseClass::Create(hWndParent, rect, m_strWindowCaption, dwStyle, dwExStyle, MenuOrID, lpCreateParam);

        if (hWnd)
        {
            m_bkHeader.SetContainer(m_hWnd);
            m_bkBody.SetContainer(m_hWnd);
            m_bkFooter.SetContainer(m_hWnd);

            m_wndToolTip.Create(hWnd);

            CToolInfo ti(0, hWnd);
            m_wndToolTip.AddTool(ti);
            m_wndToolTip.Activate(TRUE);

            if (!m_rgnInvalidate.IsNull())
                m_rgnInvalidate.DeleteObject();
        }

        return hWnd;
    };

    HWND Create(HWND hWndParent, _U_MENUorID MenuOrID)
    {
        return Create(hWndParent, NULL, 0, 0, MenuOrID, NULL);
    };

    BOOL Load(UINT uResID)
    {
        CStringA strXml;

        BOOL bRet = BkResManager::LoadResource(uResID, strXml);

        if (!bRet)
            return FALSE;

        return SetXml(strXml);
    }

    BOOL XmlLoaded()
    {
        return m_bXmlLoaded;
    }

    BOOL SetXml(LPCSTR lpszXml)
    {
        CStringA strValue;

        TiXmlDocument xmlDoc;

        m_bXmlLoaded    = FALSE;

        m_dwDlgStyle    = WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX | 0;
        m_dwDlgExStyle  = 0;

        m_bkHeader.BkSendMessage(WM_DESTROY);
        m_bkBody.BkSendMessage(WM_DESTROY);
        m_bkFooter.BkSendMessage(WM_DESTROY);

        m_bHasHeader    = FALSE;
        m_bHasBody      = FALSE;
        m_bHasFooter    = FALSE;

        { // Free stack
            xmlDoc.Parse(lpszXml, NULL, TIXML_ENCODING_UTF8);
        }

        if (xmlDoc.Error())
        {
            _Redraw();
            return FALSE;
        }

        TiXmlElement *pXmlRootElem = xmlDoc.RootElement();

        strValue = pXmlRootElem->Value();
        if (strValue != "layer")
        {
            _Redraw();
            return FALSE;
        }

        {
            m_strWindowCaption = CA2T(pXmlRootElem->Attribute("title"), CP_UTF8);
            m_sizeDefault.cx = 0;
            m_sizeDefault.cy = 0;
            pXmlRootElem->Attribute("width", (int *)&m_sizeDefault.cx);
            pXmlRootElem->Attribute("height", (int *)&m_sizeDefault.cy);

            BOOL bValue = FALSE;

            pXmlRootElem->Attribute("appwin", &bValue);
            if (bValue)
                m_dwDlgExStyle |= WS_EX_APPWINDOW;

            bValue = FALSE;

            pXmlRootElem->Attribute("resize", &bValue);

            if (bValue)
            {
                m_bCanMaximize = TRUE;
                m_dwDlgStyle |= WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;


				BOOL bValueT = FALSE;
				pXmlRootElem->Attribute("nomaxsize", &bValueT);

				if (bValueT)
				{
					m_bCanMaximize = FALSE;
					m_dwDlgStyle &= ~WS_MAXIMIZEBOX;
				}
// 				else
// 					m_bCanMaximize = TRUE;

            }
            else
                m_bCanMaximize = FALSE;

		
            bValue = FALSE;

            pXmlRootElem->Attribute("noborder", &bValue);

            if (bValue)
            {
                m_dwDlgExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
            }
            else
            {
                m_dwDlgExStyle |= WS_EX_OVERLAPPEDWINDOW;
            }

        }

        TiXmlElement *pTiElement = NULL;

        pTiElement = pXmlRootElem->FirstChildElement("header");
        m_bHasHeader = m_bkHeader.Load(pTiElement);
        if (m_bHasHeader)
        {
            CStringA strPos;
            int nHeight = 0;
            pTiElement->Attribute("height", &nHeight);
            strPos.Format("0,0,-0,%d", nHeight);
            m_bkHeader.SetAttribute("pos", strPos, TRUE);
        }

        pTiElement = pXmlRootElem->FirstChildElement("footer");
        m_bHasFooter = m_bkFooter.Load(pTiElement);
        if (m_bHasFooter)
        {
            CStringA strPos;
            int nHeight = 0;
            pTiElement->Attribute("height", &nHeight);
            strPos.Format("0,-%d,-0,-0", nHeight);
            m_bkFooter.SetAttribute("pos", strPos, TRUE);
        }

        m_bHasBody = m_bkBody.Load(pXmlRootElem->FirstChildElement("body"));
        if (m_bHasBody)
        {
            m_bkBody.SetAttribute("pos", "0,0,-0,-0", TRUE);
        }

        m_bXmlLoaded = TRUE;

        if (!m_hWnd)
            return TRUE;

        _Redraw();

        m_hBkWndHover = NULL;
        m_hBkWndPushDown = NULL;

        return TRUE;
    }

    LPCTSTR GetWindowCaption()
    {
        return m_strWindowCaption;
    }

    void SetWindowCaption(LPCTSTR lpszCaption)
    {
        m_strWindowCaption = lpszCaption;
    }

    SIZE GetDefaultSize()
    {
        return m_sizeDefault;
    }

    DWORD GetDlgStyle()
    {
        return m_dwDlgStyle;
    }

    DWORD GetDlgExStyle()
    {
        return m_dwDlgExStyle;
    }

    void ShowAllRealWindows(BOOL bShow)
    {
        if (m_bHasHeader)
            m_bkHeader.ShowAllRealWindowChilds(bShow);
        if (m_bHasFooter)
            m_bkFooter.ShowAllRealWindowChilds(bShow);
        if (m_bHasBody)
            m_bkBody.ShowAllRealWindowChilds(bShow);
    }

    void RecomposeItems(BOOL bRedraw)
    {

    }

    void Redraw()
    {

    }

    CBkWindow* FindChildByCmdID(UINT uCmdID)
    {
        CBkWindow *pWnd = NULL;

        pWnd = m_bkHeader.FindChildByCmdID(uCmdID);
        if (pWnd)
            return pWnd;

        pWnd = m_bkBody.FindChildByCmdID(uCmdID);
        if (pWnd)
            return pWnd;

        pWnd = m_bkFooter.FindChildByCmdID(uCmdID);

        return pWnd;
    }

    BOOL SetPanelXml(UINT uItemID, UINT uResID)
    {
        CStringA strXml;
        BOOL bRet = BkResManager::LoadResource(uResID, strXml);
        if (!bRet)
            return FALSE;

        return SetPanelXml(uItemID, strXml);
    }

    BOOL SetPanelXml(UINT uItemID, LPCSTR lpszXml)
    {
        TiXmlDocument xmlDoc;

        { // Free stack
            xmlDoc.Parse(lpszXml, NULL, TIXML_ENCODING_UTF8);
        }

        if (xmlDoc.Error())
            return FALSE;

        CBkWindow *pWnd = FindChildByCmdID(uItemID);

        if (!pWnd)
            return FALSE;

        if (!pWnd->IsClass(CBkDialog::GetClassName()) && 
			!pWnd->IsClass(CBkPanel::GetClassName()) && 
			!pWnd->IsClass(CBkTab::GetClassName()) &&
			!pWnd->IsClass(CBkDialogFile::GetClassName()))
            return FALSE;

        TiXmlElement *pXmlRootElem = xmlDoc.RootElement();

        CBkPanel *pWndPanel = (CBkPanel *)pWnd;

        pWndPanel->LoadChilds(pXmlRootElem);
        pWndPanel->RepositionChilds();

        _InvalidateControl(pWnd);

        if (pWnd->IsVisible(TRUE))
            pWnd->BkSendMessage(WM_SHOWWINDOW, TRUE);

        return TRUE;
    }

	void RepositionItems(BOOL bRedraw = TRUE)
	{
		_RepositionItems(bRedraw);
	}

protected:

    void _Redraw()
    {
        m_bNeedAllRepaint = TRUE;
        m_bNeedRepaint = TRUE;
        if (!m_rgnInvalidate.IsNull())
            m_rgnInvalidate.DeleteObject();

        Invalidate(FALSE);
    }

    void _RepositionItems(BOOL bRedraw = TRUE)
    {
        CRect rcClient, rcHeader, rcFooter, rcBody;

        if (!m_hWnd)
            return;

        GetClientRect(rcClient);

        if (rcClient.Width() == 0)
            return;

        WINDOWPOS WndPos = { 0, 0, rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), SWP_SHOWWINDOW };

        if (m_bHasHeader)
        {
            m_bkHeader.BkSendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&WndPos);
            m_bkHeader.GetRect(rcHeader);
        }

        if (m_bHasFooter)
        {
            m_bkFooter.BkSendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&WndPos);
            m_bkFooter.GetRect(rcFooter);

            WndPos.y = rcClient.bottom - rcFooter.Height();
            WndPos.cy = rcFooter.Height();
            m_bkFooter.BkSendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&WndPos);
        }

        if (m_bHasBody)
        {
            WndPos.y = rcHeader.bottom;
            WndPos.cy = rcClient.bottom - rcFooter.Height() - rcHeader.bottom;

            m_bkBody.BkSendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&WndPos);
        }

        _Redraw();
    }

    void _ModifyWndState(CBkWindow *pWnd, DWORD dwStateAdd, DWORD dwStateRemove)
    {
        pWnd->ModifyState(dwStateAdd, dwStateRemove);
        if (pWnd->NeedRedrawWhenStateChange())
            _InvalidateControl(pWnd);
    }

    void _InvalidateControl(CBkWindow *pWnd, BOOL bCheckVisible = TRUE)
    {
        if (!bCheckVisible || pWnd->IsVisible(TRUE))
        {
            CRect rcInvalidate;

            pWnd->GetRect(rcInvalidate);
            _InvalidateRect(rcInvalidate);
        }
    }

    void _InvalidateRect(CRect& rcInvalidate)
    {
        if (m_rgnInvalidate.IsNull())
        {
            m_rgnInvalidate.CreateRectRgnIndirect(rcInvalidate);
        }
        else
        {
            CRgn rgnInvalidate;

            rgnInvalidate.CreateRectRgnIndirect(rcInvalidate);

            m_rgnInvalidate.CombineRgn(rgnInvalidate, RGN_OR);
        }

        if (IsWindow())
            InvalidateRect(rcInvalidate, FALSE);

        m_bNeedRepaint = TRUE;
    }

    //
    // Message handler

    void OnPrint(CDCHandle dc, UINT uFlags)
    {
        if (m_bNeedAllRepaint)
        {
            if (!m_rgnInvalidate.IsNull())
                m_rgnInvalidate.DeleteObject();

            m_bNeedAllRepaint = FALSE;
        }

        if (m_bNeedRepaint)
        {
            BkWinManager::EnterPaintLock();

            CDC dcMem;
            CDCHandle dcMemHandle;
            HDC hDCDesktop = ::GetDC(NULL);
            dcMem.CreateCompatibleDC(hDCDesktop);
            ::ReleaseDC(NULL, hDCDesktop);
            HBITMAP hbmpOld = dcMem.SelectBitmap(m_imgMem);

            HFONT hftOld = dcMem.SelectFont(BkFontPool::GetFont(BKF_DEFAULTFONT));

            dcMem.SetBkMode(TRANSPARENT);

            if (!m_rgnInvalidate.IsNull())
                dcMem.SelectClipRgn(m_rgnInvalidate);

            dcMemHandle.Attach(dcMem);

            if (m_bHasHeader)
                m_bkHeader.RedrawRegion(dcMemHandle, m_rgnInvalidate);
            if (m_bHasBody)
                m_bkBody.RedrawRegion(dcMemHandle, m_rgnInvalidate);
            if (m_bHasFooter)
                m_bkFooter.RedrawRegion(dcMemHandle, m_rgnInvalidate);

            dcMemHandle.Detach();

            if (!m_rgnInvalidate.IsNull())
                m_rgnInvalidate.DeleteObject();

            dcMem.SelectFont(hftOld);
            dcMem.SelectBitmap(hbmpOld);

            BkWinManager::LeavePaintLock();

            m_bNeedRepaint = FALSE;
        }

        m_imgMem.Draw(dc, 0, 0);
    }

    void OnPaint(CDCHandle dc)
    {
        CPaintDC dcPaint(m_hWnd);

        OnPrint((HDC)dcPaint, 0);
    }

    BOOL OnEraseBkgnd(CDCHandle dc)
    {
        return TRUE;
    }

    void OnDestroy()
    {
        if (m_imgMem.M_HOBJECT)
            m_imgMem.DeleteObject();
    }

    void OnSize(UINT nType, CSize size)
    {
        if (m_imgMem.M_HOBJECT)
            m_imgMem.DeleteObject();

        CRect rcClient;

        GetClientRect(rcClient);

        if (0 == rcClient.Width())
            return;

        m_imgMem.CreateBitmap(rcClient.Width(), rcClient.Height(), RGB(0, 0, 0));

        _RepositionItems();
    }

    void OnMouseMove(UINT nFlags, CPoint point)
    {
		//ATLTRACE(L"b1?\r\n");
		::SendMessage(GetParent(),WM_MOUSEMOVE,0,MAKELONG(point.x,point.y));

        if (!m_bTrackFlag)
        {
            TRACKMOUSEEVENT tme;
            tme.cbSize = sizeof(tme);
            tme.hwndTrack = m_hWnd;
            tme.dwFlags = TME_LEAVE;
            tme.dwHoverTime = 0;
            m_bTrackFlag = _TrackMouseEvent(&tme);

            {
                NMHDR nms;
                nms.code = BKNM_MOUSEHOVER;
                nms.hwndFrom = m_hWnd;
                nms.idFrom = GetDlgCtrlID();
                ::SendMessage(GetParent(), WM_NOTIFY, (LPARAM)nms.idFrom, (WPARAM)&nms);
            }
        }

        HBKWND hBkWndHitTest = NULL;

        hBkWndHitTest = m_bkHeader.BkGetHWNDFromPoint(point, TRUE);
        if (NULL == hBkWndHitTest)
            hBkWndHitTest = m_bkBody.BkGetHWNDFromPoint(point, TRUE);
        if (NULL == hBkWndHitTest)
            hBkWndHitTest = m_bkFooter.BkGetHWNDFromPoint(point, TRUE);

        CBkWindow* pWndHover = BkWnds::GetWindow(hBkWndHitTest);

        if (pWndHover)
        {
            BOOL bDisabled = pWndHover->IsDisabled(TRUE);
            if (!bDisabled)
                pWndHover->BkSendMessage(WM_MOUSEMOVE, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));

            if (hBkWndHitTest != m_hBkWndHover)
            {
                CRect rcInvalidate;

                if (NULL != m_hBkWndHover)
                {
                    CBkWindow* pWndHoverOld = BkWnds::GetWindow(m_hBkWndHover);
                    
                    if (pWndHoverOld && !pWndHoverOld->IsDisabled(TRUE))
                    {
                        _ModifyWndState(pWndHoverOld, 0, BkWndState_Hover);
                        pWndHoverOld->BkSendMessage(WM_MOUSELEAVE);
                    }
                }

                if (!bDisabled)
                    _ModifyWndState(pWndHover, BkWndState_Hover, 0);

                m_hBkWndHover = hBkWndHitTest;

                if (pWndHover)
					m_wndToolTip.UpdateTipText(pWndHover->GetToolTipText(), m_hWnd);
            }
        }
    }

    void OnMouseLeave()
    {
        m_bTrackFlag = FALSE;

        if (m_hBkWndHover)
        {
            CBkWindow* pWndHover = BkWnds::GetWindow(m_hBkWndHover);
            if (pWndHover)
            {
                _ModifyWndState(pWndHover, 0, BkWndState_Hover);
                pWndHover->BkSendMessage(WM_MOUSELEAVE);
            }

            m_hBkWndHover = NULL;
        }

        if (m_hBkWndPushDown)
        {
            CBkWindow* pWndPushdown = BkWnds::GetWindow(m_hBkWndPushDown);
            if (pWndPushdown)
                _ModifyWndState(pWndPushdown, 0, BkWndState_PushDown);

            m_hBkWndPushDown = NULL;
        }

        {
            NMHDR nms;
            nms.code = BKNM_MOUSELEAVE;
            nms.hwndFrom = m_hWnd;
            nms.idFrom = GetDlgCtrlID();
            ::SendMessage(GetParent(), WM_NOTIFY, (LPARAM)nms.idFrom, (WPARAM)&nms);
        }
    }

    void OnLButtonDown(UINT nFlags, CPoint point)
    {
        HBKWND hBkWndHitTest = m_bkHeader.BkGetHWNDFromPoint(point, TRUE);

        if (hBkWndHitTest)
        {
            CBkWindow* pWndPushDown = BkWnds::GetWindow(hBkWndHitTest);

            if (!(pWndPushDown->IsClass("button") || pWndPushDown->IsClass("imgbtn") || pWndPushDown->IsClass("link")))
            {
                CWindow &wndParent = GetParent();

                if (0 == (wndParent.GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)))
                    wndParent.SendMessage(WM_SYSCOMMAND, SC_MOVE | HTCAPTION);

                return;
            }
        }

        if (NULL == hBkWndHitTest)
            hBkWndHitTest = m_bkBody.BkGetHWNDFromPoint(point, TRUE);
        if (NULL == hBkWndHitTest)
            hBkWndHitTest = m_bkFooter.BkGetHWNDFromPoint(point, TRUE);

        CBkWindow* pWndPushDown = BkWnds::GetWindow(hBkWndHitTest);

        if (pWndPushDown)
        {
            if (pWndPushDown->IsDisabled(TRUE))
                return;

            if (!m_bCaptureSetted)
            {
                SetCapture();
                m_bCaptureSetted = TRUE;

                if (hBkWndHitTest != m_hBkWndHover)
                {
                    // Hover和Pushdown不同的原因是:鼠标一直没动,界面刷新,切换了鼠标所在位置的控件
                    //ATLASSERT(FALSE);
                    m_hBkWndHover = hBkWndHitTest;
                }

                m_hBkWndPushDown = hBkWndHitTest;

                _ModifyWndState(pWndPushDown, BkWndState_PushDown, 0);
                pWndPushDown->BkSendMessage(WM_LBUTTONDOWN, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));
            }
        }
    }

    void OnLButtonUp(UINT nFlags, CPoint point)
    {
        BOOL bNotifyClick = FALSE;
        UINT uCmdID = 0;
        CBkWindow* pWndClick = NULL;

        if (m_bCaptureSetted)
        {
            ReleaseCapture();
            m_bCaptureSetted = FALSE;
        }

        if (m_hBkWndPushDown)
        {
            pWndClick = BkWnds::GetWindow(m_hBkWndPushDown);

            if (pWndClick)
            {
                _ModifyWndState(pWndClick, 0, BkWndState_PushDown);

                if (m_hBkWndPushDown == m_hBkWndHover)
                {
                    pWndClick->BkSendMessage(WM_LBUTTONUP, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));

                    LPCTSTR lpszUrl = pWndClick->GetLinkUrl();
                    if (lpszUrl && lpszUrl[0])
                    {
                        HINSTANCE hRet = ::ShellExecute(NULL, L"open", lpszUrl, NULL, NULL, SW_SHOWNORMAL);
                    }
                    else if (pWndClick->GetCmdID())
                    {
                        bNotifyClick = TRUE;
                        uCmdID = pWndClick->GetCmdID();
                    }
                }
				else if(pWndClick->IsClass("slider"))
				{
					pWndClick->BkSendMessage(WM_LBUTTONUP, (WPARAM)nFlags, MAKELPARAM(point.x, point.y));

					LPCTSTR lpszUrl = pWndClick->GetLinkUrl();
					if (lpszUrl && lpszUrl[0])
					{
						HINSTANCE hRet = ::ShellExecute(NULL, _T("open"), lpszUrl, NULL, NULL, SW_SHOWNORMAL);
					}
					else if (pWndClick->GetCmdID())
					{
						bNotifyClick = TRUE;
						uCmdID = pWndClick->GetCmdID();
					}
				}
            }

            m_hBkWndPushDown = NULL;
        }

        if (bNotifyClick)
        {
            BKNMCOMMAND nms;
            nms.hdr.code = BKNM_COMMAND;
            nms.hdr.hwndFrom = m_hWnd;
            nms.hdr.idFrom = GetDlgCtrlID();
            nms.uItemID = uCmdID;
            nms.szItemClass = pWndClick->GetObjectClass();

            LRESULT lRet = ::SendMessage(GetParent(), WM_NOTIFY, (LPARAM)nms.hdr.idFrom, (WPARAM)&nms);
        }
    }

    void OnLButtonDblClk(UINT nFlags, CPoint point)
    {
        HBKWND hBkWndHitTest = m_bkHeader.BkGetHWNDFromPoint(point, TRUE);

        if (hBkWndHitTest)
        {
            CBkWindow* pWndPushDown = BkWnds::GetWindow(hBkWndHitTest);

            if (!(pWndPushDown->IsClass("button") || pWndPushDown->IsClass("imgbtn") || pWndPushDown->IsClass("link")))
            {
                if (m_bCanMaximize)
                {
                    CWindow &wndParent = GetParent();
                    DWORD dwStyle = wndParent.GetStyle();

                    if (WS_MAXIMIZE == (dwStyle & WS_MAXIMIZE))
                        wndParent.SendMessage(WM_SYSCOMMAND, SC_RESTORE | HTCAPTION);
                    else
                        wndParent.SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE | HTCAPTION);
                }

                return;
            }
        }
    }

    BOOL OnSetCursor(CWindow /*wnd*/, UINT nHitTest, UINT message)
    {
        if (m_hBkWndHover)
        {
            CBkWindow *pBkWndHover = BkWnds::GetWindow(m_hBkWndHover);

            if (pBkWndHover && !pBkWndHover->IsDisabled(TRUE))
            {
                pBkWndHover->SetCursor();
                return TRUE;
            }
        }

        ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));

        return TRUE;
    }

    BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
    {
        return FALSE;
    }

    LRESULT OnChildNotify(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        return ::SendMessage(::GetParent(m_hWnd), uMsg, wParam, lParam);
    }

    LRESULT OnToolTipEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        if(m_wndToolTip.IsWindow())
        {
            MSG msg = { m_hWnd, uMsg, wParam, lParam };

            m_wndToolTip.RelayEvent(&msg);
        }

        SetMsgHandled(FALSE);

        return 0;
    }

    LRESULT OnBKINMInvalidateRect(LPNMHDR pnmh)
    {
        LPBKINMINVALIDATERECT pnms = (LPBKINMINVALIDATERECT)pnmh;
        CRect rcWnd = pnms->rect;

        _InvalidateRect(rcWnd);

        return 0;
    }

protected:
    BEGIN_MSG_MAP_EX(CBkDialogViewImpl)
        MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnToolTipEvent)
        MSG_WM_SIZE(OnSize)
        MSG_WM_PRINT(OnPrint)
        MSG_WM_PAINT(OnPaint)
        MSG_WM_DESTROY(OnDestroy)
        MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_MOUSEMOVE(OnMouseMove)
        MSG_WM_MOUSELEAVE(OnMouseLeave)
        MSG_WM_LBUTTONDOWN(OnLButtonDown)
        MSG_WM_LBUTTONUP(OnLButtonUp)
        MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
        MSG_WM_SETCURSOR(OnSetCursor)
        MSG_WM_MOUSEWHEEL(OnMouseWheel)
        NOTIFY_CODE_HANDLER_EX(BKINM_INVALIDATERECT, OnBKINMInvalidateRect)
        REFLECT_NOTIFY_CODE(NM_CUSTOMDRAW)
        MESSAGE_HANDLER_EX(WM_NOTIFY, OnChildNotify)
        MESSAGE_HANDLER_EX(WM_COMMAND, OnChildNotify)
        MESSAGE_HANDLER_EX(WM_VSCROLL, OnChildNotify)
        MESSAGE_HANDLER_EX(WM_HSCROLL, OnChildNotify)
        REFLECT_NOTIFICATIONS_EX()
    END_MSG_MAP()
};

//
// CBkDialogView

class CBkDialogView
    : public CBkDialogViewImpl<CBkDialogView>
{
};

//
// Default view control id in CBkDialogImpl

#define IDC_RICHVIEW_WIN            1000
#define TIMER_ID_MOTHON_DIALOG		2000

//
// CBkDialogImpl

template <class T, class TBkView = CBkDialogView, class TBase = CWindow, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CBkDialogImpl : public CWindowImpl<T, TBase, TWinTraits>
{
public:

    static BOOL IsWinXPAndLater()
    {
        DWORD dwVersion = GetVersion();
        DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
        DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));

        if (dwMajorVersion > 5)         // Vista and later
            return TRUE;
        else if (dwMajorVersion < 5)    // 98/NT4 and before
            return FALSE;
        else if (dwMinorVersion > 0)    // XP and 2003
            return TRUE;
        else                            // 2000
            return FALSE;
    }

    static ATL::CWndClassInfo& GetWndClassInfo()
    {
        static ATL::CWndClassInfo wc = {
                { sizeof(WNDCLASSEX), 
                CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | (IsWinXPAndLater() ? CS_DROPSHADOW : 0), 
                  StartWindowProc, 0, 0, NULL, NULL, NULL, 
                  (HBRUSH)(COLOR_WINDOW + 1), NULL, NULL, NULL },
                NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
            };
        return wc;
    }

public:
    CBkDialogImpl(UINT uResID = 0)
        : m_uResID(uResID)
        , m_bShowWindow(TRUE)
        , m_bExitModalLoop(FALSE)
		, m_nAlpha(0)
		, m_nAlphaIncrement(20)
    {
    }
    virtual ~CBkDialogImpl()
    {

    }

protected:
    typedef CBkDialogImpl<T, TBkView, TBase, TWinTraits> __thisClass;

    UINT m_uResID;
    UINT m_uRetCode;

    TBkView m_richView;

    BOOL m_bShowWindow;

	int m_nAlpha;

	int m_nAlphaIncrement;

    void ResizeClient(SIZE sizeClient, BOOL bRedraw)
    {
        ResizeClient(sizeClient.cx, sizeClient.cy, bRedraw);
    }

    void ResizeClient(int cx, int cy, BOOL bRedraw)
    {
        CRect rcWindow, rcClient;
        CPoint ptWindow;

        GetWindowRect(rcWindow);
        GetClientRect(rcClient);

        ptWindow = rcWindow.TopLeft();

        rcWindow.MoveToXY(0, 0);

        rcWindow -= rcClient;
        rcClient.SetRect(0, 0, cx, cy);
        rcWindow += rcClient;

        rcWindow.MoveToXY(ptWindow);

        MoveWindow(rcWindow, bRedraw);
    }

    void OnSize(UINT nType, CSize size)
    {
        CRect rcClient;

        GetClientRect(rcClient);

        if (SIZE_MINIMIZED != nType)
        {
            if (m_richView.m_hWnd)
                m_richView.MoveWindow(rcClient);

        }

        SetMsgHandled(FALSE);
    }

    BOOL OnEraseBkgnd(CDCHandle dc)
    {
        return TRUE;
    }

    LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
    {
        if (bCalcValidRects)
        {
            CRect rcWindow;

            GetWindowRect(rcWindow);

            LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam;

            if (SWP_NOSIZE == (SWP_NOSIZE & pParam->lppos->flags))
                return 0;

            if (0 == (SWP_NOMOVE & pParam->lppos->flags))
            {
                rcWindow.left = pParam->lppos->x;
                rcWindow.top = pParam->lppos->y;
            }

            rcWindow.right = rcWindow.left + pParam->lppos->cx;
            rcWindow.bottom = rcWindow.top + pParam->lppos->cy;
            pParam->rgrc[0] = rcWindow;
            pParam->rgrc[1] = pParam->rgrc[0];
        }

        return 0;
    }

    void OnGetMinMaxInfo(LPMINMAXINFO lpMMI)
    {
        HMONITOR hMonitor = ::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONULL);

        if (hMonitor)
        {
            MONITORINFO mi = {sizeof(MONITORINFO)};
            ::GetMonitorInfo(hMonitor, &mi);

            CRect rcWork = mi.rcWork, rcMonitor = mi.rcMonitor;
            lpMMI->ptMaxPosition.x = abs(rcWork.left - rcMonitor.left) - 1;
            lpMMI->ptMaxPosition.y = abs(rcWork.top - rcMonitor.top) - 1;
            lpMMI->ptMaxSize.x = abs(rcWork.Width()) + 2;
            lpMMI->ptMaxSize.y = abs(rcWork.Height()) + 2;
            lpMMI->ptMaxTrackSize.x = abs(rcWork.Width()) + 2;
            lpMMI->ptMaxTrackSize.y = abs(rcWork.Height()) + 2;
        }
    }

    BOOL OnNcActivate(BOOL bActive)
    {
        return TRUE;
    }

public:

    BOOL Load(UINT uResID)
    {
        CStringA strXml;

        BOOL bRet = BkResManager::LoadResource(uResID, strXml);

        if (!bRet)
            return FALSE;

       BOOL bOk = SetXml(strXml);
        //add by gy
        m_richView.RepositionItems();
        return bOk;
    }

    BOOL SetXml(LPCSTR lpszXml)
    {
        return m_richView.SetXml(lpszXml);
    }

    HWND GetViewHWND()
    {
        return m_richView.m_hWnd;
    }

    BOOL SetPanelXml(UINT uItemID, UINT uResID)
    {
        return m_richView.SetPanelXml(uItemID, uResID);
    }

    BOOL SetPanelXml(UINT uItemID, LPCSTR lpszXml)
    {
        return m_richView.SetPanelXml(uItemID, lpszXml);
    }

    BOOL SetRichText(UINT uItemID, UINT uResID)
    {
        return m_richView.SetRichText(uItemID, uResID);
    }

    BOOL FormatRichText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return m_richView.SetRichText(uItemID, strText);
    }

    BOOL SetRichText(UINT uItemID, LPCWSTR lpszXml)
    {
        return m_richView.SetRichText(uItemID, lpszXml);
    }

    BOOL SetRichText(UINT uItemID, LPCSTR lpszXml)
    {
        return m_richView.SetRichText(uItemID, lpszXml);
    }

    BOOL SetItemText(UINT uItemID, LPCTSTR lpszText)
    {
        return m_richView.SetItemText(uItemID, lpszText);
    }

	CString GetItemText(UINT uItemID)
	{
		return m_richView.GetItemText(uItemID);
	}

    BOOL FormatItemText(UINT uItemID, LPCTSTR lpszFormat, ...)
    {
        va_list args;
        CString strText;

        va_start(args, lpszFormat);

        strText.FormatV(lpszFormat, args);

        return m_richView.SetItemText(uItemID, strText);
    }

    BOOL SetItemAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCSTR lpszValue)
    {
        return m_richView.SetItemAttribute(uItemID, lpszAttrib, lpszValue);
    }

    BOOL GetItemRect(UINT uItemID, RECT &rcItem)
    {
        return m_richView.GetItemRect(uItemID, rcItem);
    }

    BOOL SetItemStringAttribute(UINT uItemID, LPCSTR lpszAttrib, LPCTSTR lpszValue)
    {
        return m_richView.SetItemStringAttribute(uItemID, lpszAttrib, lpszValue);
    }

    BOOL SetItemIntAttribute(UINT uItemID, LPCSTR lpszAttrib, int nValue)
    {
        return m_richView.SetItemIntAttribute(uItemID, lpszAttrib, nValue);
    }

	INT	GetSliderAttribute(UINT uItemID, LPCSTR lpszAttrib)
	{
		 return m_richView.GetSliderAttribute(uItemID, lpszAttrib);
	}

    BOOL SetItemDWordAttribute(UINT uItemID, LPCSTR lpszAttrib, DWORD dwValue)
    {
        return m_richView.SetItemDWordAttribute(uItemID, lpszAttrib, dwValue);
    }

    BOOL SetItemColorAttribute(UINT uItemID, LPCSTR lpszAttrib, COLORREF crValue)
    {
        return m_richView.SetItemColorAttribute(uItemID, lpszAttrib, crValue);
    }

    BOOL GetItemCheck(UINT uItemID)
    {
        return m_richView.GetItemCheck(uItemID);
    }

    BOOL SetItemCheck(UINT uItemID, BOOL bCheck)
    {
        return m_richView.SetItemCheck(uItemID, bCheck);
    }

    BOOL IsItemEnable(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        return m_richView.IsItemEnable(uItemID, bCheckParent);
    }

    BOOL EnableItem(UINT uItemID, BOOL bEnable)
    {
        return m_richView.EnableItem(uItemID, bEnable);
    }

    BOOL IsItemVisible(UINT uItemID, BOOL bCheckParent = FALSE)
    {
        return m_richView.IsItemVisible(uItemID, bCheckParent);
    }

    BOOL SetItemVisible(UINT uItemID, BOOL bVisible)
    {
        return m_richView.SetItemVisible(uItemID, bVisible);
    }

    BOOL SetTabCurSel(UINT uItemID, int nPage)
    {
        return m_richView.SetTabCurSel(uItemID, nPage);
    }

    int GetTabCurSel(UINT uItemID)
    {
        return m_richView.GetTabCurSel(uItemID);
    }

    BOOL SetTabTitle(UINT uItemID, int nPage, LPCTSTR lpszTitle)
    {
        return m_richView.SetTabTitle(uItemID, nPage, lpszTitle);
    }

    BOOL IsTabPageVisible(UINT uItemID, int nPage)
    {
        return m_richView.IsTabPageVisible(uItemID, nPage);
    }

    BOOL SetTabPageVisible(UINT uItemID, int nPage, BOOL bVisible)
    {
        return m_richView.SetTabPageVisible(uItemID, nPage, bVisible);
    }

    BOOL SetItemIconHandle(UINT uItemID, HICON hIcon)
    {
        return m_richView.SetItemIconHandle(uItemID, hIcon);
    }

	BOOL SetItemPaintHook(UINT uItemID, IBkWindowPaintHook* lpPaintHook)
	{
		return m_richView.SetItemPaintHook(uItemID, lpPaintHook);
	}

    void SetWindowCaption(LPCTSTR lpszCaption)
    {
        m_richView.SetWindowCaption(lpszCaption);
    }

    // Call at WM_INITDIALOG
    void DontShowWindow()
    {
        m_bShowWindow = FALSE;
    }

    HWND Create(HWND hWndParent = ::GetActiveWindow(), LPRECT rect = NULL)
    {
        if (!m_richView.XmlLoaded())
        {
            if (0 == m_uResID || !Load(m_uResID))
            {
                return NULL;
            }
        }

        CRect rcWnd(0, 0, 0, 0);
        LPCTSTR lpszCaption = m_richView.GetWindowCaption();

        if (_T('\0') == lpszCaption[0])
            lpszCaption = NULL;

        if (rect)
            rcWnd = rect;

        HWND hWnd = __super::Create(hWndParent, rcWnd, lpszCaption, m_richView.GetDlgStyle(), m_richView.GetDlgExStyle());
        if (!hWnd)
            return NULL;

        BkWinThemeFunc::SetWindowTheme(hWnd, L"", L"");

        if (rect)
        {
            rcWnd.MoveToXY(0, 0);
            m_richView.Create(m_hWnd, rcWnd, 0, 0, IDC_RICHVIEW_WIN);
        }
        else
            m_richView.Create(m_hWnd, NULL, 0, 0, IDC_RICHVIEW_WIN);

        m_bShowWindow = TRUE;

        SendMessage(WM_INITDIALOG, (WPARAM)hWnd);

        m_richView.ShowAllRealWindows(TRUE);

        if (m_hWnd == hWnd)
        {
            SIZE sizeDefault = m_richView.GetDefaultSize();
            if (sizeDefault.cx && sizeDefault.cy)
            {
                ResizeClient(sizeDefault, FALSE);
            }
        }
        else
            hWnd = m_hWnd;

        return hWnd;
    }

	/*BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
	{
		::SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(GWL_EXSTYLE) | WS_EX_LAYERED);
		BYTE bTran = 5;
		m_nAlpha = 5;
		::SetLayeredWindowAttributes(m_hWnd, 0, bTran, LWA_ALPHA);

		return TRUE;
	}*/

	void TransparentDlg(int nAlpha, int nAlphaIncrement = 20)
	{
		::SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(GWL_EXSTYLE) | WS_EX_LAYERED);
		m_nAlpha = nAlpha;
		m_nAlphaIncrement = nAlphaIncrement;
		::SetLayeredWindowAttributes(m_hWnd, 0, m_nAlpha, LWA_ALPHA);
	}

	void Fadein(UINT_PTR uIdEvent)//OnTimer
	{
		if(uIdEvent == TIMER_ID_MOTHON_DIALOG)
		{
			if(m_bShowWindow)
			{
				ShowMotionThread();	
			}
		}
	}

	void UpdateTipText(LPCTSTR str)
	{
		m_richView.m_wndToolTip.UpdateTipText(str, GetViewHWND());
	}

	/*void ToolTipRelayEvent(MSG msg)
	{
		m_richView.m_wndToolTip.RelayEvent(&msg);
	}

	BOOL IsToolTipWindow()
	{
		return m_richView.m_wndToolTip.IsWindow();
	}*/

	void ShowMotionThread()
	{
		while (m_nAlpha < 255)
		{
			m_nAlpha += m_nAlphaIncrement;
			if(m_nAlpha > 255)
			{
				m_nAlpha = 255;
				KillTimer(TIMER_ID_MOTHON_DIALOG);
			}

			::SetLayeredWindowAttributes(m_hWnd, 0, m_nAlpha, LWA_ALPHA);
		}
	}

    UINT_PTR DoModal(HWND hWndParent = NULL, LPRECT rect = NULL)
    {
        BOOL bEnableParent = FALSE;

        if (NULL == hWndParent)
        {
            hWndParent = BkWinManager::GetActive();
            if (NULL == hWndParent)
                hWndParent = ::GetActiveWindow();
        }

        if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
        {
            ::EnableWindow(hWndParent, FALSE);
            bEnableParent = TRUE;
        }

        m_bExitModalLoop = FALSE;

        HWND hWnd = Create(hWndParent, rect);
        if (!hWnd)
        {
            ::EnableWindow(hWndParent, TRUE);
            return 0;
        }

        HWND hWndLastActive = BkWinManager::SetActive(hWnd);

        if (!rect)
            CenterWindow();

        if (m_bShowWindow)
        {
            ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
			SetTimer(TIMER_ID_MOTHON_DIALOG, 10, NULL);
        }

        _ModalMessageLoop();

        m_bExitModalLoop = FALSE;

        // From MFC
        // hide the window before enabling the parent, etc.

		if ( IsWindow() )
		{
			SetWindowPos(
            NULL, 0, 0, 0, 0, 
            SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
		}

        if (bEnableParent)
        {
            ::EnableWindow(hWndParent, TRUE);
        }

        if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
            ::SetActiveWindow(hWndParent);

        BkWinManager::SetActive(hWndLastActive);

		if ( IsWindow() )
	        DestroyWindow();

        return m_uRetCode;
    }

    void OnClose()
    {
        SendMessage(WM_COMMAND, MAKELONG(IDCANCEL, 0), NULL);
    }

    void EndDialog(UINT uRetCode)
    {
        m_uRetCode = uRetCode;

        m_bExitModalLoop = TRUE;

        // DestroyWindow里面直接Send了WM_DESTROY,所以不会跑到DoModal的消息循环里,所以有了下面那行代码
        // DestroyWindow();

        // 这句非常重要,可以让DoModal消息循环再跑一次,防止卡死在GetMessage,泪奔~~~~~~~
        ::PostThreadMessage(::GetCurrentThreadId(), WM_NULL, 0, 0);
    }

    void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
        if (IsWindowEnabled())
        {
            if (::GetKeyState(VK_CONTROL) >= 0)
            {
                if (VK_ESCAPE == nChar)
                {
                    SendMessage(WM_COMMAND, MAKELONG(IDCANCEL, 0), NULL);
                }
                else if (VK_RETURN == nChar)
                {
                    SendMessage(WM_COMMAND, MAKELONG(IDOK, 0), NULL);
                }
            }

            SetMsgHandled(FALSE);
        }
    }

    void OnOK(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
    {
        BKNMCOMMAND nms;
        nms.hdr.code = BKNM_COMMAND;
        nms.hdr.hwndFrom = m_hWnd;
        nms.hdr.idFrom = IDC_RICHVIEW_WIN;
        nms.uItemID = IDOK;
        nms.szItemClass = "";

        LRESULT lRet = ::SendMessage(m_hWnd, WM_NOTIFY, (LPARAM)nms.hdr.idFrom, (WPARAM)&nms);
    }

    void OnCancel(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
    {
        BKNMCOMMAND nms;
        nms.hdr.code = BKNM_COMMAND;
        nms.hdr.hwndFrom = m_hWnd;
        nms.hdr.idFrom = IDC_RICHVIEW_WIN;
        nms.uItemID = IDCANCEL;
        nms.szItemClass = "";

        LRESULT lRet = ::SendMessage(m_hWnd, WM_NOTIFY, (LPARAM)nms.hdr.idFrom, (WPARAM)&nms);
    }

protected:

    BOOL m_bExitModalLoop;

    void _ModalMessageLoop()
    {
        BOOL bRet;
        MSG msg;

        for(;;)
        {
            if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
            {
                if (WM_QUIT == msg.message)
                    break;
            }

            if (m_bExitModalLoop || NULL == m_hWnd || !::IsWindow(m_hWnd))
                break;

            bRet = ::GetMessage(&msg, NULL, 0, 0);

            if (bRet == -1)
            {
                continue;   // error, don't process
            }
            else if (!bRet)
            {
                ATLTRACE(L"Why Receive WM_QUIT here?\r\n");
                break;   // WM_QUIT, exit message loop
            }

            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }

	BEGIN_MSG_MAP_EX(CBkDialogImpl)
		//MSG_WM_INITDIALOG(OnInitDialog)
        MSG_WM_NCACTIVATE(OnNcActivate)
        MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_NCCALCSIZE(OnNcCalcSize)
        MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
        MSG_WM_SIZE(OnSize)
        MSG_WM_KEYDOWN(OnKeyDown)
        MSG_WM_CLOSE(OnClose)
        COMMAND_ID_HANDLER_EX(IDOK, OnOK)
        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
		//MSG_WM_TIMER(OnTimer)
	END_MSG_MAP()
};

//
// CBkSimpleDialog

class CBkSimpleDialog
    : public CBkDialogImpl<CBkSimpleDialog>
{
public:
    CBkSimpleDialog(UINT uResID = 0)
        : CBkDialogImpl<CBkSimpleDialog>(uResID)
    {
    }
protected:

    void OnBkCommand(UINT uItemID, LPCSTR szItemClass)
    {
        if (strcmp(CBkButton::GetClassName(), szItemClass) != 0 && strcmp(CBkImageBtnWnd::GetClassName(), szItemClass) != 0)
            return;

        EndDialog(uItemID);
    }

    BK_NOTIFY_MAP(IDC_RICHVIEW_WIN)
        BK_NOTIFY_COMMAND(OnBkCommand)
    BK_NOTIFY_MAP_END()

	BEGIN_MSG_MAP_EX(CBkDialogImpl<CBkSimpleDialog>)
        MSG_BK_NOTIFY(IDC_RICHVIEW_WIN)
        CHAIN_MSG_MAP(CBkDialogImpl<CBkSimpleDialog>)
	END_MSG_MAP()
};

bkwndpanel.h

//
//   File Name: bkwndpanel.h
// Description: CBkPanel Definition, Virtual Container of BkWindows
//     Creator: Zhang Xiaoxuan
//     Version: 2009.04.28 - 1.0 - Create
//

#pragma once

#include "bkwndcmnctrl.h"
#include "bkwndrichtxt.h"
#include "bkwndedit.h"

class CBkPanel : public CBkContainerWnd
{
    BKOBJ_DECLARE_CLASS_NAME(CBkPanel, "div")

public:
    CBkPanel()
        : m_bOnlyDrawChild(FALSE)
    {
    }

protected:

    CAtlList<CBkWindow *> m_lstWndChild;
    BOOL m_bOnlyDrawChild;

protected:

    CBkWindow* _CreateBkWindowByName(LPCSTR lpszName);

    // Vert-Align Process
    // Called after this line composed
    void _ProcessLineVAlign(POSITION posLineStart, POSITION posLineEnd, LONG lLineTop, LONG lLineBottom)
    {
        CRect rcChild;

        if (m_uVAlign == VAlign_Top)
            return;

        POSITION posLine = posLineStart;
        int nNewTop = 0;

        while (posLine != posLineEnd)
        {
            CBkWindow *pBkWndLine = m_lstWndChild.GetNext(posLine);

            pBkWndLine->GetRect(rcChild);

            if (m_uVAlign == VAlign_Middle)
                nNewTop = lLineTop + (lLineBottom - lLineTop - rcChild.Height()) / 2;
            else if(m_uVAlign == VAlign_Bottom)
                nNewTop = lLineBottom - rcChild.Height();

            rcChild.MoveToY(nNewTop);
            pBkWndLine->Move(rcChild);
        }
    }

    // Composing .....
    void _ComposingPanel(LPWINDOWPOS lpWndPos)
    {
        POSITION pos = m_lstWndChild.GetHeadPosition(), posPrev = NULL, posThisLineStart = NULL;
        WINDOWPOS WndPos;
        CRect rcChild;

        LONG lNextLineTop = lpWndPos->y + m_style.m_nMarginY + m_style.m_nLineSpacing;
        LONG lMaxRight = m_rcWindow.right;
        LONG lMaxBottom = m_rcWindow.top;
        BOOL bFirstInBlock = TRUE, bNewLine = FALSE;

        memcpy(&WndPos, lpWndPos, sizeof(WINDOWPOS));

        WndPos.x += m_style.m_nMarginX;
        WndPos.y += m_style.m_nMarginY;
        WndPos.cx = ((GetPositionType() & SizeX_Specify) ? m_lSpecifyWidth : WndPos.cx) - m_style.m_nMarginX * 2;
        WndPos.cy -= m_style.m_nMarginY * 2;

        while (pos != NULL)
        {
            posPrev = pos;

            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (!pBkWndChild->IsVisible())
                continue;

            if (Position_Float & pBkWndChild->GetPositionType())
                continue;

            if (bFirstInBlock)
                posThisLineStart = posPrev;

            // Return
            if (pBkWndChild->IsClass(CBkReturn::GetClassName()))
            {
                _ProcessLineVAlign(posThisLineStart, posPrev, WndPos.y, lNextLineTop);
                posThisLineStart = posPrev;

                WndPos.x = lpWndPos->x + m_style.m_nMarginX;
                WndPos.y = lNextLineTop + m_style.m_nLineSpacing;
                WndPos.cx = ((GetPositionType() & SizeX_Specify) ? m_lSpecifyWidth : lpWndPos->cx) - m_style.m_nMarginX * 2;
                WndPos.cy = lpWndPos->y + lpWndPos->cy - WndPos.y - m_style.m_nMarginY;

                bFirstInBlock = FALSE;

                continue;
            }

            if (WndPos.cx == 0)
            {
                bNewLine = TRUE;
            }
            else
            {
                pBkWndChild->BkSendMessage(WM_WINDOWPOSCHANGED, NULL, (LPARAM)&WndPos);
                pBkWndChild->GetRect(rcChild);

                bNewLine = FALSE;

                // Is this line full?
                if ((rcChild.right > WndPos.x + WndPos.cx || rcChild.right <= rcChild.left) && !bFirstInBlock)
                {
                    bNewLine = TRUE;
                    _ProcessLineVAlign(posThisLineStart, posPrev, WndPos.y, lNextLineTop);
                    posThisLineStart = posPrev;
                }
            }

            bFirstInBlock = FALSE;

            if (bNewLine)
            {
                // Reposition this control to next line
                WndPos.x = lpWndPos->x + m_style.m_nMarginX;
                WndPos.y = lNextLineTop + m_style.m_nLineSpacing;
                WndPos.cx = ((GetPositionType() & SizeX_Specify) ? m_lSpecifyWidth : lpWndPos->cx) - m_style.m_nMarginX * 2;
                WndPos.cy = lpWndPos->y + lpWndPos->cy - WndPos.y - m_style.m_nMarginY;

                pBkWndChild->BkSendMessage(WM_WINDOWPOSCHANGED, NULL, (LPARAM)&WndPos);
                pBkWndChild->GetRect(rcChild);
            }

            // Next control position
            WndPos.x += rcChild.Width() + m_style.m_nSpacing;
            WndPos.cx -= rcChild.Width() + m_style.m_nSpacing;

            if (lNextLineTop < rcChild.bottom)
            {
                lNextLineTop = rcChild.bottom;
            }

            if (lMaxRight < rcChild.right + m_style.m_nMarginX)
            {
                lMaxRight = rcChild.right + m_style.m_nMarginX;
            }
        }

        // Process last line
        _ProcessLineVAlign(posThisLineStart, NULL, WndPos.y, lNextLineTop);

        switch (GetPositionType() & SizeX_Mask)
        {
        case SizeX_FitParent:
            m_rcWindow.right = lpWndPos->x + lpWndPos->cx;
            break;
        case SizeX_FitContent:
            m_rcWindow.right = lMaxRight;
            break;
        case SizeX_Specify:
            m_rcWindow.right = lpWndPos->x + m_lSpecifyWidth;
            break;
        }

        switch (GetPositionType() & SizeY_Mask)
        {
        case SizeY_FitParent:
            m_rcWindow.bottom = lpWndPos->y + lpWndPos->cy;
            break;
        case SizeY_FitContent:
            m_rcWindow.bottom = lNextLineTop + m_style.m_nMarginY;
            break;
        case SizeY_Specify:
            m_rcWindow.bottom = lpWndPos->y + m_lSpecifyHeight;
            break;
        }

        // Process float children here
        pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            posPrev = pos;

            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (!pBkWndChild->IsVisible())
                continue;

            if (0 == (Position_Float & pBkWndChild->GetPositionType()))
                continue;

            memcpy(&WndPos, lpWndPos, sizeof(WINDOWPOS));

            WndPos.x += m_style.m_nMarginX;
            WndPos.y += m_style.m_nMarginY;
            WndPos.cx = ((GetPositionType() & SizeX_Specify) ? m_lSpecifyWidth : WndPos.cx) - m_style.m_nMarginX * 2;
            WndPos.cy -= m_style.m_nMarginY * 2;

            pBkWndChild->BkSendMessage(WM_WINDOWPOSCHANGED, NULL, (LPARAM)&WndPos);
            pBkWndChild->GetRect(rcChild);

            if (Align_Right & pBkWndChild->GetAlign())
            {
                WndPos.x = WndPos.x + WndPos.cx - rcChild.Width();
            }
            else if (Align_Center & pBkWndChild->GetAlign())
            {
                WndPos.x = WndPos.x + (WndPos.cx - rcChild.Width()) / 2;
            }

            if (VAlign_Bottom & pBkWndChild->GetAlign())
            {
                WndPos.y = WndPos.y + WndPos.cy - rcChild.Height();
            }
            else if (VAlign_Middle & pBkWndChild->GetAlign())
            {
                WndPos.y = WndPos.y + (WndPos.cy - rcChild.Height()) / 2;
            }

            WndPos.cx = rcChild.Width();
            WndPos.cy = rcChild.Height();

            pBkWndChild->BkSendMessage(WM_WINDOWPOSCHANGED, NULL, (LPARAM)&WndPos);

        }
    }

public:

    BOOL LoadChilds(TiXmlElement* pTiXmlChildElem)
    {
        BkSendMessage(WM_DESTROY);

        BOOL bVisible = IsVisible(TRUE);

        for (TiXmlElement* pXmlChild = pTiXmlChildElem; NULL != pXmlChild; pXmlChild = pXmlChild->NextSiblingElement())
        {
            CBkWindow *pNewChildWindow = _CreateBkWindowByName(pXmlChild->Value());
            if (!pNewChildWindow)
                continue;

//             int nID = 0;
//             pXmlChild->Attribute("id", &nID);

            pNewChildWindow->SetParent(m_hBkWnd);
            pNewChildWindow->SetContainer(m_hWndContainer);
            pNewChildWindow->Load(pXmlChild);

//             if (pNewChildWindow->IsVisible())
//                 pNewChildWindow->BkSendMessage(WM_SHOWWINDOW, bVisible);

            m_lstWndChild.AddTail(pNewChildWindow);
        }

        return TRUE;
    }

    // Create children
    virtual BOOL Load(TiXmlElement* pTiXmlElem)
    {
        if (!CBkWindow::Load(pTiXmlElem))
            return FALSE;

        return LoadChilds(pTiXmlElem->FirstChildElement());
    }

    // Hittest children
    virtual HBKWND BkGetHWNDFromPoint(POINT ptHitTest, BOOL bOnlyText)
    {
        if (m_rcWindow.PtInRect(ptHitTest))
        {
            if (m_bOnlyDrawChild)
                return m_hBkWnd;

            HBKWND hBkWndChild = NULL;

            POSITION pos = m_lstWndChild.GetTailPosition();

            while (pos != NULL)
            {
                CBkWindow *pBkWndChild = m_lstWndChild.GetPrev(pos);
                if (!pBkWndChild->IsVisible() || pBkWndChild->IsTransparent())
                    continue;

                if (Position_Float == (pBkWndChild->GetPositionType() & Position_Float))
                {
                    hBkWndChild = pBkWndChild->BkGetHWNDFromPoint(ptHitTest, bOnlyText);

                    if (hBkWndChild)
                        break;
                }
            }

            if (hBkWndChild)
                return hBkWndChild;

            pos = m_lstWndChild.GetTailPosition();

            while (pos != NULL)
            {
                CBkWindow *pBkWndChild = m_lstWndChild.GetPrev(pos);
                if (!pBkWndChild->IsVisible() || pBkWndChild->IsTransparent())
                    continue;

                if (0 == (pBkWndChild->GetPositionType() & Position_Float))
                {
                    hBkWndChild = pBkWndChild->BkGetHWNDFromPoint(ptHitTest, bOnlyText);

                    if (hBkWndChild)
                        break;
                }
            }

            if (hBkWndChild)
                return hBkWndChild;
            else
                return m_hBkWnd;
        }
        else
            return NULL;
    }

    void SetContainer(HWND hWndContainer)
    {
        __super::SetContainer(hWndContainer);

        POSITION pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (pBkWndChild)
            {
                pBkWndChild->SetContainer(hWndContainer);
            }
        }
    }

    CBkWindow* FindChildByCmdID(UINT uCmdID)
    {
        CBkWindow *pChildFind = NULL;

        POSITION pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (pBkWndChild->GetCmdID() == uCmdID)
                return pBkWndChild;
        }

        pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (pBkWndChild->IsContainer())
            {
                pChildFind = ((CBkContainerWnd *)pBkWndChild)->FindChildByCmdID(uCmdID);
                if (pChildFind)
                    return pChildFind;
            }
        }

        return NULL;
    }

    virtual BOOL RedrawRegion(CDCHandle& dc, CRgn& rgn)
    {
        if (__super::RedrawRegion(dc, rgn))
        {
            POSITION pos = m_lstWndChild.GetHeadPosition();
            BkDCPaint BkDC;

            BeforePaint(dc, BkDC);

            while (pos != NULL)
            {
                CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

                if (pBkWndChild && pBkWndChild->IsVisible())
                {
                    pBkWndChild->RedrawRegion(dc, rgn);
                }
            }

            AfterPaint(dc, BkDC);

            return TRUE;
        }

        return FALSE;
    }

    void ShowAllRealWindowChilds(BOOL bShow);

    void OnWindowPosChanged(LPWINDOWPOS lpWndPos)
    {
        // Calc default panel size
        CBkWindow::OnWindowPosChanged(lpWndPos);

        _ComposingPanel(lpWndPos);

    }

    int OnCreate(LPCREATESTRUCT /*lpCreateStruct*/)
    {
        POSITION pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            pBkWndChild->OnCreate(NULL);
        }

        return TRUE;
    }

    void OnDestroy()
    {
        POSITION pos = m_lstWndChild.GetHeadPosition();

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            pBkWndChild->BkSendMessage(WM_DESTROY);

            delete pBkWndChild;
        }

        m_lstWndChild.RemoveAll();
    }

    BOOL OnEraseBkgnd(CDCHandle dc)
    {
//         CBkWindow::OnEraseBkgnd(dc);

        POSITION pos = m_lstWndChild.GetHeadPosition();

        BOOL bDisabled = IsDisabled(), bIsChildDisabled = FALSE;

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);
            if (!pBkWndChild->IsVisible())
                continue;

            if (bDisabled)
            {
                bIsChildDisabled = pBkWndChild->IsDisabled();

                if (!bIsChildDisabled)
                    pBkWndChild->ModifyState(BkWndState_Disable, 0);
            }

            pBkWndChild->BkSendMessage(WM_ERASEBKGND, (WPARAM)(HDC)dc);

            if (bDisabled && !bIsChildDisabled)
            {
                pBkWndChild->ModifyState(0, BkWndState_Disable);
            }
        }

        return TRUE;
    }

    void OnPaint(CDCHandle dc)
    {
        return;

        HFONT hftOld = NULL, hftDraw = NULL;
        COLORREF crOld = CLR_INVALID, crOldBg = CLR_INVALID, crDraw = CLR_INVALID;
        CRect rcText = m_rcWindow;
        int nOldBkMode = OPAQUE;

        if (!m_style.m_strSkinName.IsEmpty())
            nOldBkMode = dc.SetBkMode(TRANSPARENT);
        if (CLR_INVALID != m_style.m_crBg)
            crOldBg = dc.SetBkColor(m_style.m_crBg);

        if (m_style.m_ftText)
            hftDraw = m_style.m_ftText;

        if (m_style.m_crText != CLR_INVALID)
            crDraw = m_style.m_crText;

        if (BkWndState_Hover == (GetState() & BkWndState_Hover))
        {
            if (m_style.m_ftHover)
                hftDraw = m_style.m_ftHover;

            if (m_style.m_crHoverText != CLR_INVALID)
                crDraw = m_style.m_crHoverText;
        }

        if (hftDraw)
            hftOld = dc.SelectFont(hftDraw);

        if (crDraw != CLR_INVALID)
            crOld = dc.SetTextColor(crDraw);
//         int nOldBkMode = OPAQUE;
//         COLORREF crOldBg = CLR_INVALID;
//         COLORREF crOldText = CLR_INVALID;
// 
//         if (!m_style.m_strSkinName.IsEmpty())
//             nOldBkMode = dc.SetBkMode(TRANSPARENT);
//         if (CLR_INVALID != m_style.m_crBg)
//             crOldBg = dc.SetBkColor(m_style.m_crBg);
//         if (CLR_INVALID != m_style.m_crText)
//             crOldText = dc.SetTextColor(m_style.m_crText);

        POSITION pos = m_lstWndChild.GetHeadPosition();

        BOOL bDisabled = IsDisabled(), bIsChildDisabled = FALSE;

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

            if (!pBkWndChild->IsVisible())
                continue;

            if (bDisabled)
            {
                bIsChildDisabled = pBkWndChild->IsDisabled();

                if (!bIsChildDisabled)
                    pBkWndChild->ModifyState(BkWndState_Disable, 0);
            }

            pBkWndChild->BkSendMessage(WM_PAINT, (WPARAM)(HDC)dc);

            if (bDisabled && !bIsChildDisabled)
            {
                pBkWndChild->ModifyState(0, BkWndState_Disable);
            }
        }

        if (hftDraw)
            dc.SelectFont(hftOld);

        if (crDraw != CLR_INVALID)
            dc.SetTextColor(crOld);

        if (!m_style.m_strSkinName.IsEmpty())
            dc.SetBkMode(nOldBkMode);
        if (CLR_INVALID != m_style.m_crBg)
            dc.SetBkColor(crOldBg);
    }

    void OnMouseMove(UINT nFlags, CPoint point)
    {
        POSITION pos = m_lstWndChild.GetHeadPosition();
        CRect rcChild;

        while (pos != NULL)
        {
            CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);
            if (!pBkWndChild->IsVisible())
                continue;

            pBkWndChild->GetRect(rcChild);

            if (rcChild.PtInRect(point))
            {
                pBkWndChild->BkSendMessage(WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)MAKELONG(point.x, point.y));
            }
        }
    }

    void OnShowWindow(BOOL bShow, UINT nStatus)
    {
        __super::OnShowWindow(bShow, nStatus);

        ShowAllRealWindowChilds(bShow);
    }

protected:

    BKWIN_DECLARE_ATTRIBUTES_BEGIN()
        BKWIN_INT_ATTRIBUTE("onlydrawchild", m_bOnlyDrawChild, FALSE)
    BKWIN_DECLARE_ATTRIBUTES_END()

    BKWIN_BEGIN_MSG_MAP()
        MSG_WM_PAINT(OnPaint)
//         MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
        MSG_WM_DESTROY(OnDestroy)
        MSG_WM_MOUSEMOVE(OnMouseMove)
        MSG_WM_SHOWWINDOW(OnShowWindow)
    BKWIN_END_MSG_MAP()
};

#include "bkwnddlg.h"
#include "bkwnddlgfile.h"
#include "bkwndtabctrl.h"

inline CBkWindow* CBkPanel::_CreateBkWindowByName(LPCSTR lpszName)
{
    CBkWindow *pNewWindow = NULL;

//     pNewWindow = CBkPanel::CheckAndNew(lpszName);
//     if (pNewWindow)
//         return pNewWindow;

    pNewWindow = CBkDialog::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

	pNewWindow = CBkDialogFile::CheckAndNew(lpszName);
	if (pNewWindow)
		return pNewWindow;

    pNewWindow = CBkStatic::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkButton::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

//     pNewWindow = CBkSpacing::CheckAndNew(lpszName);
//     if (pNewWindow)
//         return pNewWindow;

    pNewWindow = CBkImageWnd::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

//     pNewWindow = CBkReturn::CheckAndNew(lpszName);
//     if (pNewWindow)
//         return pNewWindow;

    pNewWindow = CBkProgress::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkImageBtnWnd::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkRealWnd::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkLine::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkCheckBox::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkIconWnd::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkTabCtrl::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkRadioBox::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkRichText::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

    pNewWindow = CBkLink::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

	pNewWindow = CBkMemoryImage::CheckAndNew(lpszName);
	if (pNewWindow)
		return pNewWindow;

	pNewWindow = CBkImageListHWnd::CheckAndNew(lpszName);
	if (pNewWindow)
		return pNewWindow;

	pNewWindow = CBkDrawFileIcon::CheckAndNew(lpszName);
	if (pNewWindow)
		return pNewWindow;

    pNewWindow = CBkEdit::CheckAndNew(lpszName);
    if (pNewWindow)
        return pNewWindow;

	pNewWindow = CBkSlider::CheckAndNew(lpszName);
	if (pNewWindow)
		return pNewWindow;

    return NULL;
}

inline void CBkPanel::ShowAllRealWindowChilds(BOOL bShow)
{
    POSITION pos = m_lstWndChild.GetHeadPosition();

    BOOL bVisible = IsVisible(TRUE);

    while (pos != NULL)
    {
        CBkWindow *pBkWndChild = m_lstWndChild.GetNext(pos);

        BOOL bChildVisible = bVisible && pBkWndChild->IsVisible();

//         if (!pBkWndChild->IsVisible())
//             continue;

        if (pBkWndChild->IsClass(CBkRealWnd::GetClassName()))
        {
            ((CBkRealWnd *)pBkWndChild)->ShowRealWindow(bShow && bChildVisible);
        }
        else if (pBkWndChild->IsClass(CBkPanel::GetClassName()) || pBkWndChild->IsClass(CBkDialog::GetClassName()) || pBkWndChild->IsClass(CBkDialogFile::GetClassName()) )
        {
            ((CBkPanel *)pBkWndChild)->ShowAllRealWindowChilds(bShow && bChildVisible);
        }
        else if (pBkWndChild->IsClass(CBkTabCtrl::GetClassName()))
        {
            ((CBkTabCtrl *)pBkWndChild)->ShowAllRealWindowChilds(bShow && bChildVisible);
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值