From 02d1ed8832a14764a00d0e50c0bc08033883051f Mon Sep 17 00:00:00 2001 From: wangchyz Date: Thu, 17 Mar 2016 21:17:06 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E7=BB=9F=E4=B8=80=E4=BA=86=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6class=20name=E5=92=8Cinterface=20name=202=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86=E8=8B=A5=E5=B9=B2bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 360SafeDemo/360Safe.cpp | 6 +- DuiLib/Control/UIActiveX.cpp | 7 +- DuiLib/Control/UIActiveX.h | 4 +- DuiLib/Control/UIButton.cpp | 48 +- DuiLib/Control/UIButton.h | 2 +- DuiLib/Control/UICheckBox.cpp | 2 +- DuiLib/Control/UICheckBox.h | 2 +- DuiLib/Control/UICombo.cpp | 406 ++++++++-- DuiLib/Control/UICombo.h | 27 +- DuiLib/Control/UIDateTime.cpp | 36 +- DuiLib/Control/UIDateTime.h | 5 +- DuiLib/Control/UIEdit.cpp | 67 +- DuiLib/Control/UIEdit.h | 2 +- DuiLib/Control/UIGifAnim.cpp | Bin 9127 -> 18374 bytes DuiLib/Control/UIGifAnim.h | 4 +- DuiLib/Control/UILabel.cpp | 106 ++- DuiLib/Control/UILabel.h | 22 +- DuiLib/Control/UIList.cpp | 1125 ++++++++++++++++++++------ DuiLib/Control/UIList.h | 164 ++-- DuiLib/Control/UIOption.cpp | 6 +- DuiLib/Control/UIOption.h | 2 +- DuiLib/Control/UIProgress.cpp | 2 +- DuiLib/Control/UIProgress.h | 2 +- DuiLib/Control/UIRichEdit.cpp | 56 +- DuiLib/Control/UIRichEdit.h | 8 +- DuiLib/Control/UIScrollBar.cpp | 81 +- DuiLib/Control/UIScrollBar.h | 7 +- DuiLib/Control/UISlider.cpp | 47 +- DuiLib/Control/UISlider.h | 2 +- DuiLib/Control/UIText.cpp | 37 +- DuiLib/Control/UIText.h | 3 +- DuiLib/Control/UITreeView.cpp | 260 +++--- DuiLib/Control/UITreeView.h | 30 +- DuiLib/Control/UIWebBrowser.cpp | 2 +- DuiLib/Control/UIWebBrowser.h | 2 +- DuiLib/Core/UIBase.cpp | 2 +- DuiLib/Core/UIBase.h | 10 +- DuiLib/Core/UIContainer.cpp | 233 +++--- DuiLib/Core/UIContainer.h | 20 +- DuiLib/Core/UIControl.cpp | 136 +++- DuiLib/Core/UIControl.h | 19 +- DuiLib/Core/UIDefine.h | 14 +- DuiLib/Core/UIDlgBuilder.cpp | 195 ++--- DuiLib/Core/UIDlgBuilder.h | 2 +- DuiLib/Core/UIManager.cpp | 357 +++++++- DuiLib/Core/UIManager.h | 93 ++- DuiLib/Core/UIMarkup.h | 4 +- DuiLib/Core/UIRender.cpp | 38 +- DuiLib/Core/UIRender.h | 6 +- DuiLib/DuiLib.vcxproj | 14 +- DuiLib/DuiLib.vcxproj.filters | 24 +- DuiLib/Layout/UIChildLayout.cpp | 2 +- DuiLib/Layout/UIChildLayout.h | 2 +- DuiLib/Layout/UIHorizontalLayout.cpp | 3 +- DuiLib/Layout/UIHorizontalLayout.h | 2 +- DuiLib/Layout/UITabLayout.cpp | 6 +- DuiLib/Layout/UITabLayout.h | 4 +- DuiLib/Layout/UITileLayout.cpp | 2 +- DuiLib/Layout/UITileLayout.h | 2 +- DuiLib/Layout/UIVerticalLayout.cpp | 2 +- DuiLib/Layout/UIVerticalLayout.h | 2 +- DuiLib/UIlib.cpp | 1 - DuiLib/UIlib.h | 13 +- DuiLib/Utils/UIDelegate.h | 6 +- DuiLib/Utils/Utils.cpp | 456 +++++++++-- DuiLib/Utils/Utils.h | 376 ++++++--- DuiLib/Utils/WinImplBase.cpp | 6 +- DuiLib/Utils/WinImplBase.h | 2 +- DuiLib/Utils/WndShadow.cpp | 648 +++++++++++++++ DuiLib/Utils/WndShadow.h | 124 +++ FlashDemo/App.cpp | 2 +- GameDemo/ControlEx.h | 34 +- GameDemo/GameDemo.cpp | 24 +- ListDemo/Main.cpp | 6 +- MenuDemo/MenuDemo.vcxproj | 92 ++- MenuDemo/MenuDemo.vcxproj.filters | 26 +- MenuDemo/UIMenu.cpp | 99 ++- MenuDemo/UIMenu.h | 6 +- MenuDemo/res/menutest.xml | 2 +- MenuDemo/res/skin.xml | 6 +- QQDemo/ColorPicker.cpp | 4 +- QQDemo/UIFriends.cpp | 28 +- QQDemo/UIFriends.hpp | 4 +- QQDemo/UIGroups.cpp | 26 +- QQDemo/UIGroups.hpp | 4 +- QQDemo/main_frame.cpp | 6 +- RichListDemo/RichListDemo.vcxproj | 4 + RichListDemo/RichListWnd.cpp | 14 +- ScrCapture/ScrCaptureWnd.cpp | 9 - TestApp1/App.cpp | 333 +++++++- bin/LeftWithFill.png | Bin 0 -> 7078 bytes bin/skin/GameRes/hall.xml | 13 +- bin/test1.xml | 17 +- 93 files changed, 4658 insertions(+), 1509 deletions(-) create mode 100644 DuiLib/Utils/WndShadow.cpp create mode 100644 DuiLib/Utils/WndShadow.h create mode 100644 bin/LeftWithFill.png diff --git a/360SafeDemo/360Safe.cpp b/360SafeDemo/360Safe.cpp index 6a1b0d84..1cc7d450 100644 --- a/360SafeDemo/360Safe.cpp +++ b/360SafeDemo/360Safe.cpp @@ -135,9 +135,9 @@ class C360SafeFrameWnd : public CWindowWnd, public INotifyUI if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_pm.FindControl(pt)); - if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("OptionUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("TextUI")) != 0 ) + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_TEXT) != 0 ) return HTCAPTION; } diff --git a/DuiLib/Control/UIActiveX.cpp b/DuiLib/Control/UIActiveX.cpp index 628061af..c24a0c91 100644 --- a/DuiLib/Control/UIActiveX.cpp +++ b/DuiLib/Control/UIActiveX.cpp @@ -933,7 +933,7 @@ CActiveXUI::~CActiveXUI() LPCTSTR CActiveXUI::GetClass() const { - return _T("ActiveXUI"); + return DUI_CTR_ACTIVEX; } LPVOID CActiveXUI::GetInterface(LPCTSTR pstrName) @@ -1019,12 +1019,13 @@ void CActiveXUI::Move(SIZE szOffset, bool bNeedInvalidate) } } -void CActiveXUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CActiveXUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { if( m_pControl != NULL && m_pControl->m_bWindowless && m_pControl->m_pViewObject != NULL ) { m_pControl->m_pViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hDC, (RECTL*) &m_rcItem, (RECTL*) &m_rcItem, NULL, NULL); } + return true; } void CActiveXUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) @@ -1058,7 +1059,7 @@ LRESULT CActiveXUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool if( dwHitResult != HITRESULT_HIT ) return 0; if( uMsg == WM_SETCURSOR ) bWasHandled = false; else if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN ) { - ::SetFocus(GetManager()->GetPaintWindow()); + if (!GetManager()->IsNoActivate()) ::SetFocus(GetManager()->GetPaintWindow()); SetFocus(); } } diff --git a/DuiLib/Control/UIActiveX.h b/DuiLib/Control/UIActiveX.h index eb66b9a8..fc9fa904 100644 --- a/DuiLib/Control/UIActiveX.h +++ b/DuiLib/Control/UIActiveX.h @@ -25,7 +25,7 @@ class CSafeRelease ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CActiveXUI : public CControlUI, public IMessageFilterUI +class DUILIB_API CActiveXUI : public CControlUI, public IMessageFilterUI { friend class CActiveXCtrl; public: @@ -51,7 +51,7 @@ class UILIB_API CActiveXUI : public CControlUI, public IMessageFilterUI void SetInternVisible(bool bVisible = true); void SetPos(RECT rc, bool bNeedInvalidate = true); void Move(SIZE szOffset, bool bNeedInvalidate = true); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); diff --git a/DuiLib/Control/UIButton.cpp b/DuiLib/Control/UIButton.cpp index 5898dbe6..d0f31e6f 100644 --- a/DuiLib/Control/UIButton.cpp +++ b/DuiLib/Control/UIButton.cpp @@ -17,7 +17,7 @@ namespace DuiLib LPCTSTR CButtonUI::GetClass() const { - return _T("ButtonUI"); + return DUI_CTR_BUTTON; } LPVOID CButtonUI::GetInterface(LPCTSTR pstrName) @@ -49,7 +49,7 @@ namespace DuiLib } if( event.Type == UIEVENT_KEYDOWN ) { - if (IsKeyboardEnabled()) { + if (IsKeyboardEnabled() && IsEnabled()) { if( event.chKey == VK_SPACE || event.chKey == VK_RETURN ) { Activate(); return; @@ -76,7 +76,7 @@ namespace DuiLib if( event.Type == UIEVENT_BUTTONUP ) { if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { - if( ::PtInRect(&m_rcItem, event.ptMouse) ) Activate(); + if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled()) Activate(); m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED); Invalidate(); } @@ -84,33 +84,43 @@ namespace DuiLib } if( event.Type == UIEVENT_CONTEXTMENU ) { - if( IsContextMenuUsed() ) { + if( IsContextMenuUsed() && IsEnabled()) { m_pManager->SendNotify(this, DUI_MSGTYPE_MENU, event.wParam, event.lParam); } return; } if( event.Type == UIEVENT_MOUSEENTER ) { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); - } + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } + } if ( GetFadeAlphaDelta() > 0 ) { m_pManager->SetTimer(this, FADE_TIMERID, FADE_ELLAPSE); } - // return; } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( IsEnabled() ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); - } - - if ( GetFadeAlphaDelta() > 0 ) { - m_pManager->SetTimer(this, FADE_TIMERID, FADE_ELLAPSE); - } - // return; + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + if ( GetFadeAlphaDelta() > 0 ) { + m_pManager->SetTimer(this, FADE_TIMERID, FADE_ELLAPSE); + } + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } } if( event.Type == UIEVENT_SETCURSOR ) { @@ -426,7 +436,7 @@ namespace DuiLib if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, clrColor, \ - NULL, NULL, nLinks, m_uTextStyle); + NULL, NULL, nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, clrColor, \ m_iFont, m_uTextStyle); diff --git a/DuiLib/Control/UIButton.h b/DuiLib/Control/UIButton.h index ceddd780..fda3da2b 100644 --- a/DuiLib/Control/UIButton.h +++ b/DuiLib/Control/UIButton.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CButtonUI : public CLabelUI + class DUILIB_API CButtonUI : public CLabelUI { public: CButtonUI(); diff --git a/DuiLib/Control/UICheckBox.cpp b/DuiLib/Control/UICheckBox.cpp index a0039365..63157e7e 100644 --- a/DuiLib/Control/UICheckBox.cpp +++ b/DuiLib/Control/UICheckBox.cpp @@ -5,7 +5,7 @@ namespace DuiLib { LPCTSTR CCheckBoxUI::GetClass() const { - return _T("CheckBoxUI"); + return DUI_CTR_CHECKBOX; } LPVOID CCheckBoxUI::GetInterface(LPCTSTR pstrName) diff --git a/DuiLib/Control/UICheckBox.h b/DuiLib/Control/UICheckBox.h index dac3c904..0a9bb721 100644 --- a/DuiLib/Control/UICheckBox.h +++ b/DuiLib/Control/UICheckBox.h @@ -9,7 +9,7 @@ namespace DuiLib /// 派生于COptionUI,只是每组只有一个按钮而已,组名为空,配置文件默认属性举例: /// - class UILIB_API CCheckBoxUI : public COptionUI + class DUILIB_API CCheckBoxUI : public COptionUI { public: LPCTSTR GetClass() const; diff --git a/DuiLib/Control/UICombo.cpp b/DuiLib/Control/UICombo.cpp index e10d0429..7257fa87 100644 --- a/DuiLib/Control/UICombo.cpp +++ b/DuiLib/Control/UICombo.cpp @@ -2,6 +2,118 @@ namespace DuiLib { +///////////////////////////////////////////////////////////////////////////////////// +// + +class CComboBodyUI : public CVerticalLayoutUI +{ +public: + CComboBodyUI::CComboBodyUI(CComboUI* pOwner); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + +protected: + CComboUI* m_pOwner; +}; + + +CComboBodyUI::CComboBodyUI(CComboUI* pOwner) : m_pOwner(pOwner) +{ + ASSERT(m_pOwner); +} + +bool CComboBodyUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { + RECT rcTemp = { 0 }; + if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true; + + TListInfoUI* pListInfo = NULL; + if( m_pOwner ) pListInfo = m_pOwner->GetListInfo(); + + CRenderClip clip; + CRenderClip::GenerateClip(hDC, rcTemp, clip); + CControlUI::DoPaint(hDC, rcPaint, pStopControl); + + if( m_items.GetSize() > 0 ) { + RECT rc = m_rcItem; + rc.left += m_rcInset.left; + rc.top += m_rcInset.top; + rc.right -= m_rcInset.right; + rc.bottom -= m_rcInset.bottom; + if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth(); + if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); + + if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) { + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + else { + int iDrawIndex = 0; + CRenderClip childClip; + CRenderClip::GenerateClip(hDC, rcTemp, childClip); + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( !pControl->IsFloat() ) { + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); + if( pListItem != NULL ) { + pListItem->SetDrawIndex(iDrawIndex); + iDrawIndex += 1; + } + if (pListInfo && pListInfo->iHLineSize > 0) { + // 因为没有为最后一个预留分割条长度,如果list铺满,最后一条不会显示 + RECT rcPadding = pControl->GetPadding(); + const RECT& rcPos = pControl->GetPos(); + RECT rcBottomLine = { rcPos.left, rcPos.bottom + rcPadding.bottom, rcPos.right, rcPos.bottom + rcPadding.bottom + pListInfo->iHLineSize }; + if( ::IntersectRect(&rcTemp, &rcPaint, &rcBottomLine) ) { + rcBottomLine.top += pListInfo->iHLineSize / 2; + rcBottomLine.bottom = rcBottomLine.top; + CRenderEngine::DrawLine(hDC, rcBottomLine, pListInfo->iHLineSize, GetAdjustColor(pListInfo->dwHLineColor)); + } + } + } + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + CRenderClip::UseOldClipBegin(hDC, childClip); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + CRenderClip::UseOldClipEnd(hDC, childClip); + } + else { + if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + } + + if( m_pVerticalScrollBar != NULL ) { + if( m_pVerticalScrollBar == pStopControl ) return false; + if (m_pVerticalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { + if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + + if( m_pHorizontalScrollBar != NULL ) { + if( m_pHorizontalScrollBar == pStopControl ) return false; + if (m_pHorizontalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { + if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + return true; +} + ///////////////////////////////////////////////////////////////////////////////////// // // @@ -75,7 +187,7 @@ void CComboWnd::Init(CComboUI* pOwner) HWND hWndParent = m_hWnd; while( ::GetParent(hWndParent) != NULL ) hWndParent = ::GetParent(hWndParent); ::ShowWindow(m_hWnd, SW_SHOW); - ::SendMessage(hWndParent, WM_NCACTIVATE, TRUE, 0L); + //::SendMessage(hWndParent, WM_NCACTIVATE, TRUE, 0L); } LPCTSTR CComboWnd::GetWindowClassName() const @@ -99,11 +211,11 @@ LRESULT CComboWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) // The trick is to add the items to the new container. Their owner gets // reassigned by this operation - which is why it is important to reassign // the items back to the righfull owner/manager when the window closes. - m_pLayout = new CVerticalLayoutUI; + m_pLayout = new CComboBodyUI(m_pOwner); m_pLayout->SetManager(&m_pm, NULL, true); LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(_T("VerticalLayout")); if( pDefaultAttributes ) { - m_pLayout->ApplyAttributeList(pDefaultAttributes); + m_pLayout->SetAttributeList(pDefaultAttributes); } m_pLayout->SetInset(CDuiRect(1, 1, 1, 1)); m_pLayout->SetBkColor(0xFFFFFFFF); @@ -111,7 +223,7 @@ LRESULT CComboWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) m_pLayout->SetBorderSize(1); m_pLayout->SetAutoDestroy(false); m_pLayout->EnableScrollBar(); - m_pLayout->ApplyAttributeList(m_pOwner->GetDropBoxAttributeList()); + m_pLayout->SetAttributeList(m_pOwner->GetDropBoxAttributeList()); for( int i = 0; i < m_pOwner->GetCount(); i++ ) { m_pLayout->Add(static_cast(m_pOwner->GetItemAt(i))); } @@ -130,7 +242,7 @@ LRESULT CComboWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) ::GetCursorPos(&pt); ::ScreenToClient(m_pm.GetPaintWindow(), &pt); CControlUI* pControl = m_pm.FindControl(pt); - if( pControl && _tcscmp(pControl->GetClass(), _T("ScrollBarUI")) != 0 ) PostMessage(WM_KILLFOCUS); + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_SCROLLBAR) != 0 ) PostMessage(WM_KILLFOCUS); } else if( uMsg == WM_KEYDOWN ) { switch( wParam ) { @@ -162,7 +274,22 @@ LRESULT CComboWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; } else if( uMsg == WM_KILLFOCUS ) { - if( m_hWnd != (HWND) wParam ) PostMessage(WM_CLOSE); + if( m_hWnd != (HWND) wParam ) { + HWND hWnd = ::GetFocus(); + HWND hParentWnd = NULL; + bool bIsChildFocus = false; + while( hParentWnd = ::GetParent(hWnd) ) { + if( m_hWnd == hParentWnd ) { + bIsChildFocus = true; + break; + } + hWnd = hParentWnd; + } + if (!bIsChildFocus) { + PostMessage(WM_CLOSE); + return 0; + } + } } LRESULT lRes = 0; @@ -208,8 +335,9 @@ CComboUI::CComboUI() : m_pWindow(NULL), m_iCurSel(-1), m_uButtonState(0) ::ZeroMemory(&m_rcTextPadding, sizeof(m_rcTextPadding)); m_ListInfo.nColumns = 0; + m_ListInfo.uFixedHeight = 0; m_ListInfo.nFont = -1; - m_ListInfo.uTextStyle = DT_VCENTER; + m_ListInfo.uTextStyle = DT_VCENTER | DT_SINGLELINE; m_ListInfo.dwTextColor = 0xFF000000; m_ListInfo.dwBkColor = 0; m_ListInfo.bAlternateBk = false; @@ -219,7 +347,10 @@ CComboUI::CComboUI() : m_pWindow(NULL), m_iCurSel(-1), m_uButtonState(0) m_ListInfo.dwHotBkColor = 0xFFE9F5FF; m_ListInfo.dwDisabledTextColor = 0xFFCCCCCC; m_ListInfo.dwDisabledBkColor = 0xFFFFFFFF; - m_ListInfo.dwLineColor = 0; + m_ListInfo.iHLineSize = 0; + m_ListInfo.dwHLineColor = 0xFF3C3C3C; + m_ListInfo.iVLineSize = 0; + m_ListInfo.dwVLineColor = 0xFF3C3C3C; m_ListInfo.bShowHtml = false; m_ListInfo.bMultiExpandable = false; @@ -231,13 +362,13 @@ CComboUI::CComboUI() : m_pWindow(NULL), m_iCurSel(-1), m_uButtonState(0) LPCTSTR CComboUI::GetClass() const { - return _T("ComboUI"); + return DUI_CTR_COMBO; } LPVOID CComboUI::GetInterface(LPCTSTR pstrName) { + if( _tcscmp(pstrName, DUI_CTR_ILISTOWNER) == 0 ) return static_cast(this); if( _tcscmp(pstrName, DUI_CTR_COMBO) == 0 ) return static_cast(this); - if( _tcscmp(pstrName, _T("IListOwner")) == 0 ) return static_cast(this); return CContainerUI::GetInterface(pstrName); } @@ -273,7 +404,7 @@ bool CComboUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent) if( m_iCurSel >= 0 ) { CControlUI* pControl = static_cast(m_items[m_iCurSel]); if( !pControl ) return false; - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) pListItem->Select(false, bTriggerEvent); m_iCurSel = -1; } @@ -282,7 +413,7 @@ bool CComboUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent) if( iIndex >= m_items.GetSize() ) iIndex = m_items.GetSize() - 1; CControlUI* pControl = static_cast(m_items[iIndex]); if( !pControl || !pControl->IsVisible() || !pControl->IsEnabled() ) return false; - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem == NULL ) return false; m_iCurSel = iIndex; if( m_pWindow != NULL || bTakeFocus ) pControl->SetFocus(); @@ -293,21 +424,56 @@ bool CComboUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent) return true; } -bool CComboUI::SetItemIndex(CControlUI* pControl, int iIndex) +bool CComboUI::ExpandItem(int iIndex, bool bExpand) +{ + return false; +} + +int CComboUI::GetExpandedItem() const +{ + return -1; +} + +bool CComboUI::SetItemIndex(CControlUI* pControl, int iNewIndex) { int iOrginIndex = GetItemIndex(pControl); if( iOrginIndex == -1 ) return false; - if( iOrginIndex == iIndex ) return true; + if( iOrginIndex == iNewIndex ) return true; + + IListItemUI* pSelectedListItem = NULL; + if( m_iCurSel >= 0 ) pSelectedListItem = + static_cast(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM)); + if( !CContainerUI::SetItemIndex(pControl, iNewIndex) ) return false; + int iMinIndex = min(iOrginIndex, iNewIndex); + int iMaxIndex = max(iOrginIndex, iNewIndex); + for(int i = iMinIndex; i < iMaxIndex + 1; ++i) { + CControlUI* p = GetItemAt(i); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); + if( pListItem != NULL ) { + pListItem->SetIndex(i); + } + } + if( m_iCurSel >= 0 && pSelectedListItem != NULL ) m_iCurSel = pSelectedListItem->GetIndex(); + return true; +} + +bool CComboUI::SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex) +{ + if (pStartControl == NULL || iCount < 0 || iNewStartIndex < 0) return false; + int iStartIndex = GetItemIndex(pStartControl); + if (iStartIndex == iNewStartIndex) return true; + if (iStartIndex + iCount > GetCount()) return false; + if (iNewStartIndex + iCount > GetCount()) return false; IListItemUI* pSelectedListItem = NULL; if( m_iCurSel >= 0 ) pSelectedListItem = - static_cast(GetItemAt(m_iCurSel)->GetInterface(_T("ListItem"))); - if( !CContainerUI::SetItemIndex(pControl, iIndex) ) return false; - int iMinIndex = min(iOrginIndex, iIndex); - int iMaxIndex = max(iOrginIndex, iIndex); + static_cast(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM)); + if( !CContainerUI::SetMultiItemIndex(pStartControl, iCount, iNewStartIndex) ) return false; + int iMinIndex = min(iStartIndex, iNewStartIndex); + int iMaxIndex = max(iStartIndex + iCount, iNewStartIndex + iCount); for(int i = iMinIndex; i < iMaxIndex + 1; ++i) { CControlUI* p = GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -318,7 +484,7 @@ bool CComboUI::SetItemIndex(CControlUI* pControl, int iIndex) bool CComboUI::Add(CControlUI* pControl) { - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetOwner(this); @@ -332,7 +498,7 @@ bool CComboUI::AddAt(CControlUI* pControl, int iIndex) if (!CContainerUI::AddAt(pControl, iIndex)) return false; // The list items should know about us - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetOwner(this); pListItem->SetIndex(iIndex); @@ -340,7 +506,7 @@ bool CComboUI::AddAt(CControlUI* pControl, int iIndex) for(int i = iIndex + 1; i < GetCount(); ++i) { CControlUI* p = GetItemAt(i); - pListItem = static_cast(p->GetInterface(_T("ListItem"))); + pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -349,16 +515,16 @@ bool CComboUI::AddAt(CControlUI* pControl, int iIndex) return true; } -bool CComboUI::Remove(CControlUI* pControl) +bool CComboUI::Remove(CControlUI* pControl, bool bDoNotDestroy) { int iIndex = GetItemIndex(pControl); if (iIndex == -1) return false; - if (!CContainerUI::RemoveAt(iIndex)) return false; + if (!CContainerUI::RemoveAt(iIndex, bDoNotDestroy)) return false; for(int i = iIndex; i < GetCount(); ++i) { CControlUI* p = GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -373,13 +539,13 @@ bool CComboUI::Remove(CControlUI* pControl) return true; } -bool CComboUI::RemoveAt(int iIndex) +bool CComboUI::RemoveAt(int iIndex, bool bDoNotDestroy) { - if (!CContainerUI::RemoveAt(iIndex)) return false; + if (!CContainerUI::RemoveAt(iIndex, bDoNotDestroy)) return false; for(int i = iIndex; i < GetCount(); ++i) { CControlUI* p = GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) pListItem->SetIndex(i); } @@ -436,49 +602,47 @@ void CComboUI::DoEvent(TEventUI& event) } if( event.Type == UIEVENT_KEYDOWN ) { - switch( event.chKey ) { - case VK_F4: - Activate(); - return; - case VK_UP: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(m_iCurSel - 1, false)); - SetSelectCloseFlag(true); - return; - case VK_DOWN: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(m_iCurSel + 1, true)); - SetSelectCloseFlag(true); - return; - case VK_PRIOR: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(m_iCurSel - 1, false)); - SetSelectCloseFlag(true); - return; - case VK_NEXT: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(m_iCurSel + 1, true)); - SetSelectCloseFlag(true); - return; - case VK_HOME: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(0, false)); - SetSelectCloseFlag(true); - return; - case VK_END: - SetSelectCloseFlag(false); - SelectItem(FindSelectable(GetCount() - 1, true)); - SetSelectCloseFlag(true); + if (IsKeyboardEnabled() && IsEnabled()) { + switch( event.chKey ) { + case VK_F4: + Activate(); + case VK_UP: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(m_iCurSel - 1, false)); + SetSelectCloseFlag(true); + case VK_DOWN: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(m_iCurSel + 1, true)); + SetSelectCloseFlag(true); + case VK_PRIOR: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(m_iCurSel - 1, false)); + SetSelectCloseFlag(true); + case VK_NEXT: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(m_iCurSel + 1, true)); + SetSelectCloseFlag(true); + case VK_HOME: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(0, false)); + SetSelectCloseFlag(true); + case VK_END: + SetSelectCloseFlag(false); + SelectItem(FindSelectable(GetCount() - 1, true)); + SetSelectCloseFlag(true); + } return; } } if( event.Type == UIEVENT_SCROLLWHEEL ) { - bool bDownward = LOWORD(event.wParam) == SB_LINEDOWN; - SetSelectCloseFlag(false); - SelectItem(FindSelectable(m_iCurSel + (bDownward ? 1 : -1), bDownward)); - SetSelectCloseFlag(true); - return; + if (IsEnabled()) { + bool bDownward = LOWORD(event.wParam) == SB_LINEDOWN; + SetSelectCloseFlag(false); + SelectItem(FindSelectable(m_iCurSel + (bDownward ? 1 : -1), bDownward)); + SetSelectCloseFlag(true); + return; + } } if( event.Type == UIEVENT_CONTEXTMENU ) { @@ -487,26 +651,36 @@ void CComboUI::DoEvent(TEventUI& event) if( event.Type == UIEVENT_MOUSEENTER ) { if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { - if( (m_uButtonState & UISTATE_HOT) == 0 ) - m_uButtonState |= UISTATE_HOT; - Invalidate(); + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } } - return; } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( (m_uButtonState & UISTATE_HOT) != 0 ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; } - return; } CControlUI::DoEvent(event); } SIZE CComboUI::EstimateSize(SIZE szAvailable) { - if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 12); + if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8); return CControlUI::EstimateSize(szAvailable); } @@ -647,12 +821,33 @@ TListInfoUI* CComboUI::GetListInfo() return &m_ListInfo; } +UINT CComboUI::GetItemFixedHeight() +{ + return m_ListInfo.uFixedHeight; +} + +void CComboUI::SetItemFixedHeight(UINT nHeight) +{ + m_ListInfo.uFixedHeight = nHeight; + Invalidate(); +} + +int CComboUI::GetItemFont(int index) +{ + return m_ListInfo.nFont; +} + void CComboUI::SetItemFont(int index) { m_ListInfo.nFont = index; Invalidate(); } +UINT CComboUI::GetItemTextStyle() +{ + return m_ListInfo.uTextStyle; +} + void CComboUI::SetItemTextStyle(UINT uStyle) { m_ListInfo.uTextStyle = uStyle; @@ -808,14 +1003,44 @@ LPCTSTR CComboUI::GetDisabledItemImage() const return m_ListInfo.diDisabled.sDrawString; } -DWORD CComboUI::GetItemLineColor() const +int CComboUI::GetItemHLineSize() const +{ + return m_ListInfo.iHLineSize; +} + +void CComboUI::SetItemHLineSize(int iSize) +{ + m_ListInfo.iHLineSize = iSize; +} + +DWORD CComboUI::GetItemHLineColor() const +{ + return m_ListInfo.dwHLineColor; +} + +void CComboUI::SetItemHLineColor(DWORD dwLineColor) +{ + m_ListInfo.dwHLineColor = dwLineColor; +} + +int CComboUI::GetItemVLineSize() const { - return m_ListInfo.dwLineColor; + return m_ListInfo.iVLineSize; } -void CComboUI::SetItemLineColor(DWORD dwLineColor) +void CComboUI::SetItemVLineSize(int iSize) { - m_ListInfo.dwLineColor = dwLineColor; + m_ListInfo.iVLineSize = iSize; +} + +DWORD CComboUI::GetItemVLineColor() const +{ + return m_ListInfo.dwVLineColor; +} + +void CComboUI::SetItemVLineColor(DWORD dwLineColor) +{ + m_ListInfo.dwVLineColor = dwLineColor; } bool CComboUI::IsItemShowHtml() @@ -871,6 +1096,7 @@ void CComboUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) szDropBoxSize.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); SetDropBoxSize(szDropBoxSize); } + else if( _tcscmp(pstrName, _T("itemheight")) == 0 ) m_ListInfo.uFixedHeight = _ttoi(pstrValue); else if( _tcscmp(pstrName, _T("itemfont")) == 0 ) m_ListInfo.nFont = _ttoi(pstrValue); else if( _tcscmp(pstrName, _T("itemalign")) == 0 ) { if( _tcsstr(pstrValue, _T("left")) != NULL ) { @@ -948,19 +1174,31 @@ void CComboUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) SetDisabledItemBkColor(clrColor); } else if( _tcscmp(pstrName, _T("itemdisabledimage")) == 0 ) SetDisabledItemImage(pstrValue); - else if( _tcscmp(pstrName, _T("itemlinecolor")) == 0 ) { + else if( _tcscmp(pstrName, _T("itemvlinesize")) == 0 ) { + SetItemVLineSize(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("itemvlinecolor")) == 0 ) { if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - SetItemLineColor(clrColor); + SetItemVLineColor(clrColor); + } + else if( _tcscmp(pstrName, _T("itemhlinesize")) == 0 ) { + SetItemHLineSize(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("itemhlinecolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetItemHLineColor(clrColor); } else if( _tcscmp(pstrName, _T("itemshowhtml")) == 0 ) SetItemShowHtml(_tcscmp(pstrValue, _T("true")) == 0); else CContainerUI::SetAttribute(pstrName, pstrValue); } -void CComboUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CComboUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { - CControlUI::DoPaint(hDC, rcPaint, pStopControl); + return CControlUI::DoPaint(hDC, rcPaint, pStopControl); } void CComboUI::PaintStatusImage(HDC hDC) @@ -998,7 +1236,7 @@ void CComboUI::PaintText(HDC hDC) if( m_iCurSel >= 0 ) { CControlUI* pControl = static_cast(m_items[m_iCurSel]); - IListItemUI* pElement = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pElement = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pElement != NULL ) { pElement->DrawItemText(hDC, rcText); } diff --git a/DuiLib/Control/UICombo.h b/DuiLib/Control/UICombo.h index 7f4b8e32..fec2f872 100644 --- a/DuiLib/Control/UICombo.h +++ b/DuiLib/Control/UICombo.h @@ -9,7 +9,7 @@ namespace DuiLib { class CComboWnd; -class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI +class DUILIB_API CComboUI : public CContainerUI, public IListOwnerUI { friend class CComboWnd; public: @@ -33,12 +33,15 @@ class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI bool GetSelectCloseFlag(); void SetSelectCloseFlag(bool flag); bool SelectItem(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true); + bool ExpandItem(int iIndex, bool bExpand = true); + int GetExpandedItem() const; - bool SetItemIndex(CControlUI* pControl, int iIndex); + bool SetItemIndex(CControlUI* pControl, int iNewIndex); + bool SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex); bool Add(CControlUI* pControl); bool AddAt(CControlUI* pControl, int iIndex); - bool Remove(CControlUI* pControl); - bool RemoveAt(int iIndex); + bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); + bool RemoveAt(int iIndex, bool bDoNotDestroy=false); void RemoveAll(); bool Activate(); @@ -59,7 +62,11 @@ class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI void SetDisabledImage(LPCTSTR pStrImage); TListInfoUI* GetListInfo(); + UINT GetItemFixedHeight(); + void SetItemFixedHeight(UINT nHeight); + int GetItemFont(int index); void SetItemFont(int index); + UINT GetItemTextStyle(); void SetItemTextStyle(UINT uStyle); RECT GetItemTextPadding() const; void SetItemTextPadding(RECT rc); @@ -89,8 +96,14 @@ class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI void SetDisabledItemBkColor(DWORD dwBkColor); LPCTSTR GetDisabledItemImage() const; void SetDisabledItemImage(LPCTSTR pStrImage); - DWORD GetItemLineColor() const; - void SetItemLineColor(DWORD dwLineColor); + int GetItemHLineSize() const; + void SetItemHLineSize(int iSize); + DWORD GetItemHLineColor() const; + void SetItemHLineColor(DWORD dwLineColor); + int GetItemVLineSize() const; + void SetItemVLineSize(int iSize); + DWORD GetItemVLineColor() const; + void SetItemVLineColor(DWORD dwLineColor); bool IsItemShowHtml(); void SetItemShowHtml(bool bShowHtml = true); @@ -100,7 +113,7 @@ class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI void DoEvent(TEventUI& event); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void PaintText(HDC hDC); void PaintStatusImage(HDC hDC); diff --git a/DuiLib/Control/UIDateTime.cpp b/DuiLib/Control/UIDateTime.cpp index 348f2be5..22e74f6e 100644 --- a/DuiLib/Control/UIDateTime.cpp +++ b/DuiLib/Control/UIDateTime.cpp @@ -203,7 +203,7 @@ namespace DuiLib LPCTSTR CDateTimeUI::GetClass() const { - return _T("DateTimeUI"); + return DUI_CTR_DATETIME; } LPVOID CDateTimeUI::GetInterface(LPCTSTR pstrName) @@ -258,6 +258,32 @@ namespace DuiLib } } + void CDateTimeUI::SetPos(RECT rc, bool bNeedInvalidate) + { + CControlUI::SetPos(rc, bNeedInvalidate); + if( m_pWindow != NULL ) { + RECT rcPos = m_pWindow->CalPos(); + if (::IsRectEmpty(&rcPos)) ::ShowWindow(m_pWindow->GetHWND(), SW_HIDE); + else { + ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, + rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); + } + } + } + + void CDateTimeUI::Move(SIZE szOffset, bool bNeedInvalidate) + { + CControlUI::Move(szOffset, bNeedInvalidate); + if( m_pWindow != NULL ) { + RECT rcPos = m_pWindow->CalPos(); + if (::IsRectEmpty(&rcPos)) ::ShowWindow(m_pWindow->GetHWND(), SW_HIDE); + else { + ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, + rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); + } + } + } + void CDateTimeUI::DoEvent(TEventUI& event) { if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) { @@ -320,14 +346,6 @@ namespace DuiLib { return; } - if( event.Type == UIEVENT_MOUSEENTER ) - { - return; - } - if( event.Type == UIEVENT_MOUSELEAVE ) - { - return; - } CLabelUI::DoEvent(event); } diff --git a/DuiLib/Control/UIDateTime.h b/DuiLib/Control/UIDateTime.h index 751d8c1c..76950972 100644 --- a/DuiLib/Control/UIDateTime.h +++ b/DuiLib/Control/UIDateTime.h @@ -8,7 +8,7 @@ namespace DuiLib class CDateTimeWnd; /// 时间选择控件 - class UILIB_API CDateTimeUI : public CLabelUI + class DUILIB_API CDateTimeUI : public CLabelUI { friend class CDateTimeWnd; public: @@ -26,6 +26,9 @@ namespace DuiLib void UpdateText(); + void SetPos(RECT rc, bool bNeedInvalidate = true); + void Move(SIZE szOffset, bool bNeedInvalidate = true); + void DoEvent(TEventUI& event); protected: diff --git a/DuiLib/Control/UIEdit.cpp b/DuiLib/Control/UIEdit.cpp index ca238b0b..4cd3cf80 100644 --- a/DuiLib/Control/UIEdit.cpp +++ b/DuiLib/Control/UIEdit.cpp @@ -40,6 +40,10 @@ namespace DuiLib m_pOwner = pOwner; RECT rcPos = CalPos(); UINT uStyle = WS_CHILD | ES_AUTOHSCROLL | pOwner->GetWindowStyls(); + UINT uTextStyle = m_pOwner->GetTextStyle(); + if(uTextStyle & DT_LEFT) uStyle |= ES_LEFT; + else if(uTextStyle & DT_CENTER) uStyle |= ES_CENTER; + else if(uTextStyle & DT_RIGHT) uStyle |= ES_RIGHT; if( m_pOwner->IsPasswordMode() ) uStyle |= ES_PASSWORD; Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos); @@ -249,7 +253,7 @@ namespace DuiLib LPCTSTR CEditUI::GetClass() const { - return _T("EditUI"); + return DUI_CTR_EDIT; } LPVOID CEditUI::GetInterface(LPCTSTR pstrName) @@ -339,22 +343,33 @@ namespace DuiLib { return; } - if( event.Type == UIEVENT_MOUSEENTER ) - { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); - } - return; - } - if( event.Type == UIEVENT_MOUSELEAVE ) - { - if( IsEnabled() ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); - } - return; - } + if( event.Type == UIEVENT_MOUSEENTER ) + { + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } + } + } + if( event.Type == UIEVENT_MOUSELEAVE ) + { + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } + } CLabelUI::DoEvent(event); } @@ -543,8 +558,11 @@ namespace DuiLib CControlUI::SetPos(rc, bNeedInvalidate); if( m_pWindow != NULL ) { RECT rcPos = m_pWindow->CalPos(); - ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, - rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE); + if (::IsRectEmpty(&rcPos)) ::ShowWindow(m_pWindow->GetHWND(), SW_HIDE); + else { + ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, + rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); + } } } @@ -552,9 +570,12 @@ namespace DuiLib { CControlUI::Move(szOffset, bNeedInvalidate); if( m_pWindow != NULL ) { - RECT rcPos = m_pWindow->CalPos(); - ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, - rcPos.bottom - rcPos.top, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + RECT rcPos = m_pWindow->CalPos(); + if (::IsRectEmpty(&rcPos)) ::ShowWindow(m_pWindow->GetHWND(), SW_HIDE); + else { + ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, + rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); + } } } @@ -571,7 +592,7 @@ namespace DuiLib SIZE CEditUI::EstimateSize(SIZE szAvailable) { - if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetFontInfo(GetFont())->tm.tmHeight + 6); + if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetFontInfo(GetFont())->tm.tmHeight + 8); return CControlUI::EstimateSize(szAvailable); } diff --git a/DuiLib/Control/UIEdit.h b/DuiLib/Control/UIEdit.h index 22d16ac0..a9dca158 100644 --- a/DuiLib/Control/UIEdit.h +++ b/DuiLib/Control/UIEdit.h @@ -7,7 +7,7 @@ namespace DuiLib { class CEditWnd; - class UILIB_API CEditUI : public CLabelUI + class DUILIB_API CEditUI : public CLabelUI { friend class CEditWnd; public: diff --git a/DuiLib/Control/UIGifAnim.cpp b/DuiLib/Control/UIGifAnim.cpp index d6b0e3b64872d1a1c46cbe2cfcd5227efeba7878..85a9ea73f352bee6af3edc4cad4c9f92c51c65b4 100644 GIT binary patch literal 18374 zcmeI4$!;9S8OQq;41pYS%&lc3!dQ`MIRSErV*@fNQ$#3<;37Fz41yeyGGUS;W~j}M zbMno|W8^9F9(j#iax>uM|Eq7lsinJT5v@1|i~%)0-BtDNYgOw%-@REKS7+6rI;oyk zkE+9}uHLA&s|#Jl4wsS-n-gSM>sAb)dPPJgG%L{5uox;K;GAN8;wb{=U$! zbA5C7B=Gn`T;12mI(#$kK=+wlS5GvSt3$1~q%kkUZ`MB2)79!hbx%01>iUy_>vpv( zEO&%ibM#2_hm!0--%Hh(nzJPQkvOpVX5AN>ThII;(R2=&f)TVF2U;V2&vnP{LlIYK zmhk}$27&IO?wyGbr+WIZx+9K$EY5H0dq;fzw1Jgj;81*KUCn})@(ixSli3s-G#`H~ z2|d+JqJ_Vs)apd0*wXgCb>nOkd(Cz2(a_fo%{N51+fz(3KLv+A*)4|H`Zz1kBM$CAt8 z6n+>Vd>p!Ja!104S_SC79ypEkL3g1J{i?+`Jd8n1M=a~vPS6czpcfHCn==o7^_WAa zf(PwbQeC}Wy{muW2RimdxYl}#oa*ZHaOb)Ht!3MX@>-AeXETu~95Ty+!$=1zc=DF8 z{7Tp64Q|Op?8pZHB<}rqY;Q+?4)3-lI^2e4Ti;K%XPRx={*&!_yfD4^A#LwLu)a5C zqeMuo6#Kt7j-sFF4zV}?y(@byXRHM8gD0{%eR-xYWbw7^1-}%Z?8jk_ba!84MF zkaIv6K8vjGXw11<(O_2|ZC&)<6YN_pJSzQO(-S^unPu_OxVk=$8Xh(CyKS?HtHhCf zWF6vd^S-TcC~jFyDWyC=E;m~!Sqv9j0a;pPo+Y(5+-@e>r%4VE1V{1=j=N3iplOG5 zX-pgJ2bX~TV65l!L2u`4JMCl=XCXe5J;YdcO?NF?!;1rrdLk`=SA&qFIM1$)^$E+p zEZ5rcZs*(U#(Oc2?}}Srh!f|scgy2ql`~7vQcw0MNCG~Ru}$}9dG%6yG$P55=d&d5 z;QBTa7s=0wJFDWuv9f%!e=07<^`xbFolNEYdwtsO$4Ei8*$Zp*^nEJ-d_G=hUB8G1 zhq}+_ef`}Hb>K$u>v8<1>IADOhm!NliL|H9I+Jf5j%{g0vytq@1kMdX=mpFSr*!nD zMxz7N9ayPhR?avO79(Y#)KgDX?-AKvPS&@Im5K!F4Msj=TdU*OoQ5OKH-F!p^tY0E_97nx6DDNb+EqTP9u?&s3hRuED7KZI~T-Jlm!2zU;ZNZ6> zo^#=fzTDLq_*Dz<6j!nv=Iv?JKw}3Qb*?+*JUBa@68Q1HK6Q0NfBee%03KG&4+L!x z_;^wMp_Sv;BG$6fj%P7s;DLI@QpO0?$y#OdUHF~)xhEmb1qq)3(HZaDPx8cr z;u(D<^az`Gep9=>Q`kkD{t?@|;N=*&jT&$1N0oR)o_Q>5#*mt z>}B?6`e1Cb%TM2z-m}v{Rgn4?*QEbJBW;^TrOxX@8v4oQFvIQdqWO<<^9p(8)3r>UYMgh%sDtsIHwQw5VIi9liK| zsKb89ze;#mWj)DPOX@spd;Qe8Po8d>ZMyB6;rRqy_Ir`{&euh)sno-!m23x36Lq!S zN{CFODqqdLuSLCKqVIL}7k!%XtvRyHYOo38Wfw$`vMIbc3u=hJr57Rsc4fx~k7)WV z_zF5^~%F@v_HWp;xjt}cUgSQnetjE z*8s4}pLvi zn@7IxWq9OkEXpJ2ZM3aaGM?2&eev;R-0W|ePvE)RXY@MmOFSbs{zkdym5N~=Z6Mvn zI|(`4Q+X?DGcu{ZKEBI$E$Eiv(AB4)DmG7GS;Ip`{5{bSbLX<>@Ts7Xx4o-M&2e*n z&|9Z^h!~|6UHQz`h^rW;&8ppOI?rakx+8*=*>J4cd749wKCTxiHBB$2m*%94YmU=D zU3acbf&V(Sr;E#Ny^;C2?D4uM-)%KFS~V@kkSl>lH}}h)lY7~DyjvL++bp-6`-@uR z>*ObEPqRg{`Dj7^5B#52si%@KzL|~WzLEOoiM+_8ab|-r;&cPM0ajIZt44DZd-PSo>Fg9HM5&fr^CCo=Goi>md{MTo4y~*Fzlm;T@7^>J%f?1Z1*KX^1KXO z)&e%G!T+8sPdXM?(s^|LMjA)Intj^m!rJFNEGVeM2_PhLSzPJH)1RZ7>&6OSoN_7l z7z}=@=aG7&rCnxiyo@u!=IRuD9x8qj%Tk@OUB5Hcjd=%r7W}U0>g#|@Ic7&1{y2%V zmb2R#n~0M^F6a85l5wXm8M6a=F6$uj(jDoV;W+_)0`i1GkXocT<;Sa1y%@Eo7tSeu zO{Y1qHH-x9H z@#XltCk?cHrckAj($c|mQ=unAou1oFQbPBpWW>bgY zt5X^|?09xr={)!zh5ZcMx0&B!9P@6-#5L!W)9V@noGw4zz89H}E-Q(0hVyB5j@RsN zdz9vUtL?>Mak2OA5^riuInFetyQc7!kZf9^JFiR@%_^oXzg~3j5t#Glc&6W_#7Y^M z#`ddU>oaRC8Pc!xSB{G@7akZ~uR+WD3+?);MossXyK2>*spgv;enu z&yanmti7*k`rY)fUHP-;pG0TdOITBug4LPsHFK9~nXz{P+}fJ6*TU}Kd8kC$ldcsZ z+0}}7$WNTc7+=d#%gUu~A8}n8ZJ~&D1vA;Gz%C#dey=Nyuc#uz17aX889w>|RD0!4vZAT((ZtH2)tlaL?bA zX5>9Rr>@TGta@=nQ6W92;d>6I#dNIjs+JSDeK6-kojqp<*D^~+@xDo0giOzpK2qJ~ zxuK1=3f(;8Bgw_y6N&i?Cz$MHlkHG=7jZPHd2O8);pBVsd4wVUk@s6|xh08>1cy^3 zob7N5(^@j_Hoxksc4Cw@mj!(!K5_bkQ&8MPy6J9JPb0j7uN7_JV!Iq%D~WdLdqP-k zT!Hy^#)~Lydl>$-pTKI{RX{t}gzsJbZ3*`k{%-b>u=?nZqkoMq^Xn zI?o&q_Uyc!=3$!W==}}3RL89scPxk=Ezu)~iG4QTPO$ez%u4A<4&{TH;qi|rewxFq z^*B&=HJrB~URm|m?v-4-a~p$d@Lvv{VNNHG1k)%==`o*O&h7Sr4lUZJY0;uy4L9(`E!R83Fj&%hIZG2JKN2jg20 zC8X$wW_1X7-^#l+Ci(W>z#YNko&I5{RwJclw2K)}%C)o#aBk!jq1J$fVRGXE?q0_L= zKr7OP@O6=DBprP;2H=L}^!n>`A688MF-gAcVowK&)G z&kRoF&on*Z1eR$SXU*`N(?)|O{W|)ADTeT;glb*|Tg8szNjCo-_bE5Tqmg*S3RKUO!;%CFtt|x IH;Sd|zmhw^oB#j- literal 9127 zcmeHNTW{OS5q_qA#UuwcD2KkB7U+Xq8&D+KCMsVbOL0!zK%k|SMOY#Qk&0vcq`$r2 z%w9;zvJ*E5(1!*%iMYFS*|~f(yL*0%lfh&$RP^>DAJ#`-x5sZQzqzqqcodK7Nj&A@ z%FeI(Q)#vu?RuxxKdzrP+b#e2Q+Qt8^LBQqo)CXfJXA>@k7AWkL=W+dM)5>ZK8|u4 zM;To!l~6iUi5gb&`HF-d&8}2?iAFQ1J%iXiiBqRaYnVkNxv{_xQ7A1qQ4lPtq!x)-1~Nxn1qV zgN(=H>qV}zfUq^lJ5u=}c-7s+cEvjk+pTVR(!%n1s)B+1J>|dmn8#qCGSCm^D#}$r z({vb*?nNVBl2yD(n%vMJozD7M{GgWf06mXoy!SX)Q?S9hIT)%TMahsBNincZ-LcA) zVThTh{0I!E(LJ0*Tfb90q9o1fUgdO~q<0DVYWrpzlQ9&6a}+E##ICEAZv@Y`PP?5y zevS9KjpKS}z5Af?|Gj5|@~6FbxmWoO2^lAf&XA&?kiF*Lo||Y)(oA8-A3s#de)RaO zqQ2&8ZeYOD`Crm_NShDABFW+#WIX~VC!|}Tb89q-ZnEm0r8OW>Vl1En?ocfrFW1$*mFU6>86m6P&GtqaB7;L#q=SN!_Jp}V}Y6=Q>-lt(h`@tn=VmO={FXr z1j)R*wSrq+;FHD=ffz+#EO5Jk(bQAJ6x5e5QeUnoFY8y(57H#dNoUz617SedX*!{J zpf%h4A=OH}OS-+5_cMz3k_YX`LTgtP0@6V?%<=$`w-RTjyx2hdHFa^PQenGgvuL2G zxrp2Gb>*>A@fxNk_rhAO_$^6Mt$2?W&ztsVSQAd88|8W4zIWPdxA*k;`5c9Ep5Jr) zE>9(gb4Y8XizMfX-91kz^zeC_#d(}2rHSh>t1t5Od=lOBdK6ZrWtfQzR1uySMTmPh z!^?s7rHP97t+KMKf3M$GQ%zK^urnVqEW13366|rlb@0!4GU=kW&3!4@0kuA$cJ#Yp z>!cqx3F}3S*FJA_FS;En1k`E>|HdTBGQWyahoIFqoU42R;OTe$x6a;gSuV5%n-6DT zyTT<*fK?-S%O@*mhMIN?vy$-)bf58_ru+5{=-xL|{%4KxKwal~_IUMpZryW-5k+BO#h;$O}z&$-Fk&^hTMpNmyXE}8Z-vy8(R zS*BOepMSd4a)TCC7!gq@3c`X;rph7YEg>)H!sJUdiHA5{Fg#dHTnnvMf1|EJszUHK zfT|hg(epS{cD&9ZU3m=0X}?s7kW=Q%z=05yk*=s(Yw>=Go8j>UQjA6t8!u_Z3w~51 zVYaRUIgNP5a~e4m(8Y^ULg-AnP zH>=E{+&*j_AP4{rSJVD-lkk}~>Gxgc#(I!tq-&b}!U|aerml*^uFn_oz%r7EL+HZM zc6%C0pEV9|MBuQn&YLCr*O{lRa?yBjF<$9A1cP{d>tH!!IP;d&w@uP|6tHOijQY>H z@pXExdJ&!%2mQSM%k^7t0=n4_1A^LVG{ooOJe~4ghYw6}xFJTAKw8@-m?nv%jY~5n zx`Q>!+plsoJac6P&}Wud+QmAq z?Knf($qon}eY!DdBYDMr0&{kW0bn_dzpCM7Jj};HMi+acsvfP1N4U+9rN=718Rt*d znqj?|+Y1M^wmG4V4P%!B+I1Q@faV>5Zf&BM%50J9OThg`Z&!E6;N%%AmA1qJ%7Nf4 zWWZfgY1QIS_>SfZ$C%Y++C;0P)&;ULhca;+g;yKTE|Tmeh>UNr3}EOrda+lJj7 z_t*qQO@qF!#1we_+(FUv)*&7^+Kt(>FbwOzd$&4TrN6*zB@;+DB^R!)^!*Q3)Mo;+ zIAfVp-jV|>AoKaF)N8`t77E-UmZOsKlV&(294&Bvw@(gTmcf`?09kIq=V%_y#_=Gd z8}p+$@p*P=n~#I~v{6nN#+Lbj;cR=NM!3pxpQx#&uQ@0CmYZBzd!6QaIxVI_y9V?w z09b>(j?4Hj${b8L>~2}qa+4$sIQX3vMElL9ONG_C=nermIl#o{Q9cI3Ji@l^^Y?#r zTL4S6(xr^o7ox*EMnepvpkwVY#q)=5{2I7d!f`=v-?{Q)O+yauCSlA?LPurkVm?qT zP*+Ldp8w)f+=2Sl?J#RiXZbx^ZF8*hG7<9*$CP3Z0$HAZ{-Lqa1D9L!ejyEkP!&go zfR0+HtxnkJcUtvkK>Qxkzrcll%M5U226To8gnsK|c+m|{j{^D^c8x!>xZdq{!uP#y ztABddIjLhYlW2UCy%{z3DLnm9Z--6uI@QNVuZ7)QL%Cb6xHGTZy0E@dYlXuTzIL(h zh7A`{%=)UMBF+wJzPQ?Hk8%UTF1{keK^hRxtJQeD7)hHB=Sn6C%({R!hIhO~Yog

g5>7%w{Lw~W!TebIz{tBDBMYUEi5nv!$%S#xf{@5%P|CHZNV-FjC)<+w>NEZevGugv8U3#H=aTCRe?$PKyHoT))@bx$6*)o zWnszOHpb{dZM#P~Ek``7(clT$_d<;?$MFyd2NXBw^3d=kgZz6zj@-u=Ui_emH17`L~O}k5}6W9Kf#f)-1|m%V}?>jzTSvwT{HL+ z(v@KGXHf3DAjkImag1{j^&N=Q$gw8AIQrHC+;@WRzk|1z&`ql-Ao~>DbUVF_ZB|1E zZ4xdneE5rd>J=ZGi!Mtf(Xm?UXHxQ!Po+A4qNeHm-WQ=3!zE-*r!Ny6!bX7Rfq_@_ z5=I8DdF2^n_I@!6GIR+2+=0FBDvpoZXYcE68iN9A!ugZ*I-1nw^mlZEZu>C&*g^r; z@gaJ0k;3^|Q~2^#wS?_-aO*QOogGs(9n7#-3;;q{i-Hk$7@{-5{}3SW1}xs%(sl-V z`YbutS_$KTx}9DN$cPJ1mV&O+wvpP{n=sf7m@N<2YJB&g8TyVCq4GwSqq*gO<+Rww zGt32EWET8jga~qs&Td_TGl#8%4jRHJlPgk0zqLUx!O_`S0TafNQtvsK3di1Pw^qJY F{sUvxqc8vf diff --git a/DuiLib/Control/UIGifAnim.h b/DuiLib/Control/UIGifAnim.h index e1630922..de8312ab 100644 --- a/DuiLib/Control/UIGifAnim.h +++ b/DuiLib/Control/UIGifAnim.h @@ -9,7 +9,7 @@ namespace DuiLib #define EVENT_TIEM_ID 100 - class UILIB_API CGifAnimUI : public CControlUI + class DUILIB_API CGifAnimUI : public CControlUI { public: CGifAnimUI(void); @@ -18,7 +18,7 @@ namespace DuiLib LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); void DoInit() override; - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void DoEvent(TEventUI& event); void SetVisible(bool bVisible = true ); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); diff --git a/DuiLib/Control/UILabel.cpp b/DuiLib/Control/UILabel.cpp index fbc8c686..23d63555 100644 --- a/DuiLib/Control/UILabel.cpp +++ b/DuiLib/Control/UILabel.cpp @@ -15,6 +15,7 @@ namespace DuiLib m_dwDisabledTextColor(0), m_iFont(-1), m_bShowHtml(false), + m_bNeedEstimateSize(true), m_EnableEffect(false), m_bEnableLuminous(false), m_fLuminousFuzzy(3), @@ -32,9 +33,14 @@ namespace DuiLib m_ShadowOffset.Y = 0.0f; m_ShadowOffset.Width = 0.0f; m_ShadowOffset.Height = 0.0f; - GdiplusStartup( &m_gdiplusToken,&m_gdiplusStartupInput, NULL); + m_cxyFixedLast.cx = m_cxyFixedLast.cy = 0; + m_szAvailableLast.cx = m_szAvailableLast.cy = 0; ::ZeroMemory(&m_rcTextPadding, sizeof(m_rcTextPadding)); + +#ifdef _USE_GDIPLUS + GdiplusStartup( &m_gdiplusToken,&m_gdiplusStartupInput, NULL); +#endif } CLabelUI::~CLabelUI() @@ -44,23 +50,39 @@ namespace DuiLib #else if( m_pWideText ) delete[] m_pWideText; #endif + +#ifdef _USE_GDIPLUS GdiplusShutdown( m_gdiplusToken ); +#endif } LPCTSTR CLabelUI::GetClass() const { - return _T("LabelUI"); + return DUI_CTR_LABEL; } LPVOID CLabelUI::GetInterface(LPCTSTR pstrName) { - if( _tcscmp(pstrName, _T("Label")) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_LABEL) == 0 ) return static_cast(this); return CControlUI::GetInterface(pstrName); } + void CLabelUI::SetFixedWidth(int cx) + { + m_bNeedEstimateSize = true; + CControlUI::SetFixedWidth(cx); + } + + void CLabelUI::SetFixedHeight(int cy) + { + m_bNeedEstimateSize = true; + CControlUI::SetFixedHeight(cy); + } + void CLabelUI::SetText(LPCTSTR pstrText) { CControlUI::SetText(pstrText); + m_bNeedEstimateSize = true; if( m_EnableEffect) { #ifdef _UNICODE m_pWideText = (LPWSTR)m_sText.GetData(); @@ -77,6 +99,7 @@ namespace DuiLib void CLabelUI::SetTextStyle(UINT uStyle) { m_uTextStyle = uStyle; + m_bNeedEstimateSize = true; Invalidate(); } @@ -92,8 +115,12 @@ namespace DuiLib void CLabelUI::SetMultiLine(bool bMultiLine) { - if (bMultiLine) m_uTextStyle &= ~DT_SINGLELINE; + if (bMultiLine) { + m_uTextStyle &= ~DT_SINGLELINE; + m_uTextStyle |= DT_WORDBREAK; + } else m_uTextStyle |= DT_SINGLELINE; + m_bNeedEstimateSize = true; } void CLabelUI::SetTextColor(DWORD dwTextColor) @@ -121,6 +148,7 @@ namespace DuiLib void CLabelUI::SetFont(int index) { m_iFont = index; + m_bNeedEstimateSize = true; Invalidate(); } @@ -137,6 +165,7 @@ namespace DuiLib void CLabelUI::SetTextPadding(RECT rc) { m_rcTextPadding = rc; + m_bNeedEstimateSize = true; Invalidate(); } @@ -150,13 +179,58 @@ namespace DuiLib if( m_bShowHtml == bShowHtml ) return; m_bShowHtml = bShowHtml; + m_bNeedEstimateSize = true; Invalidate(); } SIZE CLabelUI::EstimateSize(SIZE szAvailable) { - if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetFontInfo(GetFont())->tm.tmHeight + 4); - return CControlUI::EstimateSize(szAvailable); + if (m_cxyFixed.cx > 0 && m_cxyFixed.cy > 0) return m_cxyFixed; + + if ((m_uTextStyle & DT_SINGLELINE) == 0 && + (szAvailable.cx != m_szAvailableLast.cx || szAvailable.cy != m_szAvailableLast.cy)) { + m_bNeedEstimateSize = true; + } + + if (m_bNeedEstimateSize) { + m_bNeedEstimateSize = false; + m_szAvailableLast = szAvailable; + m_cxyFixedLast = m_cxyFixed; + if ((m_uTextStyle & DT_SINGLELINE) != 0) { + if (m_cxyFixedLast.cy == 0) { + m_cxyFixedLast.cy = m_pManager->GetFontInfo(m_iFont)->tm.tmHeight + 8; + m_cxyFixedLast.cy += m_rcTextPadding.top + m_rcTextPadding.bottom; + } + if (m_cxyFixedLast.cx == 0) { + RECT rcText = { 0, 0, 9999, m_cxyFixedLast.cy }; + if( m_bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, m_iFont, DT_CALCRECT | m_uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, m_iFont, DT_CALCRECT | m_uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cx = rcText.right - rcText.left + m_rcTextPadding.left + m_rcTextPadding.right; + } + } + else { + if( m_cxyFixedLast.cx == 0 ) { + m_cxyFixedLast.cx = szAvailable.cx; + } + RECT rcText = { 0, 0, m_cxyFixedLast.cx, 9999 }; + rcText.left += m_rcTextPadding.left; + rcText.right -= m_rcTextPadding.right; + if( m_bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, m_iFont, DT_CALCRECT | m_uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, m_iFont, DT_CALCRECT | m_uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cy = rcText.bottom - rcText.top + m_rcTextPadding.top + m_rcTextPadding.bottom; + } + } + return m_cxyFixedLast; } void CLabelUI::DoEvent(TEventUI& event) @@ -171,14 +245,6 @@ namespace DuiLib m_bFocused = false; return; } - if( event.Type == UIEVENT_MOUSEENTER ) - { - // return; - } - if( event.Type == UIEVENT_MOUSELEAVE ) - { - // return; - } CControlUI::DoEvent(event); } @@ -299,7 +365,7 @@ namespace DuiLib if( IsEnabled() ) { if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, m_dwTextColor, \ - NULL, NULL, nLinks, m_uTextStyle); + NULL, NULL, nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, m_dwTextColor, \ m_iFont, m_uTextStyle); @@ -307,14 +373,15 @@ namespace DuiLib else { if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, m_dwDisabledTextColor, \ - NULL, NULL, nLinks, DT_SINGLELINE | m_uTextStyle); + NULL, NULL, nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, m_dwDisabledTextColor, \ - m_iFont, DT_SINGLELINE | m_uTextStyle); + m_iFont, m_uTextStyle); } } else { +#ifdef _USE_GDIPLUS Font nFont(hDC,m_pManager->GetFont(GetFont())); Graphics nGraphics(hDC); nGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias); @@ -323,11 +390,11 @@ namespace DuiLib StringAlignment sa = StringAlignment::StringAlignmentNear; if ((m_uTextStyle & DT_VCENTER) != 0) sa = StringAlignment::StringAlignmentCenter; else if( (m_uTextStyle & DT_BOTTOM) != 0) sa = StringAlignment::StringAlignmentFar; - format.SetAlignment((StringAlignment)sa); + format.SetLineAlignment((StringAlignment)sa); sa = StringAlignment::StringAlignmentNear; if ((m_uTextStyle & DT_CENTER) != 0) sa = StringAlignment::StringAlignmentCenter; else if( (m_uTextStyle & DT_RIGHT) != 0) sa = StringAlignment::StringAlignmentFar; - format.SetLineAlignment((StringAlignment)sa); + format.SetAlignment((StringAlignment)sa); RectF nRc((float)rc.left,(float)rc.top,(float)rc.right-rc.left,(float)rc.bottom-rc.top); RectF nShadowRc = nRc; @@ -411,6 +478,7 @@ namespace DuiLib nGraphics.DrawString(m_pWideText,iLen,&nFont,nShadowRc,&format,&nLineGrBrushA); nGraphics.DrawString(m_pWideText,iLen,&nFont,nRc,&format,&nLineGrBrushB); +#endif #endif } } diff --git a/DuiLib/Control/UILabel.h b/DuiLib/Control/UILabel.h index 1456f31e..4393acbc 100644 --- a/DuiLib/Control/UILabel.h +++ b/DuiLib/Control/UILabel.h @@ -3,15 +3,20 @@ #pragma once +#define _USE_GDIPLUS 1 + +#ifdef _USE_GDIPLUS #include #pragma comment( lib, "GdiPlus.lib" ) using namespace Gdiplus; -class UILIB_API Gdiplus::RectF; -struct UILIB_API Gdiplus::GdiplusStartupInput; +class DUILIB_API Gdiplus::RectF; +struct DUILIB_API Gdiplus::GdiplusStartupInput; +#endif + namespace DuiLib { - class UILIB_API CLabelUI : public CControlUI + class DUILIB_API CLabelUI : public CControlUI { public: CLabelUI(); @@ -20,6 +25,8 @@ namespace DuiLib LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); + void SetFixedWidth(int cx); + void SetFixedHeight(int cy); void SetText(LPCTSTR pstrText); void SetTextStyle(UINT uStyle); @@ -43,6 +50,7 @@ namespace DuiLib void PaintText(HDC hDC); +#ifdef _USE_GDIPLUS void SetEnabledEffect(bool _EnabledEffect); bool GetEnabledEffect(); void SetEnabledLuminous(bool bEnableLuminous); @@ -67,7 +75,8 @@ namespace DuiLib bool GetEnabledStroke(); void SetEnabledShadow(bool _EnabledShadowe); bool GetEnabledShadow(); - +#endif + protected: LPWSTR m_pWideText; DWORD m_dwTextColor; @@ -76,6 +85,9 @@ namespace DuiLib UINT m_uTextStyle; RECT m_rcTextPadding; bool m_bShowHtml; + SIZE m_szAvailableLast; + SIZE m_cxyFixedLast; + bool m_bNeedEstimateSize; float m_fLuminousFuzzy; int m_GradientLength; @@ -90,7 +102,9 @@ namespace DuiLib DWORD m_dwStrokeColor; RectF m_ShadowOffset; ULONG_PTR m_gdiplusToken; +#ifdef _USE_GDIPLUS GdiplusStartupInput m_gdiplusStartupInput; +#endif }; } diff --git a/DuiLib/Control/UIList.cpp b/DuiLib/Control/UIList.cpp index 9b760e2e..628581ae 100644 --- a/DuiLib/Control/UIList.cpp +++ b/DuiLib/Control/UIList.cpp @@ -2,6 +2,31 @@ namespace DuiLib { + +///////////////////////////////////////////////////////////////////////////////////// +// + +class CListBodyUI : public CVerticalLayoutUI +{ +public: + CListBodyUI(CListUI* pOwner); + + void SetScrollPos(SIZE szPos); + void SetPos(RECT rc, bool bNeedInvalidate = true); + void DoEvent(TEventUI& event); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iCurSel); + +protected: + static int __cdecl ItemComareFunc(void *pvlocale, const void *item1, const void *item2); + int __cdecl ItemComareFunc(const void *item1, const void *item2); + +protected: + CListUI* m_pOwner; + PULVCompareFunc m_pCompareFunc; + UINT_PTR m_compareData; +}; + ///////////////////////////////////////////////////////////////////////////////////// // // @@ -15,8 +40,9 @@ CListUI::CListUI() : m_pCallback(NULL), m_bScrollSelect(false), m_iCurSel(-1), m CVerticalLayoutUI::Add(m_pList); m_ListInfo.nColumns = 0; + m_ListInfo.uFixedHeight = 0; m_ListInfo.nFont = -1; - m_ListInfo.uTextStyle = DT_VCENTER; // m_uTextStyle(DT_VCENTER | DT_END_ELLIPSIS) + m_ListInfo.uTextStyle = DT_VCENTER | DT_SINGLELINE; // m_uTextStyle(DT_VCENTER | DT_END_ELLIPSIS) m_ListInfo.dwTextColor = 0xFF000000; m_ListInfo.dwBkColor = 0; m_ListInfo.bAlternateBk = false; @@ -26,7 +52,10 @@ CListUI::CListUI() : m_pCallback(NULL), m_bScrollSelect(false), m_iCurSel(-1), m m_ListInfo.dwHotBkColor = 0xFFE9F5FF; m_ListInfo.dwDisabledTextColor = 0xFFCCCCCC; m_ListInfo.dwDisabledBkColor = 0xFFFFFFFF; - m_ListInfo.dwLineColor = 0; + m_ListInfo.iHLineSize = 0; + m_ListInfo.dwHLineColor = 0xFF3C3C3C; + m_ListInfo.iVLineSize = 0; + m_ListInfo.dwVLineColor = 0xFF3C3C3C; m_ListInfo.bShowHtml = false; m_ListInfo.bMultiExpandable = false; ::ZeroMemory(&m_ListInfo.rcTextPadding, sizeof(m_ListInfo.rcTextPadding)); @@ -35,7 +64,7 @@ CListUI::CListUI() : m_pCallback(NULL), m_bScrollSelect(false), m_iCurSel(-1), m LPCTSTR CListUI::GetClass() const { - return _T("ListUI"); + return DUI_CTR_LIST; } UINT CListUI::GetControlFlags() const @@ -46,8 +75,8 @@ UINT CListUI::GetControlFlags() const LPVOID CListUI::GetInterface(LPCTSTR pstrName) { if( _tcscmp(pstrName, DUI_CTR_LIST) == 0 ) return static_cast(this); - if( _tcscmp(pstrName, _T("IList")) == 0 ) return static_cast(this); - if( _tcscmp(pstrName, _T("IListOwner")) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_ILIST) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_ILISTOWNER) == 0 ) return static_cast(this); return CVerticalLayoutUI::GetInterface(pstrName); } @@ -58,18 +87,18 @@ CControlUI* CListUI::GetItemAt(int iIndex) const int CListUI::GetItemIndex(CControlUI* pControl) const { - if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::GetItemIndex(pControl); + if( pControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) return CVerticalLayoutUI::GetItemIndex(pControl); // We also need to recognize header sub-items - if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->GetItemIndex(pControl); + if( _tcsstr(pControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) return m_pHeader->GetItemIndex(pControl); return m_pList->GetItemIndex(pControl); } bool CListUI::SetItemIndex(CControlUI* pControl, int iIndex) { - if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::SetItemIndex(pControl, iIndex); + if( pControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) return CVerticalLayoutUI::SetItemIndex(pControl, iIndex); // We also need to recognize header sub-items - if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->SetItemIndex(pControl, iIndex); + if( _tcsstr(pControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) return m_pHeader->SetItemIndex(pControl, iIndex); int iOrginIndex = m_pList->GetItemIndex(pControl); if( iOrginIndex == -1 ) return false; @@ -77,13 +106,42 @@ bool CListUI::SetItemIndex(CControlUI* pControl, int iIndex) IListItemUI* pSelectedListItem = NULL; if( m_iCurSel >= 0 ) pSelectedListItem = - static_cast(GetItemAt(m_iCurSel)->GetInterface(_T("ListItem"))); + static_cast(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM)); if( !m_pList->SetItemIndex(pControl, iIndex) ) return false; int iMinIndex = min(iOrginIndex, iIndex); int iMaxIndex = max(iOrginIndex, iIndex); for(int i = iMinIndex; i < iMaxIndex + 1; ++i) { CControlUI* p = m_pList->GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); + if( pListItem != NULL ) { + pListItem->SetIndex(i); + } + } + if( m_iCurSel >= 0 && pSelectedListItem != NULL ) m_iCurSel = pSelectedListItem->GetIndex(); + return true; +} + +bool CListUI::SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex) +{ + if (pStartControl == NULL || iCount < 0 || iNewStartIndex < 0) return false; + if( pStartControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) return CVerticalLayoutUI::SetMultiItemIndex(pStartControl, iCount, iNewStartIndex); + // We also need to recognize header sub-items + if( _tcsstr(pStartControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) return m_pHeader->SetMultiItemIndex(pStartControl, iCount, iNewStartIndex); + + int iStartIndex = GetItemIndex(pStartControl); + if (iStartIndex == iNewStartIndex) return true; + if (iStartIndex + iCount > GetCount()) return false; + if (iNewStartIndex + iCount > GetCount()) return false; + + IListItemUI* pSelectedListItem = NULL; + if( m_iCurSel >= 0 ) pSelectedListItem = + static_cast(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM)); + if( !m_pList->SetMultiItemIndex(pStartControl, iCount, iNewStartIndex) ) return false; + int iMinIndex = min(iStartIndex, iNewStartIndex); + int iMaxIndex = max(iStartIndex + iCount, iNewStartIndex + iCount); + for(int i = iMinIndex; i < iMaxIndex + 1; ++i) { + CControlUI* p = m_pList->GetItemAt(i); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -102,7 +160,7 @@ bool CListUI::Add(CControlUI* pControl) // Override the Add() method so we can add items specifically to // the intended widgets. Headers are assumed to be // answer the correct interface so we can add multiple list headers. - if( pControl->GetInterface(_T("ListHeader")) != NULL ) { + if( pControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) { if( m_pHeader != pControl && m_pHeader->GetCount() == 0 ) { CVerticalLayoutUI::Remove(m_pHeader); m_pHeader = static_cast(pControl); @@ -111,13 +169,13 @@ bool CListUI::Add(CControlUI* pControl) return CVerticalLayoutUI::AddAt(pControl, 0); } // We also need to recognize header sub-items - if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) { + if( _tcsstr(pControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) { bool ret = m_pHeader->Add(pControl); m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS); return ret; } // The list items should know about us - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetOwner(this); pListItem->SetIndex(GetCount()); @@ -130,7 +188,7 @@ bool CListUI::AddAt(CControlUI* pControl, int iIndex) // Override the AddAt() method so we can add items specifically to // the intended widgets. Headers and are assumed to be // answer the correct interface so we can add multiple list headers. - if( pControl->GetInterface(_T("ListHeader")) != NULL ) { + if( pControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) { if( m_pHeader != pControl && m_pHeader->GetCount() == 0 ) { CVerticalLayoutUI::Remove(m_pHeader); m_pHeader = static_cast(pControl); @@ -139,7 +197,7 @@ bool CListUI::AddAt(CControlUI* pControl, int iIndex) return CVerticalLayoutUI::AddAt(pControl, 0); } // We also need to recognize header sub-items - if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) { + if( _tcsstr(pControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) { bool ret = m_pHeader->AddAt(pControl, iIndex); m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS); return ret; @@ -147,7 +205,7 @@ bool CListUI::AddAt(CControlUI* pControl, int iIndex) if (!m_pList->AddAt(pControl, iIndex)) return false; // The list items should know about us - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetOwner(this); pListItem->SetIndex(iIndex); @@ -155,7 +213,7 @@ bool CListUI::AddAt(CControlUI* pControl, int iIndex) for(int i = iIndex + 1; i < m_pList->GetCount(); ++i) { CControlUI* p = m_pList->GetItemAt(i); - pListItem = static_cast(p->GetInterface(_T("ListItem"))); + pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -164,20 +222,20 @@ bool CListUI::AddAt(CControlUI* pControl, int iIndex) return true; } -bool CListUI::Remove(CControlUI* pControl) +bool CListUI::Remove(CControlUI* pControl, bool bDoNotDestroy) { - if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::Remove(pControl); + if( pControl->GetInterface(DUI_CTR_LISTHEADER) != NULL ) return CVerticalLayoutUI::Remove(pControl, bDoNotDestroy); // We also need to recognize header sub-items - if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->Remove(pControl); + if( _tcsstr(pControl->GetClass(), DUI_CTR_LISTHEADERITEM) != NULL ) return m_pHeader->Remove(pControl, bDoNotDestroy); int iIndex = m_pList->GetItemIndex(pControl); if (iIndex == -1) return false; - if (!m_pList->RemoveAt(iIndex)) return false; + if (!m_pList->RemoveAt(iIndex, bDoNotDestroy)) return false; for(int i = iIndex; i < m_pList->GetCount(); ++i) { CControlUI* p = m_pList->GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) { pListItem->SetIndex(i); } @@ -192,13 +250,13 @@ bool CListUI::Remove(CControlUI* pControl) return true; } -bool CListUI::RemoveAt(int iIndex) +bool CListUI::RemoveAt(int iIndex, bool bDoNotDestroy) { - if (!m_pList->RemoveAt(iIndex)) return false; + if (!m_pList->RemoveAt(iIndex, bDoNotDestroy)) return false; for(int i = iIndex; i < m_pList->GetCount(); ++i) { CControlUI* p = m_pList->GetItemAt(i); - IListItemUI* pListItem = static_cast(p->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(p->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) pListItem->SetIndex(i); } @@ -332,34 +390,32 @@ void CListUI::DoEvent(TEventUI& event) return; } - switch( event.Type ) { - case UIEVENT_KEYDOWN: - switch( event.chKey ) { - case VK_UP: - SelectItem(FindSelectable(m_iCurSel - 1, false), true); - return; - case VK_DOWN: - SelectItem(FindSelectable(m_iCurSel + 1, true), true); - return; - case VK_PRIOR: - PageUp(); - return; - case VK_NEXT: - PageDown(); - return; - case VK_HOME: - SelectItem(FindSelectable(0, false), true); - return; - case VK_END: - SelectItem(FindSelectable(GetCount() - 1, true), true); - return; - case VK_RETURN: - if( m_iCurSel != -1 ) GetItemAt(m_iCurSel)->Activate(); - return; + if( event.Type == UIEVENT_KEYDOWN ) + { + if (IsKeyboardEnabled() && IsEnabled()) { + switch( event.chKey ) { + case VK_UP: + SelectItem(FindSelectable(m_iCurSel - 1, false), true); + case VK_DOWN: + SelectItem(FindSelectable(m_iCurSel + 1, true), true); + case VK_PRIOR: + PageUp(); + case VK_NEXT: + PageDown(); + case VK_HOME: + SelectItem(FindSelectable(0, false), true); + case VK_END: + SelectItem(FindSelectable(GetCount() - 1, true), true); + case VK_RETURN: + if( m_iCurSel != -1 ) GetItemAt(m_iCurSel)->Activate(); } - break; - case UIEVENT_SCROLLWHEEL: - { + return; + } + } + + if( event.Type == UIEVENT_SCROLLWHEEL ) + { + if (IsEnabled()) { switch( LOWORD(event.wParam) ) { case SB_LINEUP: if( m_bScrollSelect ) SelectItem(FindSelectable(m_iCurSel - 1, false), true); @@ -371,8 +427,8 @@ void CListUI::DoEvent(TEventUI& event) return; } } - break; } + CVerticalLayoutUI::DoEvent(event); } @@ -410,7 +466,7 @@ bool CListUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent) if( m_iCurSel >= 0 ) { CControlUI* pControl = GetItemAt(m_iCurSel); if( pControl != NULL) { - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem != NULL ) pListItem->Select(false, bTriggerEvent); } @@ -423,7 +479,7 @@ bool CListUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent) if( !pControl->IsVisible() ) return false; if( !pControl->IsEnabled() ) return false; - IListItemUI* pListItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pListItem == NULL ) return false; m_iCurSel = iIndex; if( !pListItem->Select(true, bTriggerEvent) ) { @@ -454,12 +510,33 @@ void CListUI::SetChildPadding(int iPadding) m_pList->SetChildPadding(iPadding); } +UINT CListUI::GetItemFixedHeight() +{ + return m_ListInfo.uFixedHeight; +} + +void CListUI::SetItemFixedHeight(UINT nHeight) +{ + m_ListInfo.uFixedHeight = nHeight; + NeedUpdate(); +} + +int CListUI::GetItemFont(int index) +{ + return m_ListInfo.nFont; +} + void CListUI::SetItemFont(int index) { m_ListInfo.nFont = index; NeedUpdate(); } +UINT CListUI::GetItemTextStyle() +{ + return m_ListInfo.uTextStyle; +} + void CListUI::SetItemTextStyle(UINT uStyle) { m_ListInfo.uTextStyle = uStyle; @@ -627,14 +704,47 @@ LPCTSTR CListUI::GetDisabledItemImage() const return m_ListInfo.diDisabled.sDrawString; } -DWORD CListUI::GetItemLineColor() const +int CListUI::GetItemHLineSize() const +{ + return m_ListInfo.iHLineSize; +} + +void CListUI::SetItemHLineSize(int iSize) +{ + m_ListInfo.iHLineSize = iSize; + Invalidate(); +} + +DWORD CListUI::GetItemHLineColor() const +{ + return m_ListInfo.dwHLineColor; +} + +void CListUI::SetItemHLineColor(DWORD dwLineColor) +{ + m_ListInfo.dwHLineColor = dwLineColor; + Invalidate(); +} + +int CListUI::GetItemVLineSize() const { - return m_ListInfo.dwLineColor; + return m_ListInfo.iVLineSize; } -void CListUI::SetItemLineColor(DWORD dwLineColor) +void CListUI::SetItemVLineSize(int iSize) { - m_ListInfo.dwLineColor = dwLineColor; + m_ListInfo.iVLineSize = iSize; + Invalidate(); +} + +DWORD CListUI::GetItemVLineColor() const +{ + return m_ListInfo.dwVLineColor; +} + +void CListUI::SetItemVLineColor(DWORD dwLineColor) +{ + m_ListInfo.dwVLineColor = dwLineColor; Invalidate(); } @@ -661,7 +771,7 @@ bool CListUI::ExpandItem(int iIndex, bool bExpand /*= true*/) if( m_iExpandedItem >= 0 && !m_ListInfo.bMultiExpandable) { CControlUI* pControl = GetItemAt(m_iExpandedItem); if( pControl != NULL ) { - IListItemUI* pItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pItem != NULL ) pItem->Expand(false); } m_iExpandedItem = -1; @@ -670,7 +780,7 @@ bool CListUI::ExpandItem(int iIndex, bool bExpand /*= true*/) CControlUI* pControl = GetItemAt(iIndex); if( pControl == NULL ) return false; if( !pControl->IsVisible() ) return false; - IListItemUI* pItem = static_cast(pControl->GetInterface(_T("ListItem"))); + IListItemUI* pItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); if( pItem == NULL ) return false; m_iExpandedItem = iIndex; if( !pItem->Expand(true) ) { @@ -723,6 +833,7 @@ void CListUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) else if( _tcscmp(pstrName, _T("headerbkimage")) == 0 ) GetHeader()->SetBkImage(pstrValue); else if( _tcscmp(pstrName, _T("scrollselect")) == 0 ) SetScrollSelect(_tcscmp(pstrValue, _T("true")) == 0); else if( _tcscmp(pstrName, _T("multiexpanding")) == 0 ) SetMultiExpanding(_tcscmp(pstrValue, _T("true")) == 0); + else if( _tcscmp(pstrName, _T("itemheight")) == 0 ) m_ListInfo.uFixedHeight = _ttoi(pstrValue); else if( _tcscmp(pstrName, _T("itemfont")) == 0 ) m_ListInfo.nFont = _ttoi(pstrValue); else if( _tcscmp(pstrName, _T("itemalign")) == 0 ) { if( _tcsstr(pstrValue, _T("left")) != NULL ) { @@ -738,11 +849,33 @@ void CListUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) m_ListInfo.uTextStyle |= DT_RIGHT; } } + else if (_tcscmp(pstrName, _T("itemvalign")) == 0) + { + if (_tcsstr(pstrValue, _T("top")) != NULL) { + m_ListInfo.uTextStyle &= ~(DT_BOTTOM | DT_VCENTER); + m_ListInfo.uTextStyle |= DT_TOP; + } + if (_tcsstr(pstrValue, _T("vcenter")) != NULL) { + m_ListInfo.uTextStyle &= ~(DT_TOP | DT_BOTTOM); + m_ListInfo.uTextStyle |= DT_VCENTER; + } + if (_tcsstr(pstrValue, _T("bottom")) != NULL) { + m_ListInfo.uTextStyle &= ~(DT_TOP | DT_VCENTER); + m_ListInfo.uTextStyle |= DT_BOTTOM; + } + } else if( _tcscmp(pstrName, _T("itemendellipsis")) == 0 ) { if( _tcscmp(pstrValue, _T("true")) == 0 ) m_ListInfo.uTextStyle |= DT_END_ELLIPSIS; else m_ListInfo.uTextStyle &= ~DT_END_ELLIPSIS; - } - if( _tcscmp(pstrName, _T("itemtextpadding")) == 0 ) { + } + else if( _tcscmp(pstrName, _T("itemmultiline")) == 0 ) { + if (_tcscmp(pstrValue, _T("true")) == 0) { + m_ListInfo.uTextStyle &= ~DT_SINGLELINE; + m_ListInfo.uTextStyle |= DT_WORDBREAK; + } + else m_ListInfo.uTextStyle |= DT_SINGLELINE; + } + else if( _tcscmp(pstrName, _T("itemtextpadding")) == 0 ) { RECT rcTextPadding = { 0 }; LPTSTR pstr = NULL; rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); @@ -804,11 +937,23 @@ void CListUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) SetDisabledItemBkColor(clrColor); } else if( _tcscmp(pstrName, _T("itemdisabledimage")) == 0 ) SetDisabledItemImage(pstrValue); - else if( _tcscmp(pstrName, _T("itemlinecolor")) == 0 ) { + else if( _tcscmp(pstrName, _T("itemvlinesize")) == 0 ) { + SetItemVLineSize(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("itemvlinecolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetItemVLineColor(clrColor); + } + else if( _tcscmp(pstrName, _T("itemhlinesize")) == 0 ) { + SetItemHLineSize(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("itemhlinecolor")) == 0 ) { if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - SetItemLineColor(clrColor); + SetItemHLineColor(clrColor); } else if( _tcscmp(pstrName, _T("itemshowhtml")) == 0 ) SetItemShowHtml(_tcscmp(pstrValue, _T("true")) == 0); else CVerticalLayoutUI::SetAttribute(pstrName, pstrValue); @@ -914,12 +1059,11 @@ CScrollBarUI* CListUI::GetHorizontalScrollBar() const return m_pList->GetHorizontalScrollBar(); } -BOOL CListUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData) +bool CListUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData) { - if (!m_pList) - return FALSE; + if (!m_pList) return false; int iCurSel = m_iCurSel; - BOOL bResult = m_pList->SortItems(pfnCompare, dwData, iCurSel); + bool bResult = m_pList->SortItems(pfnCompare, dwData, iCurSel); if (bResult) { m_iCurSel = iCurSel; EnsureVisible(m_iCurSel); @@ -927,20 +1071,19 @@ BOOL CListUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData) } return bResult; } + ///////////////////////////////////////////////////////////////////////////////////// // // - CListBodyUI::CListBodyUI(CListUI* pOwner) : m_pOwner(pOwner) { ASSERT(m_pOwner); } -BOOL CListBodyUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iCurSel) +bool CListBodyUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iCurSel) { - if (!pfnCompare) - return FALSE; + if (!pfnCompare) return false; m_pCompareFunc = pfnCompare; CControlUI *pCurSelControl = GetItemAt(iCurSel); CControlUI **pData = (CControlUI **)m_items.GetData(); @@ -956,7 +1099,7 @@ BOOL CListBodyUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iC } } - return TRUE; + return true; } int __cdecl CListBodyUI::ItemComareFunc(void *pvlocale, const void *item1, const void *item2) @@ -1035,22 +1178,40 @@ void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate) if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange(); + int iChildPadding = m_iChildPadding; + TListInfoUI* pInfo = NULL; + if( m_pOwner ) { + pInfo = m_pOwner->GetListInfo(); + if( pInfo != NULL ) { + iChildPadding += pInfo->iHLineSize; + if (pInfo->nColumns > 0) { + szAvailable.cx = pInfo->rcColumn[pInfo->nColumns - 1].right - pInfo->rcColumn[0].left; + } + } + } + int cxNeeded = 0; - int nAdjustables = 0; int cyFixed = 0; int nEstimateNum = 0; + SIZE szControlAvailable; + int iControlMaxWidth = 0; + int iControlMaxHeight = 0; for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) { CControlUI* pControl = static_cast(m_items[it1]); if( !pControl->IsVisible() ) continue; if( pControl->IsFloat() ) continue; + szControlAvailable = szAvailable; + RECT rcPadding = pControl->GetPadding(); + szControlAvailable.cx -= rcPadding.left + rcPadding.right; + iControlMaxWidth = pControl->GetFixedWidth(); + iControlMaxHeight = pControl->GetFixedHeight(); + if (iControlMaxWidth <= 0) iControlMaxWidth = pControl->GetMaxWidth(); + if (iControlMaxHeight <= 0) iControlMaxHeight = pControl->GetMaxHeight(); + if (szControlAvailable.cx > iControlMaxWidth) szControlAvailable.cx = iControlMaxWidth; + if (szControlAvailable.cy > iControlMaxHeight) szControlAvailable.cy = iControlMaxHeight; SIZE sz = pControl->EstimateSize(szAvailable); - if( sz.cy == 0 ) { - nAdjustables++; - } - else { - if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); - if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); - } + if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); + if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); cyFixed += sz.cy + pControl->GetPadding().top + pControl->GetPadding().bottom; sz.cx = MAX(sz.cx, 0); @@ -1059,7 +1220,7 @@ void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate) cxNeeded = MAX(cxNeeded, sz.cx); nEstimateNum++; } - cyFixed += (nEstimateNum - 1) * m_iChildPadding; + cyFixed += (nEstimateNum - 1) * iChildPadding; if( m_pOwner ) { CListHeaderUI* pHeader = m_pOwner->GetHeader(); @@ -1070,8 +1231,6 @@ void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate) // Place elements int cyNeeded = 0; - int cyExpand = 0; - if( nAdjustables > 0 ) cyExpand = MAX(0, (szAvailable.cy - cyFixed) / nAdjustables); // Position the elements SIZE szRemaining = szAvailable; int iPosY = rc.top; @@ -1082,8 +1241,8 @@ void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate) if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) { iPosX -= m_pHorizontalScrollBar->GetScrollPos(); } + int iAdjustable = 0; - int cyFixedRemaining = cyFixed; for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { CControlUI* pControl = static_cast(m_items[it2]); if( !pControl->IsVisible() ) continue; @@ -1094,36 +1253,31 @@ void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate) RECT rcPadding = pControl->GetPadding(); szRemaining.cy -= rcPadding.top; - SIZE sz = pControl->EstimateSize(szRemaining); - if( sz.cy == 0 ) { - iAdjustable++; - sz.cy = cyExpand; - // Distribute remaining to last element (usually round-off left-overs) - if( iAdjustable == nAdjustables ) { - sz.cy = MAX(0, szRemaining.cy - rcPadding.bottom - cyFixedRemaining); - } - if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); - if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); - } - else { - if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); - if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); - cyFixedRemaining -= sz.cy; - } - - sz.cx = MAX(cxNeeded, szAvailable.cx - rcPadding.left - rcPadding.right); - + szControlAvailable = szRemaining; + szControlAvailable.cx -= rcPadding.left + rcPadding.right; + iControlMaxWidth = pControl->GetFixedWidth(); + iControlMaxHeight = pControl->GetFixedHeight(); + if (iControlMaxWidth <= 0) iControlMaxWidth = pControl->GetMaxWidth(); + if (iControlMaxHeight <= 0) iControlMaxHeight = pControl->GetMaxHeight(); + if (szControlAvailable.cx > iControlMaxWidth) szControlAvailable.cx = iControlMaxWidth; + if (szControlAvailable.cy > iControlMaxHeight) szControlAvailable.cy = iControlMaxHeight; + SIZE sz = pControl->EstimateSize(szControlAvailable); + if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); + if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); + sz.cx = pControl->GetMaxWidth(); + if( sz.cx == 0 ) sz.cx = szAvailable.cx - rcPadding.left - rcPadding.right; + if( sz.cx < 0 ) sz.cx = 0; + if( sz.cx > szControlAvailable.cx ) sz.cx = szControlAvailable.cx; if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth(); - if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth(); RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top + rcPadding.bottom }; pControl->SetPos(rcCtrl, false); - iPosY += sz.cy + m_iChildPadding + rcPadding.top + rcPadding.bottom; + iPosY += sz.cy + iChildPadding + rcPadding.top + rcPadding.bottom; cyNeeded += sz.cy + rcPadding.top + rcPadding.bottom; - szRemaining.cy -= sz.cy + m_iChildPadding + rcPadding.bottom; + szRemaining.cy -= sz.cy + iChildPadding + rcPadding.bottom; } - cyNeeded += (nEstimateNum - 1) * m_iChildPadding; + cyNeeded += (nEstimateNum - 1) * iChildPadding; // Process the scrollbar ProcessScrollBar(rc, cxNeeded, cyNeeded); @@ -1160,6 +1314,100 @@ void CListBodyUI::DoEvent(TEventUI& event) } } +bool CListBodyUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +{ + RECT rcTemp = { 0 }; + if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true; + + TListInfoUI* pListInfo = NULL; + if( m_pOwner ) pListInfo = m_pOwner->GetListInfo(); + + CRenderClip clip; + CRenderClip::GenerateClip(hDC, rcTemp, clip); + CControlUI::DoPaint(hDC, rcPaint, pStopControl); + + if( m_items.GetSize() > 0 ) { + RECT rc = m_rcItem; + rc.left += m_rcInset.left; + rc.top += m_rcInset.top; + rc.right -= m_rcInset.right; + rc.bottom -= m_rcInset.bottom; + if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth(); + if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); + + if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) { + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + else { + int iDrawIndex = 0; + CRenderClip childClip; + CRenderClip::GenerateClip(hDC, rcTemp, childClip); + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( !pControl->IsFloat() ) { + IListItemUI* pListItem = static_cast(pControl->GetInterface(DUI_CTR_ILISTITEM)); + if( pListItem != NULL ) { + pListItem->SetDrawIndex(iDrawIndex); + iDrawIndex += 1; + } + if (pListInfo && pListInfo->iHLineSize > 0) { + // 因为没有为最后一个预留分割条长度,如果list铺满,最后一条不会显示 + RECT rcPadding = pControl->GetPadding(); + const RECT& rcPos = pControl->GetPos(); + RECT rcBottomLine = { rcPos.left, rcPos.bottom + rcPadding.bottom, rcPos.right, rcPos.bottom + rcPadding.bottom + pListInfo->iHLineSize }; + if( ::IntersectRect(&rcTemp, &rcPaint, &rcBottomLine) ) { + rcBottomLine.top += pListInfo->iHLineSize / 2; + rcBottomLine.bottom = rcBottomLine.top; + CRenderEngine::DrawLine(hDC, rcBottomLine, pListInfo->iHLineSize, GetAdjustColor(pListInfo->dwHLineColor)); + } + } + } + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + CRenderClip::UseOldClipBegin(hDC, childClip); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + CRenderClip::UseOldClipEnd(hDC, childClip); + } + else { + if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + } + + if( m_pVerticalScrollBar != NULL ) { + if( m_pVerticalScrollBar == pStopControl ) return false; + if (m_pVerticalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { + if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + + if( m_pHorizontalScrollBar != NULL ) { + if( m_pHorizontalScrollBar == pStopControl ) return false; + if (m_pHorizontalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { + if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + return true; +} + ///////////////////////////////////////////////////////////////////////////////////// // // @@ -1170,7 +1418,7 @@ CListHeaderUI::CListHeaderUI() LPCTSTR CListHeaderUI::GetClass() const { - return _T("ListHeaderUI"); + return DUI_CTR_LISTHEADER; } LPVOID CListHeaderUI::GetInterface(LPCTSTR pstrName) @@ -1186,7 +1434,7 @@ SIZE CListHeaderUI::EstimateSize(SIZE szAvailable) for( int it = 0; it < m_items.GetSize(); it++ ) { cXY.cy = MAX(cXY.cy,static_cast(m_items[it])->EstimateSize(szAvailable).cy); } - int nMin = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 6; + int nMin = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8; cXY.cy = MAX(cXY.cy,nMin); } @@ -1202,7 +1450,8 @@ SIZE CListHeaderUI::EstimateSize(SIZE szAvailable) // CListHeaderItemUI::CListHeaderItemUI() : m_bDragable(true), m_uButtonState(0), m_iSepWidth(4), -m_uTextStyle(DT_VCENTER | DT_CENTER | DT_SINGLELINE), m_dwTextColor(0), m_iFont(-1), m_bShowHtml(false) +m_uTextStyle(DT_CENTER | DT_VCENTER | DT_SINGLELINE), m_dwTextColor(0), m_dwSepColor(0), +m_iFont(-1), m_bShowHtml(false) { SetTextPadding(CDuiRect(2, 0, 2, 0)); ptLastMouse.x = ptLastMouse.y = 0; @@ -1211,7 +1460,7 @@ m_uTextStyle(DT_VCENTER | DT_CENTER | DT_SINGLELINE), m_dwTextColor(0), m_iFont( LPCTSTR CListHeaderItemUI::GetClass() const { - return _T("ListHeaderItemUI"); + return DUI_CTR_LISTHEADERITEM; } LPVOID CListHeaderItemUI::GetInterface(LPCTSTR pstrName) @@ -1275,6 +1524,18 @@ DWORD CListHeaderItemUI::GetTextColor() const void CListHeaderItemUI::SetTextColor(DWORD dwTextColor) { m_dwTextColor = dwTextColor; + Invalidate(); +} + +DWORD CListHeaderItemUI::GetSepColor() const +{ + return m_dwSepColor; +} + +void CListHeaderItemUI::SetSepColor(DWORD dwSepColor) +{ + m_dwSepColor = dwSepColor; + Invalidate(); } RECT CListHeaderItemUI::GetTextPadding() const @@ -1374,7 +1635,6 @@ void CListHeaderItemUI::SetSepImage(LPCTSTR pStrImage) void CListHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if( _tcscmp(pstrName, _T("dragable")) == 0 ) SetDragable(_tcscmp(pstrValue, _T("true")) == 0); - else if( _tcscmp(pstrName, _T("sepwidth")) == 0 ) SetSepWidth(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("align")) == 0 ) { if( _tcsstr(pstrValue, _T("left")) != NULL ) { m_uTextStyle &= ~(DT_CENTER | DT_RIGHT); @@ -1389,10 +1649,32 @@ void CListHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) m_uTextStyle |= DT_RIGHT; } } + else if (_tcscmp(pstrName, _T("valign")) == 0) + { + if (_tcsstr(pstrValue, _T("top")) != NULL) { + m_uTextStyle &= ~(DT_BOTTOM | DT_VCENTER); + m_uTextStyle |= DT_TOP; + } + if (_tcsstr(pstrValue, _T("vcenter")) != NULL) { + m_uTextStyle &= ~(DT_TOP | DT_BOTTOM); + m_uTextStyle |= DT_VCENTER; + } + if (_tcsstr(pstrValue, _T("bottom")) != NULL) { + m_uTextStyle &= ~(DT_TOP | DT_VCENTER); + m_uTextStyle |= DT_BOTTOM; + } + } else if( _tcscmp(pstrName, _T("endellipsis")) == 0 ) { if( _tcscmp(pstrValue, _T("true")) == 0 ) m_uTextStyle |= DT_END_ELLIPSIS; else m_uTextStyle &= ~DT_END_ELLIPSIS; - } + } + else if( _tcscmp(pstrName, _T("multiline")) == 0 ) { + if (_tcscmp(pstrValue, _T("true")) == 0) { + m_uTextStyle &= ~DT_SINGLELINE; + m_uTextStyle |= DT_WORDBREAK; + } + else m_uTextStyle |= DT_SINGLELINE; + } else if( _tcscmp(pstrName, _T("font")) == 0 ) SetFont(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("textcolor")) == 0 ) { if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); @@ -1414,6 +1696,13 @@ void CListHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue); else if( _tcscmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue); else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue); + else if( _tcscmp(pstrName, _T("sepwidth")) == 0 ) SetSepWidth(_ttoi(pstrValue)); + else if( _tcscmp(pstrName, _T("sepcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetSepColor(clrColor); + } else if( _tcscmp(pstrName, _T("sepimage")) == 0 ) SetSepImage(pstrValue); else CControlUI::SetAttribute(pstrName, pstrValue); } @@ -1438,10 +1727,6 @@ void CListHeaderItemUI::DoEvent(TEventUI& event) { if( !IsEnabled() ) return; RECT rcSeparator = GetThumbRect(); - if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动 - rcSeparator.left-=4; - else - rcSeparator.right+=4; if( ::PtInRect(&rcSeparator, event.ptMouse) ) { if( m_bDragable ) { m_uButtonState |= UISTATE_CAPTURED; @@ -1491,10 +1776,6 @@ void CListHeaderItemUI::DoEvent(TEventUI& event) if( event.Type == UIEVENT_SETCURSOR ) { RECT rcSeparator = GetThumbRect(); - if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动 - rcSeparator.left-=4; - else - rcSeparator.right+=4; if( IsEnabled() && m_bDragable && ::PtInRect(&rcSeparator, event.ptMouse) ) { ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE))); return; @@ -1502,26 +1783,37 @@ void CListHeaderItemUI::DoEvent(TEventUI& event) } if( event.Type == UIEVENT_MOUSEENTER ) { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } } - return; } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( IsEnabled() ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; } - return; } CControlUI::DoEvent(event); } SIZE CListHeaderItemUI::EstimateSize(SIZE szAvailable) { - if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 14); + if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8); return CControlUI::EstimateSize(szAvailable); } @@ -1549,13 +1841,19 @@ void CListHeaderItemUI::PaintStatusImage(HDC hDC) DrawImage(hDC, m_diNormal); } - RECT rcThumb = GetThumbRect(); - rcThumb.left -= m_rcItem.left; - rcThumb.top -= m_rcItem.top; - rcThumb.right -= m_rcItem.left; - rcThumb.bottom -= m_rcItem.top; - m_diSep.rcDestOffset = rcThumb; - DrawImage(hDC, m_diSep); + if (m_iSepWidth > 0) { + RECT rcThumb = GetThumbRect(); + m_diSep.rcDestOffset.left = rcThumb.left - m_rcItem.left; + m_diSep.rcDestOffset.top = rcThumb.top - m_rcItem.top; + m_diSep.rcDestOffset.right = rcThumb.right - m_rcItem.left; + m_diSep.rcDestOffset.bottom = rcThumb.bottom - m_rcItem.top; + if( !DrawImage(hDC, m_diSep) ) { + if (m_dwSepColor != 0) { + RECT rcSepLine = { rcThumb.left + m_iSepWidth/2, rcThumb.top, rcThumb.left + m_iSepWidth/2, rcThumb.bottom}; + CRenderEngine::DrawLine(hDC, rcSepLine, m_iSepWidth, GetAdjustColor(m_dwSepColor)); + } + } + } } void CListHeaderItemUI::PaintText(HDC hDC) @@ -1572,10 +1870,10 @@ void CListHeaderItemUI::PaintText(HDC hDC) int nLinks = 0; if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \ - NULL, NULL, nLinks, DT_SINGLELINE | m_uTextStyle); + NULL, NULL, nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \ - m_iFont, DT_SINGLELINE | m_uTextStyle); + m_iFont, m_uTextStyle); } ///////////////////////////////////////////////////////////////////////////////////// @@ -1584,6 +1882,7 @@ void CListHeaderItemUI::PaintText(HDC hDC) CListElementUI::CListElementUI() : m_iIndex(-1), +m_iDrawIndex(0), m_pOwner(NULL), m_bSelected(false), m_uButtonState(0) @@ -1592,7 +1891,7 @@ m_uButtonState(0) LPCTSTR CListElementUI::GetClass() const { - return _T("ListElementUI"); + return DUI_CTR_LISTELEMENT; } UINT CListElementUI::GetControlFlags() const @@ -1602,7 +1901,7 @@ UINT CListElementUI::GetControlFlags() const LPVOID CListElementUI::GetInterface(LPCTSTR pstrName) { - if( _tcscmp(pstrName, DUI_CTR_LISTITEM) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_ILISTITEM) == 0 ) return static_cast(this); if( _tcscmp(pstrName, DUI_CTR_LISTELEMENT) == 0 ) return static_cast(this); return CControlUI::GetInterface(pstrName); } @@ -1614,7 +1913,7 @@ IListOwnerUI* CListElementUI::GetOwner() void CListElementUI::SetOwner(CControlUI* pOwner) { - m_pOwner = static_cast(pOwner->GetInterface(_T("IListOwner"))); + if (pOwner != NULL) m_pOwner = static_cast(pOwner->GetInterface(DUI_CTR_ILISTOWNER)); } void CListElementUI::SetVisible(bool bVisible) @@ -1645,12 +1944,22 @@ void CListElementUI::SetIndex(int iIndex) m_iIndex = iIndex; } +int CListElementUI::GetDrawIndex() const +{ + return m_iDrawIndex; +} + +void CListElementUI::SetDrawIndex(int iIndex) +{ + m_iDrawIndex = iIndex; +} + void CListElementUI::Invalidate() { if( !IsVisible() ) return; if( GetParent() ) { - CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(_T("Container"))); + CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(DUI_CTR_CONTAINER)); if( pParentContainer ) { RECT rc = pParentContainer->GetPos(); RECT rcInset = pParentContainer->GetInset(); @@ -1742,12 +2051,14 @@ void CListElementUI::DoEvent(TEventUI& event) } return; } - if( event.Type == UIEVENT_KEYDOWN && IsEnabled() ) + if( event.Type == UIEVENT_KEYDOWN ) { - if( event.chKey == VK_RETURN ) { - Activate(); - Invalidate(); - return; + if (IsKeyboardEnabled() && IsEnabled()) { + if( event.chKey == VK_RETURN ) { + Activate(); + Invalidate(); + return; + } } } // An important twist: The list-item will send the event not to its immediate @@ -1769,7 +2080,7 @@ void CListElementUI::DrawItemBk(HDC hDC, const RECT& rcItem) TListInfoUI* pInfo = m_pOwner->GetListInfo(); if( pInfo == NULL ) return; DWORD iBackColor = 0; - if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) iBackColor = pInfo->dwBkColor; + if( !pInfo->bAlternateBk || m_iDrawIndex % 2 == 0 ) iBackColor = pInfo->dwBkColor; if( (m_uButtonState & UISTATE_HOT) != 0 ) { iBackColor = pInfo->dwHotBkColor; } @@ -1795,28 +2106,27 @@ void CListElementUI::DrawItemBk(HDC hDC, const RECT& rcItem) } if( !DrawImage(hDC, m_diBk) ) { - if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) { + if( !pInfo->bAlternateBk || m_iDrawIndex % 2 == 0 ) { if( DrawImage(hDC, pInfo->diBk) ) return; } } - - if ( pInfo->dwLineColor != 0 ) { - RECT rcLine = { rcItem.left, rcItem.bottom - 1, rcItem.right, rcItem.bottom - 1 }; - CRenderEngine::DrawLine(hDC, rcLine, 1, GetAdjustColor(pInfo->dwLineColor)); - } } ///////////////////////////////////////////////////////////////////////////////////// // // -CListLabelElementUI::CListLabelElementUI() +CListLabelElementUI::CListLabelElementUI() : m_bNeedEstimateSize(true), m_uFixedHeightLast(0), + m_nFontLast(-1), m_uTextStyleLast(0) { + m_szAvailableLast.cx = m_szAvailableLast.cy = 0; + m_cxyFixedLast.cx = m_cxyFixedLast.cy = 0; + ::ZeroMemory(&m_rcTextPaddingLast, sizeof(m_rcTextPaddingLast)); } LPCTSTR CListLabelElementUI::GetClass() const { - return _T("ListLabelElementUI"); + return DUI_CTR_LISTLABELELEMENT; } LPVOID CListLabelElementUI::GetInterface(LPCTSTR pstrName) @@ -1825,6 +2135,30 @@ LPVOID CListLabelElementUI::GetInterface(LPCTSTR pstrName) return CListElementUI::GetInterface(pstrName); } +void CListLabelElementUI::SetOwner(CControlUI* pOwner) +{ + m_bNeedEstimateSize = true; + CListElementUI::SetOwner(pOwner); +} + +void CListLabelElementUI::SetFixedWidth(int cx) +{ + m_bNeedEstimateSize = true; + CControlUI::SetFixedWidth(cx); +} + +void CListLabelElementUI::SetFixedHeight(int cy) +{ + m_bNeedEstimateSize = true; + CControlUI::SetFixedHeight(cy); +} + +void CListLabelElementUI::SetText(LPCTSTR pstrText) +{ + m_bNeedEstimateSize = true; + CControlUI::SetText(pstrText); +} + void CListLabelElementUI::DoEvent(TEventUI& event) { if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) { @@ -1852,19 +2186,30 @@ void CListLabelElementUI::DoEvent(TEventUI& event) } if( event.Type == UIEVENT_MOUSEENTER ) { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } } - return; } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( (m_uButtonState & UISTATE_HOT) != 0 ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; } - return; } CListElementUI::DoEvent(event); } @@ -1872,33 +2217,79 @@ void CListLabelElementUI::DoEvent(TEventUI& event) SIZE CListLabelElementUI::EstimateSize(SIZE szAvailable) { if( m_pOwner == NULL ) return CDuiSize(0, 0); - TListInfoUI* pInfo = m_pOwner->GetListInfo(); - SIZE cXY = m_cxyFixed; - if( cXY.cy == 0 && m_pManager != NULL ) { - cXY.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8; - cXY.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; - } + if (pInfo == NULL) return CDuiSize(0, 0); + if (m_cxyFixed.cx > 0) { + if (m_cxyFixed.cy > 0) return m_cxyFixed; + else if (pInfo->uFixedHeight > 0) return CDuiSize(m_cxyFixed.cx, pInfo->uFixedHeight); + } + + if ((pInfo->uTextStyle & DT_SINGLELINE) == 0 && + (szAvailable.cx != m_szAvailableLast.cx || szAvailable.cy != m_szAvailableLast.cy)) { + m_bNeedEstimateSize = true; + } + if (m_uFixedHeightLast != pInfo->uFixedHeight || m_nFontLast != pInfo->nFont || + m_uTextStyleLast != pInfo->uTextStyle || + m_rcTextPaddingLast.left != pInfo->rcTextPadding.left || m_rcTextPaddingLast.right != pInfo->rcTextPadding.right || + m_rcTextPaddingLast.top != pInfo->rcTextPadding.top || m_rcTextPaddingLast.bottom != pInfo->rcTextPadding.bottom) { + m_bNeedEstimateSize = true; + } + + if (m_bNeedEstimateSize) { + m_bNeedEstimateSize = false; + m_szAvailableLast = szAvailable; + m_uFixedHeightLast = pInfo->uFixedHeight; + m_nFontLast = pInfo->nFont; + m_uTextStyleLast = pInfo->uTextStyle; + m_rcTextPaddingLast = pInfo->rcTextPadding; + + m_cxyFixedLast = m_cxyFixed; + if (m_cxyFixedLast.cy == 0) { + m_cxyFixedLast.cy = pInfo->uFixedHeight; + } - if( cXY.cx == 0 && m_pManager != NULL ) { - RECT rcText = { 0, 0, 9999, cXY.cy }; - if( pInfo->bShowHtml ) { - int nLinks = 0; - CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, DT_SINGLELINE | DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + if ((pInfo->uTextStyle & DT_SINGLELINE) != 0) { + if( m_cxyFixedLast.cy == 0 ) { + m_cxyFixedLast.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8; + m_cxyFixedLast.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; + } + if (m_cxyFixedLast.cx == 0) { + RECT rcText = { 0, 0, 9999, m_cxyFixedLast.cy }; + if( pInfo->bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right; + } } else { - CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, pInfo->nFont, DT_SINGLELINE | DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + if( m_cxyFixedLast.cx == 0 ) { + m_cxyFixedLast.cx = szAvailable.cx; + } + RECT rcText = { 0, 0, m_cxyFixedLast.cx, 9999 }; + rcText.left += pInfo->rcTextPadding.left; + rcText.right -= pInfo->rcTextPadding.right; + if( pInfo->bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cy = rcText.bottom - rcText.top + pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; } - cXY.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right; } - - return cXY; + return m_cxyFixedLast; } -void CListLabelElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CListLabelElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { DrawItemBk(hDC, m_rcItem); DrawItemText(hDC, m_rcItem); + return true; } void CListLabelElementUI::DrawItemText(HDC hDC, const RECT& rcItem) @@ -1907,6 +2298,7 @@ void CListLabelElementUI::DrawItemText(HDC hDC, const RECT& rcItem) if( m_pOwner == NULL ) return; TListInfoUI* pInfo = m_pOwner->GetListInfo(); + if( pInfo == NULL ) return; DWORD iTextColor = pInfo->dwTextColor; if( (m_uButtonState & UISTATE_HOT) != 0 ) { iTextColor = pInfo->dwHotTextColor; @@ -1926,10 +2318,10 @@ void CListLabelElementUI::DrawItemText(HDC hDC, const RECT& rcItem) if( pInfo->bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, iTextColor, \ - NULL, NULL, nLinks, DT_SINGLELINE | pInfo->uTextStyle); + NULL, NULL, nLinks, pInfo->nFont, pInfo->uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, iTextColor, \ - pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle); + pInfo->nFont, pInfo->uTextStyle); } @@ -1954,7 +2346,7 @@ CListTextElementUI::~CListTextElementUI() LPCTSTR CListTextElementUI::GetClass() const { - return _T("ListTextElementUI"); + return DUI_CTR_LISTTEXTELEMENT; } LPVOID CListTextElementUI::GetInterface(LPCTSTR pstrName) @@ -1980,6 +2372,8 @@ void CListTextElementUI::SetText(int iIndex, LPCTSTR pstrText) if( m_pOwner == NULL ) return; TListInfoUI* pInfo = m_pOwner->GetListInfo(); if( iIndex < 0 || iIndex >= pInfo->nColumns ) return; + m_bNeedEstimateSize = true; + while( m_aTexts.GetSize() < pInfo->nColumns ) { m_aTexts.Add(NULL); } CDuiString* pText = static_cast(m_aTexts[iIndex]); @@ -1994,8 +2388,11 @@ void CListTextElementUI::SetText(int iIndex, LPCTSTR pstrText) void CListTextElementUI::SetOwner(CControlUI* pOwner) { - CListElementUI::SetOwner(pOwner); - m_pOwner = static_cast(pOwner->GetInterface(_T("IList"))); + if (pOwner != NULL) { + m_bNeedEstimateSize = true; + CListElementUI::SetOwner(pOwner); + m_pOwner = static_cast(pOwner->GetInterface(DUI_CTR_ILIST)); + } } CDuiString* CListTextElementUI::GetLinkContent(int iIndex) @@ -2045,8 +2442,15 @@ void CListTextElementUI::DoEvent(TEventUI& event) } if( m_nLinks > 0 && event.Type == UIEVENT_MOUSELEAVE ) { if(m_nHoverLink != -1) { - Invalidate(); - m_nHoverLink = -1; + if( !::PtInRect(&m_rcLinks[m_nHoverLink], event.ptMouse) ) { + m_nHoverLink = -1; + Invalidate(); + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } } } CListLabelElementUI::DoEvent(event); @@ -2054,22 +2458,96 @@ void CListTextElementUI::DoEvent(TEventUI& event) SIZE CListTextElementUI::EstimateSize(SIZE szAvailable) { - TListInfoUI* pInfo = NULL; - if( m_pOwner ) pInfo = m_pOwner->GetListInfo(); - - SIZE cXY = m_cxyFixed; - if( cXY.cy == 0 && m_pManager != NULL ) { - cXY.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8; - if( pInfo ) cXY.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; + if( m_pOwner == NULL ) return CDuiSize(0, 0); + TListInfoUI* pInfo = m_pOwner->GetListInfo(); + if (pInfo == NULL) return CDuiSize(0, 0); + SIZE cxyFixed = m_cxyFixed; + if (cxyFixed.cx == 0 && pInfo->nColumns > 0) { + cxyFixed.cx = pInfo->rcColumn[pInfo->nColumns - 1].right - pInfo->rcColumn[0].left; + if (m_cxyFixedLast.cx != cxyFixed.cx) m_bNeedEstimateSize = true; + } + if (cxyFixed.cx > 0) { + if (cxyFixed.cy > 0) return cxyFixed; + else if (pInfo->uFixedHeight > 0) return CDuiSize(cxyFixed.cx, pInfo->uFixedHeight); + } + + if ((pInfo->uTextStyle & DT_SINGLELINE) == 0 && + (szAvailable.cx != m_szAvailableLast.cx || szAvailable.cy != m_szAvailableLast.cy)) { + m_bNeedEstimateSize = true; + } + if (m_uFixedHeightLast != pInfo->uFixedHeight || m_nFontLast != pInfo->nFont || + m_uTextStyleLast != pInfo->uTextStyle || + m_rcTextPaddingLast.left != pInfo->rcTextPadding.left || m_rcTextPaddingLast.right != pInfo->rcTextPadding.right || + m_rcTextPaddingLast.top != pInfo->rcTextPadding.top || m_rcTextPaddingLast.bottom != pInfo->rcTextPadding.bottom) { + m_bNeedEstimateSize = true; } - return cXY; + CDuiString strText; + IListCallbackUI* pCallback = m_pOwner->GetTextCallback(); + if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, 0); + else if (m_aTexts.GetSize() > 0) strText.Assign(GetText(0)); + else strText = m_sText; + if (m_sTextLast != strText) m_bNeedEstimateSize = true; + + if (m_bNeedEstimateSize) { + m_bNeedEstimateSize = false; + m_szAvailableLast = szAvailable; + m_uFixedHeightLast = pInfo->uFixedHeight; + m_nFontLast = pInfo->nFont; + m_uTextStyleLast = pInfo->uTextStyle; + m_rcTextPaddingLast = pInfo->rcTextPadding; + m_sTextLast = strText; + + m_cxyFixedLast = m_cxyFixed; + if (m_cxyFixedLast.cx == 0 && pInfo->nColumns > 0) { + m_cxyFixedLast.cx = pInfo->rcColumn[pInfo->nColumns - 1].right - pInfo->rcColumn[0].left; + } + if (m_cxyFixedLast.cy == 0) { + m_cxyFixedLast.cy = pInfo->uFixedHeight; + } + + if ((pInfo->uTextStyle & DT_SINGLELINE) != 0) { + if( m_cxyFixedLast.cy == 0 ) { + m_cxyFixedLast.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8; + m_cxyFixedLast.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; + } + if (m_cxyFixedLast.cx == 0) { + RECT rcText = { 0, 0, 9999, m_cxyFixedLast.cy }; + if( pInfo->bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, strText, 0, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, strText, 0, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right; + } + } + else { + if( m_cxyFixedLast.cx == 0 ) { + m_cxyFixedLast.cx = szAvailable.cx; + } + RECT rcText = { 0, 0, m_cxyFixedLast.cx, 9999 }; + rcText.left += pInfo->rcTextPadding.left; + rcText.right -= pInfo->rcTextPadding.right; + if( pInfo->bShowHtml ) { + int nLinks = 0; + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, strText, 0, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + else { + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, strText, 0, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); + } + m_cxyFixedLast.cy = rcText.bottom - rcText.top + pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; + } + } + return m_cxyFixedLast; } void CListTextElementUI::DrawItemText(HDC hDC, const RECT& rcItem) { if( m_pOwner == NULL ) return; TListInfoUI* pInfo = m_pOwner->GetListInfo(); + if (pInfo == NULL) return; DWORD iTextColor = pInfo->dwTextColor; if( (m_uButtonState & UISTATE_HOT) != 0 ) { @@ -2082,32 +2560,60 @@ void CListTextElementUI::DrawItemText(HDC hDC, const RECT& rcItem) iTextColor = pInfo->dwDisabledTextColor; } IListCallbackUI* pCallback = m_pOwner->GetTextCallback(); - //ASSERT(pCallback); - //if( pCallback == NULL ) return; m_nLinks = 0; int nLinks = lengthof(m_rcLinks); - for( int i = 0; i < pInfo->nColumns; i++ ) - { - RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom }; + if (pInfo->nColumns > 0) { + for( int i = 0; i < pInfo->nColumns; i++ ) + { + RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom }; + if (pInfo->iVLineSize > 0 && i < pInfo->nColumns - 1) { + RECT rcLine = { rcItem.right - pInfo->iVLineSize / 2, rcItem.top, rcItem.right - pInfo->iVLineSize / 2, rcItem.bottom}; + CRenderEngine::DrawLine(hDC, rcLine, pInfo->iVLineSize, GetAdjustColor(pInfo->dwVLineColor)); + rcItem.right -= pInfo->iVLineSize; + } + + rcItem.left += pInfo->rcTextPadding.left; + rcItem.right -= pInfo->rcTextPadding.right; + rcItem.top += pInfo->rcTextPadding.top; + rcItem.bottom -= pInfo->rcTextPadding.bottom; + + CDuiString strText;//不使用LPCTSTR,否则限制太多 by cddjr 2011/10/20 + if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, i); + else strText.Assign(GetText(i)); + if( pInfo->bShowHtml ) + CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \ + &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, pInfo->nFont, pInfo->uTextStyle); + else + CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \ + pInfo->nFont, pInfo->uTextStyle); + + m_nLinks += nLinks; + nLinks = lengthof(m_rcLinks) - m_nLinks; + } + } + else { + RECT rcItem = m_rcItem; rcItem.left += pInfo->rcTextPadding.left; rcItem.right -= pInfo->rcTextPadding.right; rcItem.top += pInfo->rcTextPadding.top; rcItem.bottom -= pInfo->rcTextPadding.bottom; - CDuiString strText;//不使用LPCTSTR,否则限制太多 by cddjr 2011/10/20 - if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, i); - else strText.Assign(GetText(i)); + CDuiString strText; + if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, 0); + else if (m_aTexts.GetSize() > 0) strText.Assign(GetText(0)); + else strText = m_sText; if( pInfo->bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \ - &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, DT_SINGLELINE | pInfo->uTextStyle); + &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, pInfo->nFont, pInfo->uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \ - pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle); + pInfo->nFont, pInfo->uTextStyle); m_nLinks += nLinks; nLinks = lengthof(m_rcLinks) - m_nLinks; } + for( int i = m_nLinks; i < lengthof(m_rcLinks); i++ ) { ::ZeroMemory(m_rcLinks + i, sizeof(RECT)); ((CDuiString*)(m_sLinks + i))->Empty(); @@ -2120,15 +2626,18 @@ void CListTextElementUI::DrawItemText(HDC hDC, const RECT& rcItem) CListContainerElementUI::CListContainerElementUI() : m_iIndex(-1), +m_iDrawIndex(0), m_pOwner(NULL), m_bSelected(false), +m_bExpandable(false), +m_bExpand(false), m_uButtonState(0) { } LPCTSTR CListContainerElementUI::GetClass() const { - return _T("ListContainerElementUI"); + return DUI_CTR_LISTCONTAINERELEMENT; } UINT CListContainerElementUI::GetControlFlags() const @@ -2138,7 +2647,7 @@ UINT CListContainerElementUI::GetControlFlags() const LPVOID CListContainerElementUI::GetInterface(LPCTSTR pstrName) { - if( _tcscmp(pstrName, DUI_CTR_LISTITEM) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_ILISTITEM) == 0 ) return static_cast(this); if( _tcscmp(pstrName, DUI_CTR_LISTCONTAINERELEMENT) == 0 ) return static_cast(this); return CContainerUI::GetInterface(pstrName); } @@ -2150,7 +2659,7 @@ IListOwnerUI* CListContainerElementUI::GetOwner() void CListContainerElementUI::SetOwner(CControlUI* pOwner) { - m_pOwner = static_cast(pOwner->GetInterface(_T("IListOwner"))); + if (pOwner != NULL) m_pOwner = static_cast(pOwner->GetInterface(DUI_CTR_ILISTOWNER)); } void CListContainerElementUI::SetVisible(bool bVisible) @@ -2181,12 +2690,22 @@ void CListContainerElementUI::SetIndex(int iIndex) m_iIndex = iIndex; } +int CListContainerElementUI::GetDrawIndex() const +{ + return m_iDrawIndex; +} + +void CListContainerElementUI::SetDrawIndex(int iIndex) +{ + m_iDrawIndex = iIndex; +} + void CListContainerElementUI::Invalidate() { if( !IsVisible() ) return; if( GetParent() ) { - CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(_T("Container"))); + CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(DUI_CTR_CONTAINER)); if( pParentContainer ) { RECT rc = pParentContainer->GetPos(); RECT rcInset = pParentContainer->GetInset(); @@ -2252,14 +2771,36 @@ bool CListContainerElementUI::Select(bool bSelect, bool bTriggerEvent) return true; } +bool CListContainerElementUI::IsExpandable() const +{ + return m_bExpandable; +} + +void CListContainerElementUI::SetExpandable(bool bExpandable) +{ + m_bExpandable = bExpandable; +} + bool CListContainerElementUI::IsExpanded() const { - return false; + return m_bExpand; } -bool CListContainerElementUI::Expand(bool /*bExpand = true*/) +bool CListContainerElementUI::Expand(bool bExpand) { - return false; + ASSERT(m_pOwner); + if( m_pOwner == NULL ) return false; + if( bExpand == m_bExpand ) return true; + m_bExpand = bExpand; + if( m_bExpandable ) { + if( !m_pOwner->ExpandItem(m_iIndex, bExpand) ) return false; + if( m_pManager != NULL ) { + if( bExpand ) m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMEXPAND, false); + else m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCOLLAPSE, false); + } + } + + return true; } void CListContainerElementUI::DoEvent(TEventUI& event) @@ -2278,17 +2819,19 @@ void CListContainerElementUI::DoEvent(TEventUI& event) } return; } - if( event.Type == UIEVENT_KEYDOWN && IsEnabled() ) + if( event.Type == UIEVENT_KEYDOWN ) { - if( event.chKey == VK_RETURN ) { - Activate(); - Invalidate(); - return; + if (IsKeyboardEnabled() && IsEnabled()) { + if( event.chKey == VK_RETURN ) { + Activate(); + Invalidate(); + return; + } } } if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_RBUTTONDOWN ) { - if( IsEnabled() ){ + if( IsEnabled() ) { m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK); Select(); Invalidate(); @@ -2305,19 +2848,30 @@ void CListContainerElementUI::DoEvent(TEventUI& event) } if( event.Type == UIEVENT_MOUSEENTER ) { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } } - return; } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( (m_uButtonState & UISTATE_HOT) != 0 ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; } - return; } // An important twist: The list-item will send the event not to its immediate @@ -2329,13 +2883,14 @@ void CListContainerElementUI::DoEvent(TEventUI& event) void CListContainerElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if( _tcscmp(pstrName, _T("selected")) == 0 ) Select(); + else if( _tcscmp(pstrName, _T("expandable")) == 0 ) SetExpandable(_tcscmp(pstrValue, _T("true")) == 0); else CContainerUI::SetAttribute(pstrName, pstrValue); } -void CListContainerElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CListContainerElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { DrawItemBk(hDC, m_rcItem); - CContainerUI::DoPaint(hDC, rcPaint, pStopControl); + return CContainerUI::DoPaint(hDC, rcPaint, pStopControl); } void CListContainerElementUI::DrawItemText(HDC hDC, const RECT& rcItem) @@ -2350,7 +2905,7 @@ void CListContainerElementUI::DrawItemBk(HDC hDC, const RECT& rcItem) TListInfoUI* pInfo = m_pOwner->GetListInfo(); if( pInfo == NULL ) return; DWORD iBackColor = 0; - if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) iBackColor = pInfo->dwBkColor; + if( !pInfo->bAlternateBk || m_iDrawIndex % 2 == 0 ) iBackColor = pInfo->dwBkColor; if( (m_uButtonState & UISTATE_HOT) != 0 ) { iBackColor = pInfo->dwHotBkColor; @@ -2375,15 +2930,109 @@ void CListContainerElementUI::DrawItemBk(HDC hDC, const RECT& rcItem) if( DrawImage(hDC, pInfo->diHot) ) return; } if( !DrawImage(hDC, m_diBk) ) { - if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) { + if( !pInfo->bAlternateBk || m_iDrawIndex % 2 == 0 ) { if( DrawImage(hDC, pInfo->diBk) ) return; } } +} - if ( pInfo->dwLineColor != 0 ) { - RECT rcLine = { m_rcItem.left, m_rcItem.bottom - 1, m_rcItem.right, m_rcItem.bottom - 1 }; - CRenderEngine::DrawLine(hDC, rcLine, 1, GetAdjustColor(pInfo->dwLineColor)); - } +SIZE CListContainerElementUI::EstimateSize(SIZE szAvailable) +{ + TListInfoUI* pInfo = NULL; + if( m_pOwner ) pInfo = m_pOwner->GetListInfo(); + + SIZE cXY = m_cxyFixed; + + if( cXY.cy == 0 ) { + cXY.cy = pInfo->uFixedHeight; + } + + return cXY; +} + +///////////////////////////////////////////////////////////////////////////////////// +// +// + +CListHBoxElementUI::CListHBoxElementUI() +{ + +} + +LPCTSTR CListHBoxElementUI::GetClass() const +{ + return DUI_CTR_LISTHBOXELEMENT; +} + +LPVOID CListHBoxElementUI::GetInterface(LPCTSTR pstrName) +{ + if( _tcscmp(pstrName, DUI_CTR_LISTHBOXELEMENT) == 0 ) return static_cast(this); + return CListContainerElementUI::GetInterface(pstrName); +} + +void CListHBoxElementUI::SetPos(RECT rc, bool bNeedInvalidate) +{ + if( m_pOwner == NULL ) return CListContainerElementUI::SetPos(rc, bNeedInvalidate); + + CControlUI::SetPos(rc, bNeedInvalidate); + rc = m_rcItem; + + TListInfoUI* pInfo = m_pOwner->GetListInfo(); + if (pInfo == NULL) return; + if (pInfo->nColumns > 0) { + int iColumnIndex = 0; + for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { + CControlUI* pControl = static_cast(m_items[it2]); + if( !pControl->IsVisible() ) continue; + if( pControl->IsFloat() ) { + SetFloatPos(it2); + continue; + } + if( iColumnIndex >= pInfo->nColumns ) continue; + + RECT rcPadding = pControl->GetPadding(); + RECT rcItem = { pInfo->rcColumn[iColumnIndex].left + rcPadding.left, m_rcItem.top + rcPadding.top, + pInfo->rcColumn[iColumnIndex].right - rcPadding.right, m_rcItem.bottom - rcPadding.bottom }; + if (pInfo->iVLineSize > 0 && iColumnIndex < pInfo->nColumns - 1) { + rcItem.right -= pInfo->iVLineSize; + } + pControl->SetPos(rcItem, false); + iColumnIndex += 1; + } + } + else { + for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { + CControlUI* pControl = static_cast(m_items[it2]); + if( !pControl->IsVisible() ) continue; + if( pControl->IsFloat() ) { + SetFloatPos(it2); + continue; + } + + RECT rcPadding = pControl->GetPadding(); + RECT rcItem = { m_rcItem.left + rcPadding.left, m_rcItem.top + rcPadding.top, + m_rcItem.right - rcPadding.right, m_rcItem.bottom - rcPadding.bottom }; + pControl->SetPos(rcItem, false); + } + } +} + +bool CListHBoxElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +{ + ASSERT(m_pOwner); + if( m_pOwner == NULL ) return true; + TListInfoUI* pInfo = m_pOwner->GetListInfo(); + if( pInfo == NULL ) return true; + + DrawItemBk(hDC, m_rcItem); + for( int i = 0; i < pInfo->nColumns; i++ ) { + RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom }; + if (pInfo->iVLineSize > 0 && i < pInfo->nColumns - 1) { + RECT rcLine = { rcItem.right - pInfo->iVLineSize / 2, rcItem.top, rcItem.right - pInfo->iVLineSize / 2, rcItem.bottom}; + CRenderEngine::DrawLine(hDC, rcLine, pInfo->iVLineSize, GetAdjustColor(pInfo->dwVLineColor)); + } + } + return CContainerUI::DoPaint(hDC, rcPaint, pStopControl); } } // namespace DuiLib diff --git a/DuiLib/Control/UIList.h b/DuiLib/Control/UIList.h index d4f85868..6636cd47 100644 --- a/DuiLib/Control/UIList.h +++ b/DuiLib/Control/UIList.h @@ -13,12 +13,13 @@ typedef int (CALLBACK *PULVCompareFunc)(UINT_PTR, UINT_PTR, UINT_PTR); class CListHeaderUI; -#define UILIST_MAX_COLUMNS 32 +#define UILIST_MAX_COLUMNS 64 typedef struct tagTListInfoUI { int nColumns; RECT rcColumn[UILIST_MAX_COLUMNS]; + UINT uFixedHeight; int nFont; UINT uTextStyle; RECT rcTextPadding; @@ -35,7 +36,10 @@ typedef struct tagTListInfoUI DWORD dwDisabledTextColor; DWORD dwDisabledBkColor; TDrawInfo diDisabled; - DWORD dwLineColor; + int iHLineSize; + DWORD dwHLineColor; + int iVLineSize; + DWORD dwVLineColor; bool bShowHtml; bool bMultiExpandable; } TListInfoUI; @@ -57,6 +61,8 @@ class IListOwnerUI virtual int GetCurSel() const = 0; virtual bool SelectItem(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true) = 0; virtual void DoEvent(TEventUI& event) = 0; + virtual bool ExpandItem(int iIndex, bool bExpand = true) = 0; + virtual int GetExpandedItem() const = 0; }; class IListUI : public IListOwnerUI @@ -66,8 +72,6 @@ class IListUI : public IListOwnerUI virtual CContainerUI* GetList() const = 0; virtual IListCallbackUI* GetTextCallback() const = 0; virtual void SetTextCallback(IListCallbackUI* pCallback) = 0; - virtual bool ExpandItem(int iIndex, bool bExpand = true) = 0; - virtual int GetExpandedItem() const = 0; }; class IListItemUI @@ -75,6 +79,8 @@ class IListItemUI public: virtual int GetIndex() const = 0; virtual void SetIndex(int iIndex) = 0; + virtual int GetDrawIndex() const = 0; + virtual void SetDrawIndex(int iIndex) = 0; virtual IListOwnerUI* GetOwner() = 0; virtual void SetOwner(CControlUI* pOwner) = 0; virtual bool IsSelected() const = 0; @@ -91,7 +97,7 @@ class IListItemUI class CListBodyUI; class CListHeaderUI; -class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI +class DUILIB_API CListUI : public CVerticalLayoutUI, public IListUI { public: CListUI(); @@ -105,18 +111,15 @@ class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI int GetCurSel() const; bool SelectItem(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true); - CListHeaderUI* GetHeader() const; - CContainerUI* GetList() const; - TListInfoUI* GetListInfo(); - CControlUI* GetItemAt(int iIndex) const; int GetItemIndex(CControlUI* pControl) const; bool SetItemIndex(CControlUI* pControl, int iIndex); + bool SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex); int GetCount() const; bool Add(CControlUI* pControl); bool AddAt(CControlUI* pControl, int iIndex); - bool Remove(CControlUI* pControl); - bool RemoveAt(int iIndex); + bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); + bool RemoveAt(int iIndex, bool bDoNotDestroy=false); void RemoveAll(); void EnsureVisible(int iIndex); @@ -125,40 +128,54 @@ class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI int GetChildPadding() const; void SetChildPadding(int iPadding); + CListHeaderUI* GetHeader() const; + CContainerUI* GetList() const; + TListInfoUI* GetListInfo(); + + UINT GetItemFixedHeight(); + void SetItemFixedHeight(UINT nHeight); + int GetItemFont(int index); void SetItemFont(int index); + UINT GetItemTextStyle(); void SetItemTextStyle(UINT uStyle); + RECT GetItemTextPadding() const; void SetItemTextPadding(RECT rc); + DWORD GetItemTextColor() const; void SetItemTextColor(DWORD dwTextColor); + DWORD GetItemBkColor() const; void SetItemBkColor(DWORD dwBkColor); + LPCTSTR GetItemBkImage() const; void SetItemBkImage(LPCTSTR pStrImage); - bool IsAlternateBk() const; + bool IsAlternateBk() const; void SetAlternateBk(bool bAlternateBk); + DWORD GetSelectedItemTextColor() const; void SetSelectedItemTextColor(DWORD dwTextColor); + DWORD GetSelectedItemBkColor() const; void SetSelectedItemBkColor(DWORD dwBkColor); - void SetSelectedItemImage(LPCTSTR pStrImage); + LPCTSTR GetSelectedItemImage() const; + void SetSelectedItemImage(LPCTSTR pStrImage); + DWORD GetHotItemTextColor() const; void SetHotItemTextColor(DWORD dwTextColor); + DWORD GetHotItemBkColor() const; void SetHotItemBkColor(DWORD dwBkColor); + LPCTSTR GetHotItemImage() const; void SetHotItemImage(LPCTSTR pStrImage); + DWORD GetDisabledItemTextColor() const; void SetDisabledItemTextColor(DWORD dwTextColor); + DWORD GetDisabledItemBkColor() const; void SetDisabledItemBkColor(DWORD dwBkColor); + LPCTSTR GetDisabledItemImage() const; void SetDisabledItemImage(LPCTSTR pStrImage); - void SetItemLineColor(DWORD dwLineColor); + int GetItemHLineSize() const; + void SetItemHLineSize(int iSize); + DWORD GetItemHLineColor() const; + void SetItemHLineColor(DWORD dwLineColor); + int GetItemVLineSize() const; + void SetItemVLineSize(int iSize); + DWORD GetItemVLineColor() const; + void SetItemVLineColor(DWORD dwLineColor); bool IsItemShowHtml(); void SetItemShowHtml(bool bShowHtml = true); - RECT GetItemTextPadding() const; - DWORD GetItemTextColor() const; - DWORD GetItemBkColor() const; - LPCTSTR GetItemBkImage() const; - DWORD GetSelectedItemTextColor() const; - DWORD GetSelectedItemBkColor() const; - LPCTSTR GetSelectedItemImage() const; - DWORD GetHotItemTextColor() const; - DWORD GetHotItemBkColor() const; - LPCTSTR GetHotItemImage() const; - DWORD GetDisabledItemTextColor() const; - DWORD GetDisabledItemBkColor() const; - LPCTSTR GetDisabledItemImage() const; - DWORD GetItemLineColor() const; void SetMultiExpanding(bool bMultiExpandable); int GetExpandedItem() const; @@ -190,7 +207,8 @@ class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI void EnableScrollBar(bool bEnableVertical = true, bool bEnableHorizontal = false); virtual CScrollBarUI* GetVerticalScrollBar() const; virtual CScrollBarUI* GetHorizontalScrollBar() const; - BOOL SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData); + bool SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData); + protected: bool m_bScrollSelect; int m_iCurSel; @@ -204,29 +222,7 @@ class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI ///////////////////////////////////////////////////////////////////////////////////// // - -class UILIB_API CListBodyUI : public CVerticalLayoutUI -{ -public: - CListBodyUI(CListUI* pOwner); - - void SetScrollPos(SIZE szPos); - void SetPos(RECT rc, bool bNeedInvalidate = true); - void DoEvent(TEventUI& event); - BOOL SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iCurSel); -protected: - static int __cdecl ItemComareFunc(void *pvlocale, const void *item1, const void *item2); - int __cdecl ItemComareFunc(const void *item1, const void *item2); -protected: - CListUI* m_pOwner; - PULVCompareFunc m_pCompareFunc; - UINT_PTR m_compareData; -}; - -///////////////////////////////////////////////////////////////////////////////////// -// - -class UILIB_API CListHeaderUI : public CHorizontalLayoutUI +class DUILIB_API CListHeaderUI : public CHorizontalLayoutUI { public: CListHeaderUI(); @@ -241,7 +237,7 @@ class UILIB_API CListHeaderUI : public CHorizontalLayoutUI ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CListHeaderItemUI : public CControlUI +class DUILIB_API CListHeaderItemUI : public CControlUI { public: CListHeaderItemUI(); @@ -260,6 +256,8 @@ class UILIB_API CListHeaderItemUI : public CControlUI void SetTextStyle(UINT uStyle); DWORD GetTextColor() const; void SetTextColor(DWORD dwTextColor); + DWORD GetSepColor() const; + void SetSepColor(DWORD dwSepColor); void SetTextPadding(RECT rc); RECT GetTextPadding() const; void SetFont(int index); @@ -290,6 +288,7 @@ class UILIB_API CListHeaderItemUI : public CControlUI UINT m_uButtonState; int m_iSepWidth; DWORD m_dwTextColor; + DWORD m_dwSepColor; int m_iFont; UINT m_uTextStyle; bool m_bShowHtml; @@ -305,7 +304,7 @@ class UILIB_API CListHeaderItemUI : public CControlUI ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CListElementUI : public CControlUI, public IListItemUI +class DUILIB_API CListElementUI : public CControlUI, public IListItemUI { public: CListElementUI(); @@ -318,6 +317,8 @@ class UILIB_API CListElementUI : public CControlUI, public IListItemUI int GetIndex() const; void SetIndex(int iIndex); + int GetDrawIndex() const; + void SetDrawIndex(int iIndex); IListOwnerUI* GetOwner(); void SetOwner(CControlUI* pOwner); @@ -338,6 +339,7 @@ class UILIB_API CListElementUI : public CControlUI, public IListItemUI protected: int m_iIndex; + int m_iDrawIndex; bool m_bSelected; UINT m_uButtonState; IListOwnerUI* m_pOwner; @@ -347,7 +349,7 @@ class UILIB_API CListElementUI : public CControlUI, public IListItemUI ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CListLabelElementUI : public CListElementUI +class DUILIB_API CListLabelElementUI : public CListElementUI { public: CListLabelElementUI(); @@ -355,18 +357,34 @@ class UILIB_API CListLabelElementUI : public CListElementUI LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); + void SetOwner(CControlUI* pOwner); + + void SetFixedWidth(int cx); + void SetFixedHeight(int cy); + void SetText(LPCTSTR pstrText); + void DoEvent(TEventUI& event); SIZE EstimateSize(SIZE szAvailable); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void DrawItemText(HDC hDC, const RECT& rcItem); + +protected: + SIZE m_cxyFixedLast; + bool m_bNeedEstimateSize; + + SIZE m_szAvailableLast; + UINT m_uFixedHeightLast; + int m_nFontLast; + UINT m_uTextStyleLast; + RECT m_rcTextPaddingLast; }; ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CListTextElementUI : public CListLabelElementUI +class DUILIB_API CListTextElementUI : public CListLabelElementUI { public: CListTextElementUI(); @@ -394,13 +412,15 @@ class UILIB_API CListTextElementUI : public CListLabelElementUI CDuiString m_sLinks[MAX_LINK]; int m_nHoverLink; IListUI* m_pOwner; - CStdPtrArray m_aTexts; + CDuiPtrArray m_aTexts; + + CDuiString m_sTextLast; }; ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CListContainerElementUI : public CContainerUI, public IListItemUI +class DUILIB_API CListContainerElementUI : public CContainerUI, public IListItemUI { public: CListContainerElementUI(); @@ -411,6 +431,8 @@ class UILIB_API CListContainerElementUI : public CContainerUI, public IListItemU int GetIndex() const; void SetIndex(int iIndex); + int GetDrawIndex() const; + void SetDrawIndex(int iIndex); IListOwnerUI* GetOwner(); void SetOwner(CControlUI* pOwner); @@ -419,6 +441,8 @@ class UILIB_API CListContainerElementUI : public CContainerUI, public IListItemU bool IsSelected() const; bool Select(bool bSelect = true, bool bTriggerEvent=true); + bool IsExpandable() const; + void SetExpandable(bool bExpandable); bool IsExpanded() const; bool Expand(bool bExpand = true); @@ -427,18 +451,38 @@ class UILIB_API CListContainerElementUI : public CContainerUI, public IListItemU void DoEvent(TEventUI& event); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void DrawItemText(HDC hDC, const RECT& rcItem); void DrawItemBk(HDC hDC, const RECT& rcItem); + SIZE EstimateSize(SIZE szAvailable); + protected: int m_iIndex; + int m_iDrawIndex; bool m_bSelected; + bool m_bExpandable; + bool m_bExpand; UINT m_uButtonState; IListOwnerUI* m_pOwner; }; +///////////////////////////////////////////////////////////////////////////////////// +// + +class DUILIB_API CListHBoxElementUI : public CListContainerElementUI +{ +public: + CListHBoxElementUI(); + + LPCTSTR GetClass() const; + LPVOID GetInterface(LPCTSTR pstrName); + + void SetPos(RECT rc, bool bNeedInvalidate = true); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); +}; + } // namespace DuiLib #endif // __UILIST_H__ diff --git a/DuiLib/Control/UIOption.cpp b/DuiLib/Control/UIOption.cpp index 5281f64d..64727d7b 100644 --- a/DuiLib/Control/UIOption.cpp +++ b/DuiLib/Control/UIOption.cpp @@ -14,7 +14,7 @@ namespace DuiLib LPCTSTR COptionUI::GetClass() const { - return _T("OptionUI"); + return DUI_CTR_OPTION; } LPVOID COptionUI::GetInterface(LPCTSTR pstrName) @@ -73,7 +73,7 @@ namespace DuiLib if( m_pManager != NULL ) { if( !m_sGroupName.IsEmpty() ) { if( m_bSelected ) { - CStdPtrArray* aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName); + CDuiPtrArray* aOptionGroup = m_pManager->GetOptionGroup(m_sGroupName); for( int i = 0; i < aOptionGroup->GetSize(); i++ ) { COptionUI* pControl = static_cast(aOptionGroup->GetAt(i)); if( pControl != this ) { @@ -241,7 +241,7 @@ namespace DuiLib if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, IsEnabled()?m_dwTextColor:m_dwDisabledTextColor, \ - NULL, NULL, nLinks, m_uTextStyle); + NULL, NULL, nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, IsEnabled()?m_dwTextColor:m_dwDisabledTextColor, \ m_iFont, m_uTextStyle); diff --git a/DuiLib/Control/UIOption.h b/DuiLib/Control/UIOption.h index d8a75127..ca0fdc9f 100644 --- a/DuiLib/Control/UIOption.h +++ b/DuiLib/Control/UIOption.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API COptionUI : public CButtonUI + class DUILIB_API COptionUI : public CButtonUI { public: COptionUI(); diff --git a/DuiLib/Control/UIProgress.cpp b/DuiLib/Control/UIProgress.cpp index b4e14310..ddbe1f8f 100644 --- a/DuiLib/Control/UIProgress.cpp +++ b/DuiLib/Control/UIProgress.cpp @@ -11,7 +11,7 @@ namespace DuiLib LPCTSTR CProgressUI::GetClass() const { - return _T("ProgressUI"); + return DUI_CTR_PROGRESS; } LPVOID CProgressUI::GetInterface(LPCTSTR pstrName) diff --git a/DuiLib/Control/UIProgress.h b/DuiLib/Control/UIProgress.h index f9395c29..74dd1fe7 100644 --- a/DuiLib/Control/UIProgress.h +++ b/DuiLib/Control/UIProgress.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CProgressUI : public CLabelUI + class DUILIB_API CProgressUI : public CLabelUI { public: CProgressUI(); diff --git a/DuiLib/Control/UIRichEdit.cpp b/DuiLib/Control/UIRichEdit.cpp index 244c44fb..9fd6350d 100644 --- a/DuiLib/Control/UIRichEdit.cpp +++ b/DuiLib/Control/UIRichEdit.cpp @@ -44,10 +44,11 @@ class CTxtWinHost : public ITextHost ITextServices* GetTextServices(void) { return pserv; } void SetClientRect(RECT *prc); RECT* GetClientRect() { return &rcClient; } - BOOL GetWordWrap(void) { return fWordWrap; } + BOOL IsWordWrap(void) { return fWordWrap; } void SetWordWrap(BOOL fWordWrap); - BOOL GetReadOnly(); + BOOL IsReadOnly(); void SetReadOnly(BOOL fReadOnly); + void SetFont(HFONT hFont); void SetColor(DWORD dwColor); SIZEL* GetExtent(); @@ -765,7 +766,7 @@ void CTxtWinHost::SetWordWrap(BOOL fWordWrap) pserv->OnTxPropertyBitsChange(TXTBIT_WORDWRAP, fWordWrap ? TXTBIT_WORDWRAP : 0); } -BOOL CTxtWinHost::GetReadOnly() +BOOL CTxtWinHost::IsReadOnly() { return (dwStyle & ES_READONLY) != 0; } @@ -1090,7 +1091,7 @@ CRichEditUI::~CRichEditUI() LPCTSTR CRichEditUI::GetClass() const { - return _T("RichEditUI"); + return DUI_CTR_RICHEDIT; } LPVOID CRichEditUI::GetInterface(LPCTSTR pstrName) @@ -1169,7 +1170,7 @@ void CRichEditUI::SetReadOnly(bool bReadOnly) if( m_pTwh ) m_pTwh->SetReadOnly(bReadOnly); } -bool CRichEditUI::GetWordWrap() +bool CRichEditUI::IsWordWrap() { return m_bWordWrap; } @@ -1294,7 +1295,7 @@ void CRichEditUI::SetText(LPCTSTR pstrText) ReplaceSel(pstrText, FALSE); } -bool CRichEditUI::GetModify() const +bool CRichEditUI::IsModify() const { if( !m_pTwh ) return false; LRESULT lResult; @@ -1967,14 +1968,6 @@ void CRichEditUI::DoEvent(TEventUI& event) { return; } - if( event.Type == UIEVENT_MOUSEENTER ) - { - return; - } - if( event.Type == UIEVENT_MOUSELEAVE ) - { - return; - } if( event.Type > UIEVENT__KEYBEGIN && event.Type < UIEVENT__KEYEND ) { return; @@ -2091,10 +2084,10 @@ void CRichEditUI::Move(SIZE szOffset, bool bNeedInvalidate) } } -void CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { RECT rcTemp = { 0 }; - if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return; + if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true; CRenderClip clip; CRenderClip::GenerateClip(hDC, rcTemp, clip); @@ -2149,12 +2142,12 @@ void CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) { for( int it = 0; it < m_items.GetSize(); it++ ) { CControlUI* pControl = static_cast(m_items[it]); - if( pControl == pStopControl ) break; + if( pControl == pStopControl ) return false; if( !pControl->IsVisible() ) continue; if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; if( pControl->IsFloat() ) { if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; } } } @@ -2163,18 +2156,18 @@ void CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl CRenderClip::GenerateClip(hDC, rcTemp, childClip); for( int it = 0; it < m_items.GetSize(); it++ ) { CControlUI* pControl = static_cast(m_items[it]); - if( pControl == pStopControl ) break; + if( pControl == pStopControl ) return false; if( !pControl->IsVisible() ) continue; if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; if( pControl->IsFloat() ) { if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; CRenderClip::UseOldClipBegin(hDC, childClip); - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; CRenderClip::UseOldClipEnd(hDC, childClip); } else { if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue; - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; } } } @@ -2189,17 +2182,24 @@ void CRichEditUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl } } - if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() ) { - if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { - m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl); + if( m_pVerticalScrollBar != NULL ) { + if( m_pVerticalScrollBar == pStopControl ) return false; + if (m_pVerticalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { + if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } } } - if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) { - if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { - m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl); + if( m_pHorizontalScrollBar != NULL ) { + if( m_pHorizontalScrollBar == pStopControl ) return false; + if (m_pHorizontalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { + if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } } } + return true; } void CRichEditUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) @@ -2307,7 +2307,7 @@ LRESULT CRichEditUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, boo if( dwHitResult != HITRESULT_HIT ) return 0; if( uMsg == WM_SETCURSOR ) bWasHandled = false; else if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN ) { - ::SetFocus(GetManager()->GetPaintWindow()); + if (!GetManager()->IsNoActivate()) ::SetFocus(GetManager()->GetPaintWindow()); SetFocus(); } } diff --git a/DuiLib/Control/UIRichEdit.h b/DuiLib/Control/UIRichEdit.h index d08e2200..0c889db6 100644 --- a/DuiLib/Control/UIRichEdit.h +++ b/DuiLib/Control/UIRichEdit.h @@ -7,7 +7,7 @@ namespace DuiLib { class CTxtWinHost; -class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI +class DUILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI { public: CRichEditUI(); @@ -29,7 +29,7 @@ class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI void SetRich(bool bRich = true); bool IsReadOnly(); void SetReadOnly(bool bReadOnly = true); - bool GetWordWrap(); + bool IsWordWrap(); void SetWordWrap(bool bWordWrap = true); int GetFont(); void SetFont(int index); @@ -43,7 +43,7 @@ class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI long GetTextLength(DWORD dwFlags = GTL_DEFAULT) const; CDuiString GetText() const; void SetText(LPCTSTR pstrText); - bool GetModify() const; + bool IsModify() const; void SetModify(bool bModified = true) const; void GetSel(CHARRANGE &cr) const; void GetSel(long& nStartChar, long& nEndChar) const; @@ -121,7 +121,7 @@ class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI void SetPos(RECT rc, bool bNeedInvalidate = true); void Move(SIZE szOffset, bool bNeedInvalidate = true); void DoEvent(TEventUI& event); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); diff --git a/DuiLib/Control/UIScrollBar.cpp b/DuiLib/Control/UIScrollBar.cpp index 81d991d7..01de6f7c 100644 --- a/DuiLib/Control/UIScrollBar.cpp +++ b/DuiLib/Control/UIScrollBar.cpp @@ -7,7 +7,8 @@ CScrollBarUI::CScrollBarUI() : m_bHorizontal(false), m_nRange(100), m_nScrollPos(0), - m_nLineSize(8), + m_nLineSize(SCROLLBAR_LINESIZE), + m_nScrollUnit(1), m_pOwner(NULL), m_nLastScrollPos(0), m_nLastScrollOffset(0), @@ -30,7 +31,7 @@ CScrollBarUI::CScrollBarUI() : LPCTSTR CScrollBarUI::GetClass() const { - return _T("ScrollBarUI"); + return DUI_CTR_SCROLLBAR; } LPVOID CScrollBarUI::GetInterface(LPCTSTR pstrName) @@ -127,7 +128,15 @@ void CScrollBarUI::SetScrollPos(int nPos, bool bTriggerEvent) int iOldScrollPos = m_nScrollPos; m_nScrollPos = nPos; if( m_nScrollPos < 0 ) m_nScrollPos = 0; + if( m_nScrollUnit > 1 ) { + int iLeftOffset = m_nScrollPos % m_nScrollUnit; + if( iLeftOffset != 0 ) { + if( iLeftOffset >= m_nScrollUnit/2 ) m_nScrollPos += m_nScrollUnit - iLeftOffset; + else m_nScrollPos -= iLeftOffset; + } + } if( m_nScrollPos > m_nRange ) m_nScrollPos = m_nRange; + SetPos(m_rcItem, true); if(bTriggerEvent && m_pManager != NULL) @@ -136,12 +145,23 @@ void CScrollBarUI::SetScrollPos(int nPos, bool bTriggerEvent) int CScrollBarUI::GetLineSize() const { + if (m_nScrollUnit > 1) return m_nScrollUnit; return m_nLineSize; } void CScrollBarUI::SetLineSize(int nSize) { - m_nLineSize = nSize; + if (nSize >= 0) m_nLineSize = nSize; +} + +int CScrollBarUI::GetScrollUnit() const +{ + return m_nScrollUnit; +} + +void CScrollBarUI::SetScrollUnit(int iUnit) +{ + if (iUnit >= 0) m_nScrollUnit = iUnit; } bool CScrollBarUI::GetShowButton1() @@ -643,22 +663,22 @@ void CScrollBarUI::DoEvent(TEventUI& event) m_uButton1State |= UISTATE_PUSHED; if( !m_bHorizontal ) { if( m_pOwner != NULL ) m_pOwner->LineUp(); - else SetScrollPos(m_nScrollPos - m_nLineSize); + else SetScrollPos(m_nScrollPos - GetLineSize()); } else { if( m_pOwner != NULL ) m_pOwner->LineLeft(); - else SetScrollPos(m_nScrollPos - m_nLineSize); + else SetScrollPos(m_nScrollPos - GetLineSize()); } } else if( ::PtInRect(&m_rcButton2, event.ptMouse) ) { m_uButton2State |= UISTATE_PUSHED; if( !m_bHorizontal ) { if( m_pOwner != NULL ) m_pOwner->LineDown(); - else SetScrollPos(m_nScrollPos + m_nLineSize); + else SetScrollPos(m_nScrollPos + GetLineSize()); } else { if( m_pOwner != NULL ) m_pOwner->LineRight(); - else SetScrollPos(m_nScrollPos + m_nLineSize); + else SetScrollPos(m_nScrollPos + GetLineSize()); } } else if( ::PtInRect(&m_rcThumb, event.ptMouse) ) { @@ -770,22 +790,22 @@ void CScrollBarUI::DoEvent(TEventUI& event) if( m_nScrollRepeatDelay <= 5 ) return; if( !m_bHorizontal ) { if( m_pOwner != NULL ) m_pOwner->LineUp(); - else SetScrollPos(m_nScrollPos - m_nLineSize); + else SetScrollPos(m_nScrollPos - GetLineSize()); } else { if( m_pOwner != NULL ) m_pOwner->LineLeft(); - else SetScrollPos(m_nScrollPos - m_nLineSize); + else SetScrollPos(m_nScrollPos - GetLineSize()); } } else if( (m_uButton2State & UISTATE_PUSHED) != 0 ) { if( m_nScrollRepeatDelay <= 5 ) return; if( !m_bHorizontal ) { if( m_pOwner != NULL ) m_pOwner->LineDown(); - else SetScrollPos(m_nScrollPos + m_nLineSize); + else SetScrollPos(m_nScrollPos + GetLineSize()); } else { if( m_pOwner != NULL ) m_pOwner->LineRight(); - else SetScrollPos(m_nScrollPos + m_nLineSize); + else SetScrollPos(m_nScrollPos + GetLineSize()); } } else { @@ -818,23 +838,30 @@ void CScrollBarUI::DoEvent(TEventUI& event) } if( event.Type == UIEVENT_MOUSEENTER ) { - if( IsEnabled() ) { - m_uButton1State |= UISTATE_HOT; - m_uButton2State |= UISTATE_HOT; - if( ::PtInRect(&m_rcThumb, event.ptMouse) ) m_uThumbState |= UISTATE_HOT; - Invalidate(); - } - return; + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + m_uButton1State |= UISTATE_HOT; + m_uButton2State |= UISTATE_HOT; + if( ::PtInRect(&m_rcThumb, event.ptMouse) ) m_uThumbState |= UISTATE_HOT; + Invalidate(); + } + } } if( event.Type == UIEVENT_MOUSELEAVE ) { - if( IsEnabled() ) { - m_uButton1State &= ~UISTATE_HOT; - m_uButton2State &= ~UISTATE_HOT; - m_uThumbState &= ~UISTATE_HOT; - Invalidate(); - } - return; + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + m_uButton1State &= ~UISTATE_HOT; + m_uButton2State &= ~UISTATE_HOT; + m_uThumbState &= ~UISTATE_HOT; + Invalidate(); + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } } if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event); @@ -887,12 +914,13 @@ void CScrollBarUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) else if( _tcscmp(pstrName, _T("linesize")) == 0 ) SetLineSize(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("range")) == 0 ) SetScrollRange(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("value")) == 0 ) SetScrollPos(_ttoi(pstrValue)); + else if( _tcscmp(pstrName, _T("scrollunit")) == 0 ) SetScrollUnit(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("showbutton1")) == 0 ) SetShowButton1(_tcscmp(pstrValue, _T("true")) == 0); else if( _tcscmp(pstrName, _T("showbutton2")) == 0 ) SetShowButton2(_tcscmp(pstrValue, _T("true")) == 0); else CControlUI::SetAttribute(pstrName, pstrValue); } -void CScrollBarUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CScrollBarUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { PaintBkColor(hDC); PaintBkImage(hDC); @@ -902,6 +930,7 @@ void CScrollBarUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopContro PaintThumb(hDC); PaintRail(hDC); PaintBorder(hDC); + return true; } void CScrollBarUI::PaintBk(HDC hDC) diff --git a/DuiLib/Control/UIScrollBar.h b/DuiLib/Control/UIScrollBar.h index 532f0cec..80c24254 100644 --- a/DuiLib/Control/UIScrollBar.h +++ b/DuiLib/Control/UIScrollBar.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CScrollBarUI : public CControlUI + class DUILIB_API CScrollBarUI : public CControlUI { public: CScrollBarUI(); @@ -28,6 +28,8 @@ namespace DuiLib void SetScrollPos(int nPos, bool bTriggerEvent=true); int GetLineSize() const; void SetLineSize(int nSize); + int GetScrollUnit() const; + void SetScrollUnit(int iUnit); bool GetShowButton1(); void SetShowButton1(bool bShow); @@ -88,7 +90,7 @@ namespace DuiLib void DoEvent(TEventUI& event); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void PaintBk(HDC hDC); void PaintButton1(HDC hDC); @@ -108,6 +110,7 @@ namespace DuiLib int m_nRange; int m_nScrollPos; int m_nLineSize; + int m_nScrollUnit; CContainerUI* m_pOwner; POINT ptLastMouse; int m_nLastScrollPos; diff --git a/DuiLib/Control/UISlider.cpp b/DuiLib/Control/UISlider.cpp index e5937bb5..91d3f88f 100644 --- a/DuiLib/Control/UISlider.cpp +++ b/DuiLib/Control/UISlider.cpp @@ -11,7 +11,7 @@ namespace DuiLib LPCTSTR CSliderUI::GetClass() const { - return _T("SliderUI"); + return DUI_CTR_SLIDER; } UINT CSliderUI::GetControlFlags() const @@ -184,7 +184,7 @@ namespace DuiLib case SB_LINEDOWN: SetValue(GetValue() - GetChangeStep()); m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED); - return; + return; } } if( event.Type == UIEVENT_MOUSEMOVE ) @@ -213,22 +213,33 @@ namespace DuiLib return; } } - if( event.Type == UIEVENT_MOUSEENTER ) - { - if( IsEnabled() ) { - m_uButtonState |= UISTATE_HOT; - Invalidate(); - } - return; - } - if( event.Type == UIEVENT_MOUSELEAVE ) - { - if( IsEnabled() ) { - m_uButtonState &= ~UISTATE_HOT; - Invalidate(); - } - return; - } + if( event.Type == UIEVENT_MOUSEENTER ) + { + if( ::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) == 0 ) { + m_uButtonState |= UISTATE_HOT; + Invalidate(); + } + } + } + } + if( event.Type == UIEVENT_MOUSELEAVE ) + { + if( !::PtInRect(&m_rcItem, event.ptMouse ) ) { + if( IsEnabled() ) { + if( (m_uButtonState & UISTATE_HOT) != 0 ) { + m_uButtonState &= ~UISTATE_HOT; + Invalidate(); + } + } + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } + } CControlUI::DoEvent(event); } diff --git a/DuiLib/Control/UISlider.h b/DuiLib/Control/UISlider.h index 8ac9ccdd..ab387577 100644 --- a/DuiLib/Control/UISlider.h +++ b/DuiLib/Control/UISlider.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CSliderUI : public CProgressUI + class DUILIB_API CSliderUI : public CProgressUI { public: CSliderUI(); diff --git a/DuiLib/Control/UIText.cpp b/DuiLib/Control/UIText.cpp index fe9fdaaf..3304bd40 100644 --- a/DuiLib/Control/UIText.cpp +++ b/DuiLib/Control/UIText.cpp @@ -17,7 +17,7 @@ namespace DuiLib LPCTSTR CTextUI::GetClass() const { - return _T("TextUI"); + return DUI_CTR_TEXT; } LPVOID CTextUI::GetInterface(LPCTSTR pstrName) @@ -93,9 +93,15 @@ namespace DuiLib if( event.Type == UIEVENT_MOUSELEAVE ) { if( m_nLinks > 0 && IsEnabled() ) { if(m_nHoverLink != -1) { - m_nHoverLink = -1; - Invalidate(); - return; + if( !::PtInRect(&m_rcLinks[m_nHoverLink], event.ptMouse) ) { + m_nHoverLink = -1; + Invalidate(); + if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this); + } + else { + if (m_pManager) m_pManager->AddMouseLeaveNeeded(this); + return; + } } } } @@ -103,25 +109,6 @@ namespace DuiLib CLabelUI::DoEvent(event); } - SIZE CTextUI::EstimateSize(SIZE szAvailable) - { - RECT rcText = { 0, 0, MAX(szAvailable.cx, m_cxyFixed.cx), 9999 }; - rcText.left += m_rcTextPadding.left; - rcText.right -= m_rcTextPadding.right; - if( m_bShowHtml ) { - int nLinks = 0; - CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, m_dwTextColor, NULL, NULL, nLinks, DT_CALCRECT | m_uTextStyle); - } - else { - CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, m_dwTextColor, m_iFont, DT_CALCRECT | m_uTextStyle); - } - SIZE cXY = {rcText.right - rcText.left + m_rcTextPadding.left + m_rcTextPadding.right, - rcText.bottom - rcText.top + m_rcTextPadding.top + m_rcTextPadding.bottom}; - - if( m_cxyFixed.cy != 0 ) cXY.cy = m_cxyFixed.cy; - return cXY; - } - void CTextUI::PaintText(HDC hDC) { if( m_sText.IsEmpty() ) { @@ -143,7 +130,7 @@ namespace DuiLib if( IsEnabled() ) { if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, m_dwTextColor, \ - m_rcLinks, m_sLinks, m_nLinks, m_uTextStyle); + m_rcLinks, m_sLinks, m_nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, m_dwTextColor, \ m_iFont, m_uTextStyle); @@ -151,7 +138,7 @@ namespace DuiLib else { if( m_bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, m_sText, m_dwDisabledTextColor, \ - m_rcLinks, m_sLinks, m_nLinks, m_uTextStyle); + m_rcLinks, m_sLinks, m_nLinks, m_iFont, m_uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rc, m_sText, m_dwDisabledTextColor, \ m_iFont, m_uTextStyle); diff --git a/DuiLib/Control/UIText.h b/DuiLib/Control/UIText.h index 615e7575..76410529 100644 --- a/DuiLib/Control/UIText.h +++ b/DuiLib/Control/UIText.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CTextUI : public CLabelUI + class DUILIB_API CTextUI : public CLabelUI { public: CTextUI(); @@ -18,7 +18,6 @@ namespace DuiLib CDuiString* GetLinkContent(int iIndex); void DoEvent(TEventUI& event); - SIZE EstimateSize(SIZE szAvailable); void PaintText(HDC hDC); diff --git a/DuiLib/Control/UITreeView.cpp b/DuiLib/Control/UITreeView.cpp index 05b2e115..4629571a 100644 --- a/DuiLib/Control/UITreeView.cpp +++ b/DuiLib/Control/UITreeView.cpp @@ -41,7 +41,7 @@ namespace DuiLib if(_ParentNode) { - if (_tcsicmp(_ParentNode->GetClass(), _T("TreeNodeUI")) != 0) + if (_tcsicmp(_ParentNode->GetClass(), DUI_CTR_TREENODE) != 0) return; pDottedLine->SetVisible(_ParentNode->IsVisible()); @@ -74,7 +74,7 @@ namespace DuiLib //************************************ LPCTSTR CTreeNodeUI::GetClass() const { - return _T("TreeNodeUI"); + return DUI_CTR_TREENODE; } //************************************ @@ -85,8 +85,7 @@ namespace DuiLib //************************************ LPVOID CTreeNodeUI::GetInterface( LPCTSTR pstrName ) { - if( _tcscmp(pstrName, _T("TreeNode")) == 0 ) - return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_TREENODE) == 0 ) return static_cast(this); return CListContainerElementUI::GetInterface(pstrName); } @@ -109,7 +108,7 @@ namespace DuiLib if( event.Type == UIEVENT_DBLCLICK ) { if( IsEnabled() ) { - m_pManager->SendNotify(this, _T("itemdbclick")); + m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMDBCLICK); Invalidate(); } return; @@ -125,7 +124,7 @@ namespace DuiLib else pItemButton->SetTextColor(pItemButton->GetDisabledTextColor()); - return; + //return; } if( event.Type == UIEVENT_MOUSELEAVE ) { @@ -138,7 +137,7 @@ namespace DuiLib else pItemButton->SetTextColor(pItemButton->GetDisabledTextColor()); - return; + //return; } } @@ -153,7 +152,7 @@ namespace DuiLib return; if( GetParent() ) { - CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(_T("Container"))); + CContainerUI* pParentContainer = static_cast(GetParent()->GetInterface(DUI_CTR_CONTAINER)); if( pParentContainer ) { RECT rc = pParentContainer->GetPos(); RECT rcInset = pParentContainer->GetInset(); @@ -217,7 +216,7 @@ namespace DuiLib //************************************ bool CTreeNodeUI::Add( CControlUI* _pTreeNodeUI ) { - if (_tcsicmp(_pTreeNodeUI->GetClass(), _T("TreeNodeUI")) == 0) + if (_tcsicmp(_pTreeNodeUI->GetClass(), DUI_CTR_TREENODE) == 0) return AddChildNode((CTreeNodeUI*)_pTreeNodeUI); return CListContainerElementUI::Add(_pTreeNodeUI); @@ -232,7 +231,7 @@ namespace DuiLib //************************************ bool CTreeNodeUI::AddAt( CControlUI* pControl, int iIndex ) { - if(NULL == static_cast(pControl->GetInterface(_T("TreeNode")))) + if(NULL == static_cast(pControl->GetInterface(DUI_CTR_TREENODE))) return false; CTreeNodeUI* pIndexNode = static_cast(mTreeNodes.GetAt(iIndex)); @@ -244,7 +243,7 @@ namespace DuiLib return false; if(!pIndexNode && pTreeView && pTreeView->GetItemAt(GetTreeIndex()+1)) - pIndexNode = static_cast(pTreeView->GetItemAt(GetTreeIndex()+1)->GetInterface(_T("TreeNode"))); + pIndexNode = static_cast(pTreeView->GetItemAt(GetTreeIndex()+1)->GetInterface(DUI_CTR_TREENODE)); pControl = CalLocation((CTreeNodeUI*)pControl); @@ -256,17 +255,6 @@ namespace DuiLib return true; } - //************************************ - // 函数名称: Remove - // 返回类型: bool - // 参数信息: CControlUI * pControl - // 函数说明: - //************************************ - bool CTreeNodeUI::Remove( CControlUI* pControl ) - { - return RemoveAt((CTreeNodeUI*)pControl); - } - //************************************ // 函数名称: SetVisibleTag // 返回类型: void @@ -351,7 +339,7 @@ namespace DuiLib if (!_pTreeNodeUI) return false; - if (_tcsicmp(_pTreeNodeUI->GetClass(), _T("TreeNodeUI")) != 0) + if (_tcsicmp(_pTreeNodeUI->GetClass(), DUI_CTR_TREENODE) != 0) return false; _pTreeNodeUI = CalLocation(_pTreeNodeUI); @@ -460,15 +448,15 @@ namespace DuiLib if(_tcscmp(pstrName, _T("text")) == 0 ) pItemButton->SetText(pstrValue); else if(_tcscmp(pstrName, _T("horizattr")) == 0 ) - pHoriz->ApplyAttributeList(pstrValue); + pHoriz->SetAttributeList(pstrValue); else if(_tcscmp(pstrName, _T("dotlineattr")) == 0 ) - pDottedLine->ApplyAttributeList(pstrValue); + pDottedLine->SetAttributeList(pstrValue); else if(_tcscmp(pstrName, _T("folderattr")) == 0 ) - pFolderButton->ApplyAttributeList(pstrValue); + pFolderButton->SetAttributeList(pstrValue); else if(_tcscmp(pstrName, _T("checkboxattr")) == 0 ) - pCheckBox->ApplyAttributeList(pstrValue); + pCheckBox->SetAttributeList(pstrValue); else if(_tcscmp(pstrName, _T("itemattr")) == 0 ) - pItemButton->ApplyAttributeList(pstrValue); + pItemButton->SetAttributeList(pstrValue); else if(_tcscmp(pstrName, _T("itemtextcolor")) == 0 ){ if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; @@ -498,10 +486,10 @@ namespace DuiLib //************************************ // 函数名称: GetTreeNodes - // 返回类型: UiLib::CStdPtrArray + // 返回类型: UiLib::CDuiPtrArray // 函数说明: //************************************ - CStdPtrArray CTreeNodeUI::GetTreeNodes() + CDuiPtrArray CTreeNodeUI::GetTreeNodes() { return mTreeNodes; } @@ -759,115 +747,129 @@ namespace DuiLib //************************************ LPCTSTR CTreeViewUI::GetClass() const { - return _T("TreeViewUI"); + return DUI_CTR_TREEVIEW; } - //************************************ - // 函数名称: GetInterface - // 返回类型: LPVOID - // 参数信息: LPCTSTR pstrName - // 函数说明: - //************************************ LPVOID CTreeViewUI::GetInterface( LPCTSTR pstrName ) { - if( _tcscmp(pstrName, _T("TreeView")) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_TREEVIEW) == 0 ) return static_cast(this); return CListUI::GetInterface(pstrName); } - //************************************ - // 函数名称: Add - // 返回类型: bool - // 参数信息: CTreeNodeUI * pControl - // 函数说明: - //************************************ - bool CTreeViewUI::Add( CTreeNodeUI* pControl ) + bool CTreeViewUI::Add(CControlUI* pControl) { - if (!pControl) - return false; + if (!pControl) return false; - if (_tcsicmp(pControl->GetClass(), _T("TreeNodeUI")) != 0) - return false; + CTreeNodeUI* pTreeNode = static_cast(pControl->GetInterface(DUI_CTR_TREENODE)); + if (pTreeNode == NULL) return false; - pControl->OnNotify += MakeDelegate(this,&CTreeViewUI::OnDBClickItem); - pControl->GetFolderButton()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnFolderChanged); - pControl->GetCheckBox()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnCheckBoxChanged); + pTreeNode->OnNotify += MakeDelegate(this,&CTreeViewUI::OnDBClickItem); + pTreeNode->GetFolderButton()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnFolderChanged); + pTreeNode->GetCheckBox()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnCheckBoxChanged); - pControl->SetVisibleFolderBtn(m_bVisibleFolderBtn); - pControl->SetVisibleCheckBtn(m_bVisibleCheckBtn); - if(m_uItemMinWidth > 0) - pControl->SetMinWidth(m_uItemMinWidth); + pTreeNode->SetVisibleFolderBtn(m_bVisibleFolderBtn); + pTreeNode->SetVisibleCheckBtn(m_bVisibleCheckBtn); + if(m_uItemMinWidth > 0) pTreeNode->SetMinWidth(m_uItemMinWidth); - CListUI::Add(pControl); + CListUI::Add(pTreeNode); - if(pControl->GetCountChild() > 0) + if(pTreeNode->GetCountChild() > 0) { - int nCount = pControl->GetCountChild(); + int nCount = pTreeNode->GetCountChild(); for(int nIndex = 0;nIndex < nCount;nIndex++) { - CTreeNodeUI* pNode = pControl->GetChildNode(nIndex); - if(pNode) - Add(pNode); + CTreeNodeUI* pNode = pTreeNode->GetChildNode(nIndex); + if(pNode) Add(pNode); } } - pControl->SetTreeView(this); + pTreeNode->SetTreeView(this); return true; } - //************************************ - // 函数名称: AddAt - // 返回类型: long - // 参数信息: CTreeNodeUI * pControl - // 参数信息: int iIndex - // 函数说明: 该方法不会将待插入的节点进行缩位处理,若打算插入的节点为非根节点,请使用AddAt(CTreeNodeUI* pControl,CTreeNodeUI* _IndexNode) 方法 - //************************************ - long CTreeViewUI::AddAt( CTreeNodeUI* pControl, int iIndex ) - { - if (!pControl) - return -1; - - if (_tcsicmp(pControl->GetClass(), _T("TreeNodeUI")) != 0) - return -1; - - CTreeNodeUI* pParent = static_cast(GetItemAt(iIndex)); - if(!pParent) - return -1; - - pControl->OnNotify += MakeDelegate(this,&CTreeViewUI::OnDBClickItem); - pControl->GetFolderButton()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnFolderChanged); - pControl->GetCheckBox()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnCheckBoxChanged); + bool CTreeViewUI::AddAt(CControlUI* pControl, int iIndex) + { + if (!pControl) return false; - pControl->SetVisibleFolderBtn(m_bVisibleFolderBtn); - pControl->SetVisibleCheckBtn(m_bVisibleCheckBtn); + CTreeNodeUI* pTreeNode = static_cast(pControl->GetInterface(DUI_CTR_TREENODE)); + if (pTreeNode == NULL) return false; + return AddAt(pTreeNode, iIndex) >= 0; + } - if(m_uItemMinWidth > 0) - pControl->SetMinWidth(m_uItemMinWidth); + bool CTreeViewUI::Remove(CControlUI* pControl, bool bDoNotDestroy) + { + if (!pControl) return false; - CListUI::AddAt(pControl,iIndex); + CTreeNodeUI* pTreeNode = static_cast(pControl->GetInterface(DUI_CTR_TREENODE)); + if (pTreeNode == NULL) return CListUI::Remove(pControl, bDoNotDestroy); - if(pControl->GetCountChild() > 0) + if(pTreeNode->GetCountChild() > 0) { - int nCount = pControl->GetCountChild(); + int nCount = pTreeNode->GetCountChild(); for(int nIndex = 0;nIndex < nCount;nIndex++) { - CTreeNodeUI* pNode = pControl->GetChildNode(nIndex); - if(pNode) - return AddAt(pNode,iIndex+1); + CTreeNodeUI* pNode = pTreeNode->GetChildNode(nIndex); + if(pNode){ + pTreeNode->Remove(pNode, true); + } } } - else - return iIndex+1; + return CListUI::Remove(pControl, bDoNotDestroy); + } - return -1; + bool CTreeViewUI::RemoveAt( int iIndex, bool bDoNotDestroy ) + { + CControlUI* pControl = GetItemAt(iIndex); + if (pControl == NULL) return false; + + CTreeNodeUI* pTreeNode = static_cast(pControl->GetInterface(DUI_CTR_TREENODE)); + if (pTreeNode == NULL) return CListUI::Remove(pControl, bDoNotDestroy); + + return Remove(pTreeNode); } - //************************************ - // 函数名称: AddAt - // 返回类型: bool - // 参数信息: CTreeNodeUI * pControl - // 参数信息: CTreeNodeUI * _IndexNode - // 函数说明: - //************************************ + void CTreeViewUI::RemoveAll() + { + CListUI::RemoveAll(); + } + + long CTreeViewUI::AddAt(CTreeNodeUI* pControl, int iIndex) + { + if (!pControl) return -1; + + CTreeNodeUI* pTreeNode = static_cast(pControl->GetInterface(DUI_CTR_TREENODE)); + if (pTreeNode == NULL) return -1; + + CTreeNodeUI* pParent = static_cast(GetItemAt(iIndex)); + if(!pParent) return -1; + + pTreeNode->OnNotify += MakeDelegate(this,&CTreeViewUI::OnDBClickItem); + pTreeNode->GetFolderButton()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnFolderChanged); + pTreeNode->GetCheckBox()->OnNotify += MakeDelegate(this,&CTreeViewUI::OnCheckBoxChanged); + + pTreeNode->SetVisibleFolderBtn(m_bVisibleFolderBtn); + pTreeNode->SetVisibleCheckBtn(m_bVisibleCheckBtn); + + if(m_uItemMinWidth > 0) pTreeNode->SetMinWidth(m_uItemMinWidth); + + CListUI::AddAt(pTreeNode,iIndex); + + if(pTreeNode->GetCountChild() > 0) + { + int nCount = pTreeNode->GetCountChild(); + for(int nIndex = 0;nIndex < nCount;nIndex++) + { + CTreeNodeUI* pNode = pTreeNode->GetChildNode(nIndex); + if(pNode) + return AddAt(pNode,iIndex+1); + } + } + else + return iIndex+1; + + return -1; + } + bool CTreeViewUI::AddAt( CTreeNodeUI* pControl,CTreeNodeUI* _IndexNode ) { if(!_IndexNode && !pControl) @@ -888,48 +890,6 @@ namespace DuiLib return AddAt(pControl,nItemIndex) >= 0; } - //************************************ - // 函数名称: Remove - // 返回类型: bool - // 参数信息: CTreeNodeUI * pControl - // 函数说明: pControl 对象以及下的所有节点将被一并移除 - //************************************ - bool CTreeViewUI::Remove( CTreeNodeUI* pControl ) - { - if(pControl->GetCountChild() > 0) - { - int nCount = pControl->GetCountChild(); - for(int nIndex = 0;nIndex < nCount;nIndex++) - { - CTreeNodeUI* pNode = pControl->GetChildNode(nIndex); - if(pNode){ - pControl->Remove(pNode); - } - } - } - CListUI::Remove(pControl); - return true; - } - - //************************************ - // 函数名称: RemoveAt - // 返回类型: bool - // 参数信息: int iIndex - // 函数说明: iIndex 索引以及下的所有节点将被一并移除 - //************************************ - bool CTreeViewUI::RemoveAt( int iIndex ) - { - CTreeNodeUI* pItem = (CTreeNodeUI*)GetItemAt(iIndex); - if(pItem->GetCountChild()) - Remove(pItem); - return true; - } - - void CTreeViewUI::RemoveAll() - { - CListUI::RemoveAll(); - } - //************************************ // 函数名称: Notify // 返回类型: void @@ -950,7 +910,7 @@ namespace DuiLib bool CTreeViewUI::OnCheckBoxChanged( void* param ) { TNotifyUI* pMsg = (TNotifyUI*)param; - if(pMsg->sType == _T("selectchanged")) + if(pMsg->sType == DUI_MSGTYPE_SELECTCHANGED) { CCheckBoxUI* pCheckBox = (CCheckBoxUI*)pMsg->pSender; CTreeNodeUI* pItem = (CTreeNodeUI*)pCheckBox->GetParent()->GetParent(); @@ -969,7 +929,7 @@ namespace DuiLib bool CTreeViewUI::OnFolderChanged( void* param ) { TNotifyUI* pMsg = (TNotifyUI*)param; - if(pMsg->sType == _T("selectchanged")) + if(pMsg->sType == DUI_MSGTYPE_SELECTCHANGED) { CCheckBoxUI* pFolder = (CCheckBoxUI*)pMsg->pSender; CTreeNodeUI* pItem = (CTreeNodeUI*)pFolder->GetParent()->GetParent(); @@ -989,7 +949,7 @@ namespace DuiLib bool CTreeViewUI::OnDBClickItem( void* param ) { TNotifyUI* pMsg = (TNotifyUI*)param; - if(pMsg->sType == _T("itemdbclick")) + if(pMsg->sType == DUI_MSGTYPE_ITEMDBCLICK) { CTreeNodeUI* pItem = static_cast(pMsg->pSender); CCheckBoxUI* pFolder = pItem->GetFolderButton(); diff --git a/DuiLib/Control/UITreeView.h b/DuiLib/Control/UITreeView.h index 5d0d49b6..b1dd1713 100644 --- a/DuiLib/Control/UITreeView.h +++ b/DuiLib/Control/UITreeView.h @@ -1,5 +1,5 @@ -#ifndef UITreeView_h__ -#define UITreeView_h__ +#ifndef __UITREEVIEW_H__ +#define __UITREEVIEW_H__ #include using namespace std; @@ -13,7 +13,7 @@ namespace DuiLib class CLabelUI; class COptionUI; - class UILIB_API CTreeNodeUI : public CListContainerElementUI + class DUILIB_API CTreeNodeUI : public CListContainerElementUI { public: CTreeNodeUI(CTreeNodeUI* _ParentNode = NULL); @@ -28,7 +28,6 @@ namespace DuiLib bool Add(CControlUI* _pTreeNodeUI); bool AddAt(CControlUI* pControl, int iIndex); - bool Remove(CControlUI* pControl); void SetVisibleTag(bool _IsVisible); bool GetVisibleTag(); @@ -61,7 +60,7 @@ namespace DuiLib void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); - CStdPtrArray GetTreeNodes(); + CDuiPtrArray GetTreeNodes(); int GetTreeIndex(); int GetNodeIndex(); @@ -94,10 +93,10 @@ namespace DuiLib CTreeNodeUI* pParentTreeNode; - CStdPtrArray mTreeNodes; + CDuiPtrArray mTreeNodes; }; - class UILIB_API CTreeViewUI : public CListUI,public INotifyUI + class DUILIB_API CTreeViewUI : public CListUI,public INotifyUI { public: CTreeViewUI(void); @@ -106,12 +105,15 @@ namespace DuiLib public: virtual LPCTSTR GetClass() const; virtual LPVOID GetInterface(LPCTSTR pstrName); - virtual bool Add(CTreeNodeUI* pControl ); - virtual long AddAt(CTreeNodeUI* pControl, int iIndex ); - virtual bool AddAt(CTreeNodeUI* pControl,CTreeNodeUI* _IndexNode); - virtual bool Remove(CTreeNodeUI* pControl); - virtual bool RemoveAt(int iIndex); - virtual void RemoveAll(); + virtual bool Add(CControlUI* pControl); + virtual bool AddAt(CControlUI* pControl, int iIndex); + virtual bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); + virtual bool RemoveAt(int iIndex, bool bDoNotDestroy=false); + virtual void RemoveAll(); + + long AddAt(CTreeNodeUI* pControl, int iIndex); + bool AddAt(CTreeNodeUI* pControl,CTreeNodeUI* _IndexNode); + virtual bool OnCheckBoxChanged(void* param); virtual bool OnFolderChanged(void* param); virtual bool OnDBClickItem(void* param); @@ -138,4 +140,4 @@ namespace DuiLib } -#endif // UITreeView_h__ +#endif // __UITREEVIEW_H__ diff --git a/DuiLib/Control/UIWebBrowser.cpp b/DuiLib/Control/UIWebBrowser.cpp index 38977b24..b1364aa9 100644 --- a/DuiLib/Control/UIWebBrowser.cpp +++ b/DuiLib/Control/UIWebBrowser.cpp @@ -500,7 +500,7 @@ void CWebBrowserUI::NavigateUrl( LPCTSTR lpszUrl ) LPCTSTR CWebBrowserUI::GetClass() const { - return _T("WebBrowserUI"); + return DUI_CTR_WEBBROWSER; } LPVOID CWebBrowserUI::GetInterface( LPCTSTR pstrName ) diff --git a/DuiLib/Control/UIWebBrowser.h b/DuiLib/Control/UIWebBrowser.h index a89ab2ff..1951d4df 100644 --- a/DuiLib/Control/UIWebBrowser.h +++ b/DuiLib/Control/UIWebBrowser.h @@ -8,7 +8,7 @@ namespace DuiLib { - class UILIB_API CWebBrowserUI + class DUILIB_API CWebBrowserUI : public CActiveXUI , public IDocHostUIHandler , public IServiceProvider diff --git a/DuiLib/Core/UIBase.cpp b/DuiLib/Core/UIBase.cpp index f1f3f3e0..86f07a80 100644 --- a/DuiLib/Core/UIBase.cpp +++ b/DuiLib/Core/UIBase.cpp @@ -11,7 +11,7 @@ namespace DuiLib { // // -void UILIB_API DUI__Trace(LPCTSTR pstrFormat, ...) +void DUILIB_API DUI__Trace(LPCTSTR pstrFormat, ...) { #ifdef _DEBUG TCHAR szBuffer[300] = { 0 }; diff --git a/DuiLib/Core/UIBase.h b/DuiLib/Core/UIBase.h index a80ce286..81ecf8ab 100644 --- a/DuiLib/Core/UIBase.h +++ b/DuiLib/Core/UIBase.h @@ -40,13 +40,13 @@ namespace DuiLib { #define DUITRACEMSG _T("") #endif -void UILIB_API DUI__Trace(LPCTSTR pstrFormat, ...); -LPCTSTR UILIB_API DUI__TraceMsg(UINT uMsg); +void DUILIB_API DUI__Trace(LPCTSTR pstrFormat, ...); +LPCTSTR DUILIB_API DUI__TraceMsg(UINT uMsg); ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CNotifyPump +class DUILIB_API CNotifyPump { public: bool AddVirtualWnd(CDuiString strName,CNotifyPump* pObject); @@ -55,10 +55,10 @@ class UILIB_API CNotifyPump bool LoopDispatch(TNotifyUI& msg); DUI_DECLARE_MESSAGE_MAP() private: - CStdStringPtrMap m_VirtualWndMap; + CDuiStringPtrMap m_VirtualWndMap; }; -class UILIB_API CWindowWnd +class DUILIB_API CWindowWnd { public: CWindowWnd(); diff --git a/DuiLib/Core/UIContainer.cpp b/DuiLib/Core/UIContainer.cpp index 98954efd..fd88f4fc 100644 --- a/DuiLib/Core/UIContainer.cpp +++ b/DuiLib/Core/UIContainer.cpp @@ -25,18 +25,18 @@ namespace DuiLib { m_bDelayedDestroy = false; RemoveAll(); - if( m_pVerticalScrollBar ) delete m_pVerticalScrollBar; - if( m_pHorizontalScrollBar ) delete m_pHorizontalScrollBar; + if( m_pVerticalScrollBar ) m_pVerticalScrollBar->Delete(); + if( m_pHorizontalScrollBar ) m_pHorizontalScrollBar->Delete(); } LPCTSTR CContainerUI::GetClass() const { - return _T("ContainerUI"); + return DUI_CTR_CONTAINER; } LPVOID CContainerUI::GetInterface(LPCTSTR pstrName) { - if( _tcscmp(pstrName, _T("IContainer")) == 0 ) return static_cast(this); + if( _tcscmp(pstrName, DUI_CTR_ICONTAINER) == 0 ) return static_cast(this); else if( _tcscmp(pstrName, DUI_CTR_CONTAINER) == 0 ) return static_cast(this); return CControlUI::GetInterface(pstrName); } @@ -58,19 +58,40 @@ namespace DuiLib return -1; } - bool CContainerUI::SetItemIndex(CControlUI* pControl, int iIndex) + bool CContainerUI::SetItemIndex(CControlUI* pControl, int iNewIndex) { for( int it = 0; it < m_items.GetSize(); it++ ) { if( static_cast(m_items[it]) == pControl ) { NeedUpdate(); m_items.Remove(it); - return m_items.InsertAt(iIndex, pControl); + return m_items.InsertAt(iNewIndex, pControl); } } return false; } + bool CContainerUI::SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex) + { + if (pStartControl == NULL || iCount < 0 || iNewStartIndex < 0) return false; + int iStartIndex = GetItemIndex(pStartControl); + if (iStartIndex == iNewStartIndex) return true; + if (iStartIndex + iCount > GetCount()) return false; + if (iNewStartIndex + iCount > GetCount()) return false; + + CDuiPtrArray pControls(iCount); + pControls.Resize(iCount); + ::CopyMemory(pControls.GetData(), m_items.GetData() + iStartIndex, iCount * sizeof(LPVOID)); + m_items.Remove(iStartIndex, iCount); + + for( int it3 = 0; it3 < pControls.GetSize(); it3++ ) { + if (!pControls.InsertAt(iNewStartIndex + it3, pControls[it3])) return false; + } + + NeedUpdate(); + return true; + } + int CContainerUI::GetCount() const { return m_items.GetSize(); @@ -90,22 +111,22 @@ namespace DuiLib { if( pControl == NULL) return false; - if( m_pManager != NULL ) m_pManager->InitControls(pControl, this); + if( m_pManager != NULL ) m_pManager->InitControls(pControl, this); if( IsVisible() ) NeedUpdate(); else pControl->SetInternVisible(false); return m_items.InsertAt(iIndex, pControl); } - bool CContainerUI::Remove(CControlUI* pControl) + bool CContainerUI::Remove(CControlUI* pControl, bool bDoNotDestroy) { if( pControl == NULL) return false; for( int it = 0; it < m_items.GetSize(); it++ ) { if( static_cast(m_items[it]) == pControl ) { NeedUpdate(); - if( m_bAutoDestroy ) { + if( !bDoNotDestroy && m_bAutoDestroy ) { if( m_bDelayedDestroy && m_pManager ) m_pManager->AddDelayedCleanup(pControl); - else delete pControl; + else pControl->Delete(); } return m_items.Remove(it); } @@ -113,11 +134,11 @@ namespace DuiLib return false; } - bool CContainerUI::RemoveAt(int iIndex) + bool CContainerUI::RemoveAt(int iIndex, bool bDoNotDestroy) { CControlUI* pControl = GetItemAt(iIndex); if (pControl != NULL) { - return CContainerUI::Remove(pControl); + return CContainerUI::Remove(pControl, bDoNotDestroy); } return false; @@ -127,7 +148,7 @@ namespace DuiLib { for( int it = 0; m_bAutoDestroy && it < m_items.GetSize(); it++ ) { if( m_bDelayedDestroy && m_pManager ) m_pManager->AddDelayedCleanup(static_cast(m_items[it])); - else delete static_cast(m_items[it]); + else static_cast(m_items[it])->Delete(); } m_items.Empty(); NeedUpdate(); @@ -256,53 +277,55 @@ namespace DuiLib return; } if( event.Type == UIEVENT_KEYDOWN ) - { - if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() ) - { - switch( event.chKey ) { - case VK_DOWN: - LineDown(); - return; - case VK_UP: - LineUp(); - return; - case VK_NEXT: - PageDown(); - return; - case VK_PRIOR: - PageUp(); - return; - case VK_HOME: - HomeUp(); - return; - case VK_END: - EndDown(); - return; - } - } - else if (m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled()) - { - switch( event.chKey ) { - case VK_DOWN: - LineRight(); - return; - case VK_UP: - LineLeft(); - return; - case VK_NEXT: - PageRight(); - return; - case VK_PRIOR: - PageLeft(); - return; - case VK_HOME: - HomeLeft(); - return; - case VK_END: - EndRight(); - return; - } - } + { + if (IsKeyboardEnabled() && IsEnabled()) { + if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() ) + { + switch( event.chKey ) { + case VK_DOWN: + LineDown(); + return; + case VK_UP: + LineUp(); + return; + case VK_NEXT: + PageDown(); + return; + case VK_PRIOR: + PageUp(); + return; + case VK_HOME: + HomeUp(); + return; + case VK_END: + EndDown(); + return; + } + } + else if (m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled()) + { + switch( event.chKey ) { + case VK_DOWN: + LineRight(); + return; + case VK_UP: + LineLeft(); + return; + case VK_NEXT: + PageRight(); + return; + case VK_PRIOR: + PageLeft(); + return; + case VK_HOME: + HomeLeft(); + return; + case VK_END: + EndRight(); + return; + } + } + } } else if (event.Type == UIEVENT_SCROLLWHEEL) { @@ -393,8 +416,12 @@ namespace DuiLib void CContainerUI::LineUp() { - int cyLine = 8; - if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8; + int cyLine = SCROLLBAR_LINESIZE; + if( m_pManager ) { + cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8; + if (m_pVerticalScrollBar && m_pVerticalScrollBar->GetScrollUnit() > 1) + cyLine = m_pVerticalScrollBar->GetScrollUnit(); + } SIZE sz = GetScrollPos(); sz.cy -= cyLine; @@ -403,8 +430,12 @@ namespace DuiLib void CContainerUI::LineDown() { - int cyLine = 8; - if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8; + int cyLine = SCROLLBAR_LINESIZE; + if( m_pManager ) { + cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8; + if (m_pVerticalScrollBar && m_pVerticalScrollBar->GetScrollUnit() > 1) + cyLine = m_pVerticalScrollBar->GetScrollUnit(); + } SIZE sz = GetScrollPos(); sz.cy += cyLine; @@ -445,15 +476,23 @@ namespace DuiLib void CContainerUI::LineLeft() { + int cxLine = SCROLLBAR_LINESIZE; + if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->GetScrollUnit() > 1) + cxLine = m_pHorizontalScrollBar->GetScrollUnit(); + SIZE sz = GetScrollPos(); - sz.cx -= 8; + sz.cx -= cxLine; SetScrollPos(sz); } void CContainerUI::LineRight() { + int cxLine = SCROLLBAR_LINESIZE; + if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->GetScrollUnit() > 1) + cxLine = m_pHorizontalScrollBar->GetScrollUnit(); + SIZE sz = GetScrollPos(); - sz.cx += 8; + sz.cx += cxLine; SetScrollPos(sz); } @@ -499,12 +538,12 @@ namespace DuiLib if ( m_pManager ) { LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("VScrollBar")); if( pDefaultAttributes ) { - m_pVerticalScrollBar->ApplyAttributeList(pDefaultAttributes); + m_pVerticalScrollBar->SetAttributeList(pDefaultAttributes); } } } else if( !bEnableVertical && m_pVerticalScrollBar ) { - delete m_pVerticalScrollBar; + m_pVerticalScrollBar->Delete(); m_pVerticalScrollBar = NULL; } @@ -517,12 +556,12 @@ namespace DuiLib if ( m_pManager ) { LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("HScrollBar")); if( pDefaultAttributes ) { - m_pHorizontalScrollBar->ApplyAttributeList(pDefaultAttributes); + m_pHorizontalScrollBar->SetAttributeList(pDefaultAttributes); } } } else if( !bEnableHorizontal && m_pHorizontalScrollBar ) { - delete m_pHorizontalScrollBar; + m_pHorizontalScrollBar->Delete(); m_pHorizontalScrollBar = NULL; } @@ -547,7 +586,7 @@ namespace DuiLib iIndex = CLAMP(iIndex, 0, GetCount() - 1); if( bForward ) { for( int i = iIndex; i < GetCount(); i++ ) { - if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL + if( GetItemAt(i)->GetInterface(DUI_CTR_ILISTITEM) != NULL && GetItemAt(i)->IsVisible() && GetItemAt(i)->IsEnabled() ) return i; } @@ -555,7 +594,7 @@ namespace DuiLib } else { for( int i = iIndex; i >= 0; --i ) { - if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL + if( GetItemAt(i)->GetInterface(DUI_CTR_ILISTITEM) != NULL && GetItemAt(i)->IsVisible() && GetItemAt(i)->IsEnabled() ) return i; } @@ -572,15 +611,9 @@ namespace DuiLib rc.bottom -= m_rcInset.bottom; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { - rc.top -= m_pVerticalScrollBar->GetScrollPos(); - rc.bottom -= m_pVerticalScrollBar->GetScrollPos(); - rc.bottom += m_pVerticalScrollBar->GetScrollRange(); rc.right -= m_pVerticalScrollBar->GetFixedWidth(); } if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) { - rc.left -= m_pHorizontalScrollBar->GetScrollPos(); - rc.right -= m_pHorizontalScrollBar->GetScrollPos(); - rc.right += m_pHorizontalScrollBar->GetScrollRange(); rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); } return rc; @@ -656,14 +689,14 @@ namespace DuiLib } else if( _tcscmp(pstrName, _T("vscrollbarstyle")) == 0 ) { EnableScrollBar(true, GetHorizontalScrollBar() != NULL); - if( GetVerticalScrollBar() ) GetVerticalScrollBar()->ApplyAttributeList(pstrValue); + if( GetVerticalScrollBar() ) GetVerticalScrollBar()->SetAttributeList(pstrValue); } else if( _tcscmp(pstrName, _T("hscrollbar")) == 0 ) { EnableScrollBar(GetVerticalScrollBar() != NULL, _tcscmp(pstrValue, _T("true")) == 0); } else if( _tcscmp(pstrName, _T("hscrollbarstyle")) == 0 ) { EnableScrollBar(GetVerticalScrollBar() != NULL, true); - if( GetHorizontalScrollBar() ) GetHorizontalScrollBar()->ApplyAttributeList(pstrValue); + if( GetHorizontalScrollBar() ) GetHorizontalScrollBar()->SetAttributeList(pstrValue); } else if( _tcscmp(pstrName, _T("childpadding")) == 0 ) SetChildPadding(_ttoi(pstrValue)); else if( _tcscmp(pstrName, _T("childalign")) == 0 ) { @@ -702,6 +735,9 @@ namespace DuiLib if( (uFlags & UIFIND_ME_FIRST) != 0 ) { if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData); } + if( pResult == NULL && m_pCover != NULL ) { + if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseChildEnabled() ) pResult = m_pCover->FindControl(Proc, pData, uFlags); + } if( pResult == NULL && m_pVerticalScrollBar != NULL ) { if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = m_pVerticalScrollBar->FindControl(Proc, pData, uFlags); } @@ -749,10 +785,10 @@ namespace DuiLib return pResult; } - void CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) + bool CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { RECT rcTemp = { 0 }; - if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return; + if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true; CRenderClip clip; CRenderClip::GenerateClip(hDC, rcTemp, clip); @@ -770,12 +806,12 @@ namespace DuiLib if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) { for( int it = 0; it < m_items.GetSize(); it++ ) { CControlUI* pControl = static_cast(m_items[it]); - if( pControl == pStopControl ) break; + if( pControl == pStopControl ) return false; if( !pControl->IsVisible() ) continue; if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; if( pControl->IsFloat() ) { if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; } } } @@ -784,34 +820,41 @@ namespace DuiLib CRenderClip::GenerateClip(hDC, rcTemp, childClip); for( int it = 0; it < m_items.GetSize(); it++ ) { CControlUI* pControl = static_cast(m_items[it]); - if( pControl == pStopControl ) break; + if( pControl == pStopControl ) return false; if( !pControl->IsVisible() ) continue; if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; if( pControl->IsFloat() ) { if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; CRenderClip::UseOldClipBegin(hDC, childClip); - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; CRenderClip::UseOldClipEnd(hDC, childClip); } else { if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue; - pControl->Paint(hDC, rcPaint, pStopControl); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; } } } } - if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() ) { - if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { - m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl); - } + if( m_pVerticalScrollBar != NULL ) { + if( m_pVerticalScrollBar == pStopControl ) return false; + if (m_pVerticalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { + if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } } - if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) { - if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { - m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl); - } + if( m_pHorizontalScrollBar != NULL ) { + if( m_pHorizontalScrollBar == pStopControl ) return false; + if (m_pHorizontalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { + if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } } + return true; } void CContainerUI::SetFloatPos(int iIndex) diff --git a/DuiLib/Core/UIContainer.h b/DuiLib/Core/UIContainer.h index bfc76e48..a7bade67 100644 --- a/DuiLib/Core/UIContainer.h +++ b/DuiLib/Core/UIContainer.h @@ -12,12 +12,13 @@ class IContainerUI public: virtual CControlUI* GetItemAt(int iIndex) const = 0; virtual int GetItemIndex(CControlUI* pControl) const = 0; - virtual bool SetItemIndex(CControlUI* pControl, int iIndex) = 0; + virtual bool SetItemIndex(CControlUI* pControl, int iNewIndex) = 0; + virtual bool SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex) = 0; virtual int GetCount() const = 0; virtual bool Add(CControlUI* pControl) = 0; virtual bool AddAt(CControlUI* pControl, int iIndex) = 0; - virtual bool Remove(CControlUI* pControl) = 0; - virtual bool RemoveAt(int iIndex) = 0; + virtual bool Remove(CControlUI* pControl, bool bDoNotDestroy=false) = 0; + virtual bool RemoveAt(int iIndex, bool bDoNotDestroy=false) = 0; virtual void RemoveAll() = 0; }; @@ -26,7 +27,7 @@ class IContainerUI // class CScrollBarUI; -class UILIB_API CContainerUI : public CControlUI, public IContainerUI +class DUILIB_API CContainerUI : public CControlUI, public IContainerUI { public: CContainerUI(); @@ -38,12 +39,13 @@ class UILIB_API CContainerUI : public CControlUI, public IContainerUI CControlUI* GetItemAt(int iIndex) const; int GetItemIndex(CControlUI* pControl) const; - bool SetItemIndex(CControlUI* pControl, int iIndex); + bool SetItemIndex(CControlUI* pControl, int iNewIndex); + bool SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex); int GetCount() const; bool Add(CControlUI* pControl); bool AddAt(CControlUI* pControl, int iIndex); - bool Remove(CControlUI* pControl); - bool RemoveAt(int iIndex); + bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); + bool RemoveAt(int iIndex, bool bDoNotDestroy=false); void RemoveAll(); void DoEvent(TEventUI& event); @@ -71,7 +73,7 @@ class UILIB_API CContainerUI : public CControlUI, public IContainerUI RECT GetClientPos() const; void SetPos(RECT rc, bool bNeedInvalidate = true); void Move(SIZE szOffset, bool bNeedInvalidate = true); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); @@ -113,7 +115,7 @@ class UILIB_API CContainerUI : public CControlUI, public IContainerUI virtual void ProcessScrollBar(RECT rc, int cxRequired, int cyRequired); protected: - CStdPtrArray m_items; + CDuiPtrArray m_items; RECT m_rcInset; int m_iChildPadding; UINT m_iChildAlign; diff --git a/DuiLib/Core/UIControl.cpp b/DuiLib/Core/UIControl.cpp index 3ac86f14..af38cedd 100644 --- a/DuiLib/Core/UIControl.cpp +++ b/DuiLib/Core/UIControl.cpp @@ -1,10 +1,11 @@ -#include "StdAfx.h" +锘#include "StdAfx.h" namespace DuiLib { CControlUI::CControlUI() : m_pManager(NULL), m_pParent(NULL), +m_pCover(NULL), m_bUpdateNeeded(true), m_bMenuUsed(false), m_bAsyncNotify(false), @@ -42,11 +43,21 @@ m_nTooltipWidth(300) CControlUI::~CControlUI() { + if( m_pCover != NULL ) { + m_pCover->Delete(); + m_pCover = NULL; + } + RemoveAllCustomAttribute(); if( OnDestroy ) OnDestroy(this); if( m_pManager != NULL ) m_pManager->ReapObjects(this); } +void CControlUI::Delete() +{ + delete this; +} + CDuiString CControlUI::GetName() const { return m_sName; @@ -68,7 +79,7 @@ LPVOID CControlUI::GetInterface(LPCTSTR pstrName) LPCTSTR CControlUI::GetClass() const { - return _T("ControlUI"); + return DUI_CTR_CONTROL; } UINT CControlUI::GetControlFlags() const @@ -95,6 +106,7 @@ CPaintManagerUI* CControlUI::GetManager() const void CControlUI::SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit) { + if( m_pCover != NULL ) m_pCover->SetManager(pManager, this, bInit); m_pManager = pManager; m_pParent = pParent; if( bInit && m_pParent ) Init(); @@ -105,6 +117,23 @@ CControlUI* CControlUI::GetParent() const return m_pParent; } +CControlUI* CControlUI::GetCover() const +{ + return m_pCover; +} + +void CControlUI::SetCover(CControlUI *pControl) +{ + if( m_pCover == pControl ) return; + if( m_pCover != NULL ) m_pCover->Delete(); + m_pCover = pControl; + if( m_pCover != NULL ) { + m_pManager->InitControls(m_pCover, this); + if( IsVisible() ) NeedUpdate(); + else pControl->SetInternVisible(false); + } +} + CDuiString CControlUI::GetText() const { return m_sText; @@ -323,6 +352,31 @@ void CControlUI::SetPos(RECT rc, bool bNeedInvalidate) } m_pManager->Invalidate(invalidateRc); } + + if( m_pCover != NULL && m_pCover->IsVisible() ) { + if( m_pCover->IsFloat() ) { + SIZE szXY = m_pCover->GetFixedXY(); + SIZE sz = {m_pCover->GetFixedWidth(), m_pCover->GetFixedHeight()}; + TPercentInfo rcPercent = m_pCover->GetFloatPercent(); + LONG width = m_rcItem.right - m_rcItem.left; + LONG height = m_rcItem.bottom - m_rcItem.top; + RECT rcCtrl = { 0 }; + rcCtrl.left = (LONG)(width*rcPercent.left) + szXY.cx; + rcCtrl.top = (LONG)(height*rcPercent.top) + szXY.cy; + rcCtrl.right = (LONG)(width*rcPercent.right) + szXY.cx + sz.cx; + rcCtrl.bottom = (LONG)(height*rcPercent.bottom) + szXY.cy + sz.cy; + m_pCover->SetPos(rcCtrl, false); + } + else { + SIZE sz = { rc.right - rc.left, rc.bottom - rc.top }; + if( sz.cx < m_pCover->GetMinWidth() ) sz.cx = m_pCover->GetMinWidth(); + if( sz.cx > m_pCover->GetMaxWidth() ) sz.cx = m_pCover->GetMaxWidth(); + if( sz.cy < m_pCover->GetMinHeight() ) sz.cy = m_pCover->GetMinHeight(); + if( sz.cy > m_pCover->GetMaxHeight() ) sz.cy = m_pCover->GetMaxHeight(); + RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy }; + m_pCover->SetPos(rcCtrl, false); + } + } } void CControlUI::Move(SIZE szOffset, bool bNeedInvalidate) @@ -346,6 +400,8 @@ void CControlUI::Move(SIZE szOffset, bool bNeedInvalidate) } m_pManager->Invalidate(invalidateRc); } + + if( m_pCover != NULL && m_pCover->IsVisible() ) m_pCover->Move(szOffset, false); } int CControlUI::GetWidth() const @@ -564,6 +620,8 @@ void CControlUI::SetVisible(bool bVisible) if( IsVisible() != v ) { NeedParentUpdate(); } + + if( m_pCover != NULL ) m_pCover->SetInternVisible(IsVisible()); } void CControlUI::SetInternVisible(bool bVisible) @@ -572,6 +630,8 @@ void CControlUI::SetInternVisible(bool bVisible) if (!bVisible && m_pManager && m_pManager->GetFocus() == this) { m_pManager->SetFocus(NULL) ; } + + if( m_pCover != NULL ) m_pCover->SetInternVisible(IsVisible()); } bool CControlUI::IsEnabled() const @@ -675,9 +735,20 @@ CControlUI* CControlUI::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFl { if( (uFlags & UIFIND_VISIBLE) != 0 && !IsVisible() ) return NULL; if( (uFlags & UIFIND_ENABLED) != 0 && !IsEnabled() ) return NULL; - if( (uFlags & UIFIND_HITTEST) != 0 && (!m_bMouseEnabled || !::PtInRect(&m_rcItem, * static_cast(pData))) ) return NULL; + if( (uFlags & UIFIND_HITTEST) != 0 && (!::PtInRect(&m_rcItem, * static_cast(pData))) ) return NULL; if( (uFlags & UIFIND_UPDATETEST) != 0 && Proc(this, pData) != NULL ) return NULL; - return Proc(this, pData); + + CControlUI* pResult = NULL; + if( (uFlags & UIFIND_ME_FIRST) != 0 ) { + if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData); + } + if( pResult == NULL && m_pCover != NULL ) { + /*if( (uFlags & UIFIND_HITTEST) == 0 || true)*/ pResult = m_pCover->FindControl(Proc, pData, uFlags); + } + if( pResult == NULL && (uFlags & UIFIND_ME_FIRST) == 0 ) { + if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData); + } + return pResult; } void CControlUI::Invalidate() @@ -812,6 +883,11 @@ CDuiString CControlUI::GetVirtualWnd() const return str; } +CDuiString CControlUI::GetAttribute(LPCTSTR pstrName) +{ + return _T(""); +} + void CControlUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if( _tcscmp(pstrName, _T("pos")) == 0 ) { @@ -936,7 +1012,12 @@ void CControlUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) } } -CControlUI* CControlUI::ApplyAttributeList(LPCTSTR pstrList) +CDuiString CControlUI::GetAttributeList(bool bIgnoreDefault) +{ + return _T(""); +} + +void CControlUI::SetAttributeList(LPCTSTR pstrList) { CDuiString sItem; CDuiString sValue; @@ -950,9 +1031,9 @@ CControlUI* CControlUI::ApplyAttributeList(LPCTSTR pstrList) } } ASSERT( *pstrList == _T('=') ); - if( *pstrList++ != _T('=') ) return this; + if( *pstrList++ != _T('=') ) return; ASSERT( *pstrList == _T('\"') ); - if( *pstrList++ != _T('\"') ) return this; + if( *pstrList++ != _T('\"') ) return; while( *pstrList != _T('\0') && *pstrList != _T('\"') ) { LPTSTR pstrTemp = ::CharNext(pstrList); while( pstrList < pstrTemp) { @@ -960,16 +1041,10 @@ CControlUI* CControlUI::ApplyAttributeList(LPCTSTR pstrList) } } ASSERT( *pstrList == _T('\"') ); - if( *pstrList++ != _T('\"') ) return this; + if( *pstrList++ != _T('\"') ) return; SetAttribute(sItem, sValue); - if( *pstrList++ != _T(' ') ) return this; + if( *pstrList++ != _T(' ') ) return; } - return this; -} - -CDuiString CControlUI::GetAttributeList() -{ - return _T(""); } SIZE CControlUI::EstimateSize(SIZE szAvailable) @@ -977,17 +1052,19 @@ SIZE CControlUI::EstimateSize(SIZE szAvailable) return m_cxyFixed; } -void CControlUI::Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CControlUI::Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { - if (pStopControl == this) return; - if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return; + if (pStopControl == this) return false; + if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return true; if( OnPaint ) { - if( !OnPaint(this) ) return; + if( !OnPaint(this) ) return true; } - DoPaint(hDC, rcPaint, pStopControl); + if (!DoPaint(hDC, rcPaint, pStopControl)) return false; + if( m_pCover != NULL ) return m_pCover->Paint(hDC, rcPaint); + return true; } -void CControlUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CControlUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { // 缁樺埗寰簭锛氳儗鏅鑹->鑳屾櫙鍥->鐘舵佸浘->鏂囨湰->杈规 if( m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0 ) { @@ -1006,6 +1083,7 @@ void CControlUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) PaintText(hDC); PaintBorder(hDC); } + return true; } void CControlUI::PaintBkColor(HDC hDC) @@ -1064,7 +1142,8 @@ void CControlUI::PaintBorder(HDC hDC) RECT rcBorder; if(m_rcBorderSize.left > 0){ rcBorder = m_rcItem; - rcBorder.right = m_rcItem.left; + rcBorder.left += m_rcBorderSize.left / 2; + rcBorder.right = rcBorder.left; if (IsFocused() && m_dwFocusBorderColor != 0) CRenderEngine::DrawLine(hDC,rcBorder,m_rcBorderSize.left,GetAdjustColor(m_dwFocusBorderColor),m_nBorderStyle); else @@ -1072,7 +1151,10 @@ void CControlUI::PaintBorder(HDC hDC) } if(m_rcBorderSize.top > 0) { rcBorder = m_rcItem; - rcBorder.bottom = m_rcItem.top; + rcBorder.top += m_rcBorderSize.top / 2; + rcBorder.bottom = rcBorder.top; + rcBorder.left += m_rcBorderSize.left; + rcBorder.right -= m_rcBorderSize.right; if (IsFocused() && m_dwFocusBorderColor != 0) CRenderEngine::DrawLine(hDC,rcBorder,m_rcBorderSize.top,GetAdjustColor(m_dwFocusBorderColor),m_nBorderStyle); else @@ -1080,7 +1162,8 @@ void CControlUI::PaintBorder(HDC hDC) } if(m_rcBorderSize.right > 0) { rcBorder = m_rcItem; - rcBorder.left = m_rcItem.right; + rcBorder.left = m_rcItem.right - m_rcBorderSize.right / 2; + rcBorder.right = rcBorder.left; if (IsFocused() && m_dwFocusBorderColor != 0) CRenderEngine::DrawLine(hDC,rcBorder,m_rcBorderSize.right,GetAdjustColor(m_dwFocusBorderColor),m_nBorderStyle); else @@ -1088,7 +1171,10 @@ void CControlUI::PaintBorder(HDC hDC) } if(m_rcBorderSize.bottom > 0) { rcBorder = m_rcItem; - rcBorder.top = m_rcItem.bottom; + rcBorder.top = m_rcItem.bottom - m_rcBorderSize.bottom / 2; + rcBorder.bottom = rcBorder.top; + rcBorder.left += m_rcBorderSize.left; + rcBorder.right -= m_rcBorderSize.right; if (IsFocused() && m_dwFocusBorderColor != 0) CRenderEngine::DrawLine(hDC,rcBorder,m_rcBorderSize.bottom,GetAdjustColor(m_dwFocusBorderColor),m_nBorderStyle); else diff --git a/DuiLib/Core/UIControl.h b/DuiLib/Core/UIControl.h index 110b37ed..bef36a0a 100644 --- a/DuiLib/Core/UIControl.h +++ b/DuiLib/Core/UIControl.h @@ -10,10 +10,13 @@ namespace DuiLib { typedef CControlUI* (CALLBACK* FINDCONTROLPROC)(CControlUI*, LPVOID); -class UILIB_API CControlUI +class DUILIB_API CControlUI { public: CControlUI(); + virtual void Delete(); + +protected: virtual ~CControlUI(); public: @@ -28,6 +31,8 @@ class UILIB_API CControlUI virtual CPaintManagerUI* GetManager() const; virtual void SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit = true); virtual CControlUI* GetParent() const; + virtual CControlUI* GetCover() const; + virtual void SetCover(CControlUI *pControl); // 文本相关 virtual CDuiString GetText() const; @@ -144,14 +149,15 @@ class UILIB_API CControlUI virtual void Event(TEventUI& event); virtual void DoEvent(TEventUI& event); + virtual CDuiString GetAttribute(LPCTSTR pstrName); virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); - CControlUI* ApplyAttributeList(LPCTSTR pstrList); - CDuiString GetAttributeList(); + virtual CDuiString GetAttributeList(bool bIgnoreDefault = true); + virtual void SetAttributeList(LPCTSTR pstrList); virtual SIZE EstimateSize(SIZE szAvailable); - virtual void Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl=NULL); - virtual void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + virtual bool Paint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl=NULL); // 返回要不要继续绘制 + virtual bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); virtual void PaintBkColor(HDC hDC); virtual void PaintBkImage(HDC hDC); virtual void PaintStatusImage(HDC hDC); @@ -176,6 +182,7 @@ class UILIB_API CControlUI protected: CPaintManagerUI* m_pManager; CControlUI* m_pParent; + CControlUI* m_pCover; CDuiString m_sVirtualWnd; CDuiString m_sName; bool m_bUpdateNeeded; @@ -216,7 +223,7 @@ class UILIB_API CControlUI SIZE m_cxyBorderRound; RECT m_rcPaint; RECT m_rcBorderSize; - CStdStringPtrMap m_mCustomAttrHash; + CDuiStringPtrMap m_mCustomAttrHash; }; } // namespace DuiLib diff --git a/DuiLib/Core/UIDefine.h b/DuiLib/Core/UIDefine.h index 0b1a854a..59178756 100644 --- a/DuiLib/Core/UIDefine.h +++ b/DuiLib/Core/UIDefine.h @@ -9,6 +9,8 @@ namespace DuiLib #define MAX_FONT_ID 30000 #define LAYEREDUPDATE_TIMERID 0x2000 +#define SCROLLBAR_LINESIZE 8 + enum DuiSig { DuiSig_end = 0, // [marks end of message map] @@ -61,6 +63,7 @@ union DuiMessageMapFunctions #define DUI_MSGTYPE_ITEMSELECT (_T("itemselect")) #define DUI_MSGTYPE_ITEMEXPAND (_T("itemexpand")) + #define DUI_MSGTYPE_WINDOWINIT (_T("windowinit")) #define DUI_MSGTYPE_BUTTONDOWN (_T("buttondown")) #define DUI_MSGTYPE_MOUSEENTER (_T("mouseenter")) @@ -224,12 +227,14 @@ protected: \ #define DUI_CTR_EDIT (_T("Edit")) #define DUI_CTR_LIST (_T("List")) #define DUI_CTR_TEXT (_T("Text")) +#define DUI_CTR_TREE (_T("Tree")) #define DUI_CTR_HBOX (_T("HBox")) #define DUI_CTR_VBOX (_T("VBox")) +#define DUI_CTR_ILIST (_T("IList")) #define DUI_CTR_COMBO (_T("Combo")) #define DUI_CTR_LABEL (_T("Label")) -#define DUI_CTR_FLASH (_T("Flash")) +#define DUI_CTR_FLASH (_T("Flash")) #define DUI_CTR_BUTTON (_T("Button")) #define DUI_CTR_OPTION (_T("Option")) @@ -239,7 +244,6 @@ protected: \ #define DUI_CTR_ACTIVEX (_T("ActiveX")) #define DUI_CTR_GIFANIM (_T("GifAnim")) -#define DUI_CTR_LISTITEM (_T("ListItem")) #define DUI_CTR_PROGRESS (_T("Progress")) #define DUI_CTR_RICHEDIT (_T("RichEdit")) #define DUI_CTR_CHECKBOX (_T("CheckBox")) @@ -248,20 +252,25 @@ protected: \ #define DUI_CTR_TREEVIEW (_T("TreeView")) #define DUI_CTR_TREENODE (_T("TreeNode")) +#define DUI_CTR_ILISTITEM (_T("IListItem")) #define DUI_CTR_CONTAINER (_T("Container")) #define DUI_CTR_TABLAYOUT (_T("TabLayout")) #define DUI_CTR_SCROLLBAR (_T("ScrollBar")) +#define DUI_CTR_ICONTAINER (_T("IContainer")) +#define DUI_CTR_ILISTOWNER (_T("IListOwner")) #define DUI_CTR_LISTHEADER (_T("ListHeader")) #define DUI_CTR_TILELAYOUT (_T("TileLayout")) #define DUI_CTR_WEBBROWSER (_T("WebBrowser")) #define DUI_CTR_CHILDLAYOUT (_T("ChildLayout")) #define DUI_CTR_LISTELEMENT (_T("ListElement")) +#define DUI_CTR_VIRTUALLIST (_T("VirtualList")) #define DUI_CTR_VERTICALLAYOUT (_T("VerticalLayout")) #define DUI_CTR_LISTHEADERITEM (_T("ListHeaderItem")) +#define DUI_CTR_LISTHBOXELEMENT (_T("ListHBoxElement")) #define DUI_CTR_LISTTEXTELEMENT (_T("ListTextElement")) #define DUI_CTR_HORIZONTALLAYOUT (_T("HorizontalLayout")) @@ -269,6 +278,7 @@ protected: \ #define DUI_CTR_LISTCONTAINERELEMENT (_T("ListContainerElement")) + /// //////////////END控件名称宏定义////////////////////////////////////////////////// diff --git a/DuiLib/Core/UIDlgBuilder.cpp b/DuiLib/Core/UIDlgBuilder.cpp index 63c661c9..870af20c 100644 --- a/DuiLib/Core/UIDlgBuilder.cpp +++ b/DuiLib/Core/UIDlgBuilder.cpp @@ -170,93 +170,7 @@ CControlUI* CDialogBuilder::Create(IDialogBuilderCallback* pCallback, CPaintMana for( int i = 0; i < nAttributes; i++ ) { pstrName = root.GetAttributeName(i); pstrValue = root.GetAttributeValue(i); - if( _tcsicmp(pstrName, _T("size")) == 0 ) { - LPTSTR pstr = NULL; - int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetInitSize(cx, cy); - } - else if( _tcsicmp(pstrName, _T("sizebox")) == 0 ) { - RECT rcSizeBox = { 0 }; - LPTSTR pstr = NULL; - rcSizeBox.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - rcSizeBox.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - rcSizeBox.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - rcSizeBox.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetSizeBox(rcSizeBox); - } - else if( _tcsicmp(pstrName, _T("caption")) == 0 ) { - RECT rcCaption = { 0 }; - LPTSTR pstr = NULL; - rcCaption.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - rcCaption.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - rcCaption.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - rcCaption.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetCaptionRect(rcCaption); - } - else if( _tcsicmp(pstrName, _T("roundcorner")) == 0 ) { - LPTSTR pstr = NULL; - int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetRoundCorner(cx, cy); - } - else if( _tcsicmp(pstrName, _T("mininfo")) == 0 ) { - LPTSTR pstr = NULL; - int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetMinInfo(cx, cy); - } - else if( _tcsicmp(pstrName, _T("maxinfo")) == 0 ) { - LPTSTR pstr = NULL; - int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); - int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); - pManager->SetMaxInfo(cx, cy); - } - else if( _tcsicmp(pstrName, _T("showdirty")) == 0 ) { - pManager->SetShowUpdateRect(_tcsicmp(pstrValue, _T("true")) == 0); - } - else if( _tcsicmp(pstrName, _T("opacity")) == 0 ) { - pManager->SetOpacity(_ttoi(pstrValue)); - } - else if( _tcscmp(pstrName, _T("layeredopacity")) == 0 ) { - pManager->SetLayeredOpacity(_ttoi(pstrValue)); - } - else if( _tcscmp(pstrName, _T("layeredimage")) == 0 ) { - pManager->SetLayered(true); - pManager->SetLayeredImage(pstrValue); - } - else if( _tcsicmp(pstrName, _T("disabledfontcolor")) == 0 ) { - if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); - LPTSTR pstr = NULL; - DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - pManager->SetDefaultDisabledColor(clrColor); - } - else if( _tcsicmp(pstrName, _T("defaultfontcolor")) == 0 ) { - if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); - LPTSTR pstr = NULL; - DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - pManager->SetDefaultFontColor(clrColor); - } - else if( _tcsicmp(pstrName, _T("linkfontcolor")) == 0 ) { - if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); - LPTSTR pstr = NULL; - DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - pManager->SetDefaultLinkFontColor(clrColor); - } - else if( _tcsicmp(pstrName, _T("linkhoverfontcolor")) == 0 ) { - if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); - LPTSTR pstr = NULL; - DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - pManager->SetDefaultLinkHoverFontColor(clrColor); - } - else if( _tcsicmp(pstrName, _T("selectedcolor")) == 0 ) { - if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); - LPTSTR pstr = NULL; - DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); - pManager->SetDefaultSelectedBkColor(clrColor); - } - else - pManager->AddWindowCustomAttribute(pstrName, pstrValue); + pManager->SetWindowAttribute(pstrName, pstrValue); } } } @@ -328,7 +242,7 @@ CControlUI* CDialogBuilder::_Parse(CMarkupNode* pRoot, CControlUI* pParent, CPai pNode->SetManager(pManager, NULL, false); LPCTSTR pDefaultAttributes = pManager->GetDefaultAttributeList(pstrClass); if( pDefaultAttributes ) { - pNode->ApplyAttributeList(pDefaultAttributes); + pNode->SetAttributeList(pDefaultAttributes); } } @@ -373,65 +287,69 @@ CControlUI* CDialogBuilder::_Parse(CMarkupNode* pRoot, CControlUI* pParent, CPai SIZE_T cchLen = _tcslen(pstrClass); switch( cchLen ) { case 4: - if( _tcsicmp(pstrClass, DUI_CTR_EDIT) == 0 ) pControl = new CEditUI; - else if( _tcsicmp(pstrClass, DUI_CTR_LIST) == 0 ) pControl = new CListUI; - else if( _tcsicmp(pstrClass, DUI_CTR_TEXT) == 0 ) pControl = new CTextUI; - else if( _tcsicmp(pstrClass, DUI_CTR_HBOX) == 0 ) pControl = new CHorizontalLayoutUI; - else if( _tcsicmp(pstrClass, DUI_CTR_VBOX) == 0 ) pControl = new CVerticalLayoutUI; + if( _tcsicmp(pstrClass, DUI_CTR_EDIT) == 0 ) pControl = new CEditUI; + else if( _tcsicmp(pstrClass, DUI_CTR_LIST) == 0 ) pControl = new CListUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TEXT) == 0 ) pControl = new CTextUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TREE) == 0 ) pControl = new CTreeViewUI; + else if( _tcsicmp(pstrClass, DUI_CTR_HBOX) == 0 ) pControl = new CHorizontalLayoutUI; + else if( _tcsicmp(pstrClass, DUI_CTR_VBOX) == 0 ) pControl = new CVerticalLayoutUI; break; case 5: - if( _tcsicmp(pstrClass, DUI_CTR_COMBO) == 0 ) pControl = new CComboUI; - else if( _tcsicmp(pstrClass, DUI_CTR_LABEL) == 0 ) pControl = new CLabelUI; - //else if( _tcsicmp(pstrClass, DUI_CTR_FLASH) == 0 ) pControl = new CFlashUI; + if( _tcsicmp(pstrClass, DUI_CTR_COMBO) == 0 ) pControl = new CComboUI; + else if( _tcsicmp(pstrClass, DUI_CTR_LABEL) == 0 ) pControl = new CLabelUI; + //else if( _tcsicmp(pstrClass, DUI_CTR_FLASH) == 0 ) pControl = new CFlashUI; break; case 6: - if( _tcsicmp(pstrClass, DUI_CTR_BUTTON) == 0 ) pControl = new CButtonUI; - else if( _tcsicmp(pstrClass, DUI_CTR_OPTION) == 0 ) pControl = new COptionUI; - else if( _tcsicmp(pstrClass, DUI_CTR_SLIDER) == 0 ) pControl = new CSliderUI; + if( _tcsicmp(pstrClass, DUI_CTR_BUTTON) == 0 ) pControl = new CButtonUI; + else if( _tcsicmp(pstrClass, DUI_CTR_OPTION) == 0 ) pControl = new COptionUI; + else if( _tcsicmp(pstrClass, DUI_CTR_SLIDER) == 0 ) pControl = new CSliderUI; break; case 7: - if( _tcsicmp(pstrClass, DUI_CTR_CONTROL) == 0 ) pControl = new CControlUI; - else if( _tcsicmp(pstrClass, DUI_CTR_ACTIVEX) == 0 ) pControl = new CActiveXUI; - else if (_tcscmp(pstrClass, DUI_CTR_GIFANIM) == 0) pControl = new CGifAnimUI; + if( _tcsicmp(pstrClass, DUI_CTR_CONTROL) == 0 ) pControl = new CControlUI; + else if( _tcsicmp(pstrClass, DUI_CTR_ACTIVEX) == 0 ) pControl = new CActiveXUI; + else if (_tcscmp(pstrClass, DUI_CTR_GIFANIM) == 0) pControl = new CGifAnimUI; break; case 8: - if( _tcsicmp(pstrClass, DUI_CTR_PROGRESS) == 0 ) pControl = new CProgressUI; - else if( _tcsicmp(pstrClass, DUI_CTR_RICHEDIT) == 0 ) pControl = new CRichEditUI; + if( _tcsicmp(pstrClass, DUI_CTR_PROGRESS) == 0 ) pControl = new CProgressUI; + else if( _tcsicmp(pstrClass, DUI_CTR_RICHEDIT) == 0 ) pControl = new CRichEditUI; else if( _tcsicmp(pstrClass, DUI_CTR_CHECKBOX) == 0 ) pControl = new CCheckBoxUI; + else if( _tcsicmp(pstrClass, DUI_CTR_COMBOBOX) == 0 ) pControl = new CComboUI; else if( _tcsicmp(pstrClass, DUI_CTR_DATETIME) == 0 ) pControl = new CDateTimeUI; - else if( _tcsicmp(pstrClass, DUI_CTR_TREEVIEW) == 0 ) pControl = new CTreeViewUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TREEVIEW) == 0 ) pControl = new CTreeViewUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TREENODE) == 0 ) pControl = new CTreeNodeUI; break; case 9: - if( _tcsicmp(pstrClass, DUI_CTR_CONTAINER) == 0 ) pControl = new CContainerUI; - else if( _tcsicmp(pstrClass, DUI_CTR_TABLAYOUT) == 0 ) pControl = new CTabLayoutUI; - else if( _tcsicmp(pstrClass, DUI_CTR_SCROLLBAR) == 0 ) pControl = new CScrollBarUI; + if( _tcsicmp(pstrClass, DUI_CTR_CONTAINER) == 0 ) pControl = new CContainerUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TABLAYOUT) == 0 ) pControl = new CTabLayoutUI; + else if( _tcsicmp(pstrClass, DUI_CTR_SCROLLBAR) == 0 ) pControl = new CScrollBarUI; break; case 10: - if( _tcsicmp(pstrClass, DUI_CTR_LISTHEADER) == 0 ) pControl = new CListHeaderUI; - else if( _tcsicmp(pstrClass, DUI_CTR_TILELAYOUT) == 0 ) pControl = new CTileLayoutUI; - else if( _tcsicmp(pstrClass, DUI_CTR_WEBBROWSER) == 0 ) pControl = new CWebBrowserUI; + if( _tcsicmp(pstrClass, DUI_CTR_LISTHEADER) == 0 ) pControl = new CListHeaderUI; + else if( _tcsicmp(pstrClass, DUI_CTR_TILELAYOUT) == 0 ) pControl = new CTileLayoutUI; + else if( _tcsicmp(pstrClass, DUI_CTR_WEBBROWSER) == 0 ) pControl = new CWebBrowserUI; break; case 11: if (_tcsicmp(pstrClass, DUI_CTR_CHILDLAYOUT) == 0) pControl = new CChildLayoutUI; break; case 14: - if( _tcsicmp(pstrClass, DUI_CTR_VERTICALLAYOUT) == 0 ) pControl = new CVerticalLayoutUI; - else if( _tcsicmp(pstrClass, DUI_CTR_LISTHEADERITEM) == 0 ) pControl = new CListHeaderItemUI; + if( _tcsicmp(pstrClass, DUI_CTR_VERTICALLAYOUT) == 0 ) pControl = new CVerticalLayoutUI; + else if( _tcsicmp(pstrClass, DUI_CTR_LISTHEADERITEM) == 0 ) pControl = new CListHeaderItemUI; break; case 15: - if( _tcsicmp(pstrClass, DUI_CTR_LISTTEXTELEMENT) == 0 ) pControl = new CListTextElementUI; + if( _tcsicmp(pstrClass, DUI_CTR_LISTTEXTELEMENT) == 0 ) pControl = new CListTextElementUI; + else if( _tcsicmp(pstrClass, DUI_CTR_LISTHBOXELEMENT) == 0 ) pControl = new CListHBoxElementUI; break; case 16: - if( _tcsicmp(pstrClass, DUI_CTR_HORIZONTALLAYOUT) == 0 ) pControl = new CHorizontalLayoutUI; - else if( _tcsicmp(pstrClass, DUI_CTR_LISTLABELELEMENT) == 0 ) pControl = new CListLabelElementUI; + if( _tcsicmp(pstrClass, DUI_CTR_HORIZONTALLAYOUT) == 0 ) pControl = new CHorizontalLayoutUI; + else if( _tcsicmp(pstrClass, DUI_CTR_LISTLABELELEMENT) == 0 ) pControl = new CListLabelElementUI; break; case 20: - if( _tcsicmp(pstrClass, DUI_CTR_LISTCONTAINERELEMENT) == 0 ) pControl = new CListContainerElementUI; + if( _tcsicmp(pstrClass, DUI_CTR_LISTCONTAINERELEMENT) == 0 ) pControl = new CListContainerElementUI; break; } // User-supplied control factory if( pControl == NULL ) { - CStdPtrArray* pPlugins = CPaintManagerUI::GetPlugins(); + CDuiPtrArray* pPlugins = CPaintManagerUI::GetPlugins(); LPCREATECONTROL lpCreateControl = NULL; for( int i = 0; i < pPlugins->GetSize(); ++i ) { lpCreateControl = (LPCREATECONTROL)pPlugins->GetAt(i); @@ -453,44 +371,49 @@ CControlUI* CDialogBuilder::_Parse(CMarkupNode* pRoot, CControlUI* pParent, CPai { #ifdef _DEBUG DUITRACE(_T("Unknow Control:%s"),pstrClass); -#else - continue; #endif + continue; } // Add children if( node.HasChildren() ) { _Parse(&node, pControl, pManager); } + TCHAR szValue[256] = { 0 }; + int cchLen = lengthof(szValue) - 1; // Attach to parent // 因为某些属性和父窗口相关,比如selected,必须先Add到父窗口 if( pParent != NULL ) { - CTreeNodeUI* pContainerNode = static_cast(pParent->GetInterface(_T("TreeNode"))); - if(pContainerNode) - pContainerNode->GetTreeNodeHoriznotal()->Add(pControl); - else - { - if( pContainer == NULL ) pContainer = static_cast(pParent->GetInterface(_T("IContainer"))); - ASSERT(pContainer); - if( pContainer == NULL ) return NULL; - if( !pContainer->Add(pControl) ) { - delete pControl; - continue; - } - } + LPCTSTR lpValue = szValue; + if( node.GetAttributeValue(_T("cover"), szValue, cchLen) && _tcscmp(lpValue, _T("true")) == 0 ) { + pParent->SetCover(pControl); + } + else { + CTreeNodeUI* pContainerNode = static_cast(pParent->GetInterface(DUI_CTR_TREENODE)); + if(pContainerNode) + pContainerNode->GetTreeNodeHoriznotal()->Add(pControl); + else + { + if( pContainer == NULL ) pContainer = static_cast(pParent->GetInterface(DUI_CTR_ICONTAINER)); + ASSERT(pContainer); + if( pContainer == NULL ) return NULL; + if( !pContainer->Add(pControl) ) { + pControl->Delete(); + continue; + } + } + } } // Init default attributes if( pManager ) { pControl->SetManager(pManager, NULL, false); LPCTSTR pDefaultAttributes = pManager->GetDefaultAttributeList(pstrClass); if( pDefaultAttributes ) { - pControl->ApplyAttributeList(pDefaultAttributes); + pControl->SetAttributeList(pDefaultAttributes); } } // Process attributes if( node.HasAttributes() ) { - TCHAR szValue[500] = { 0 }; - SIZE_T cchLen = lengthof(szValue) - 1; // Set ordinary attributes int nAttributes = node.GetAttributeCount(); for( int i = 0; i < nAttributes; i++ ) { diff --git a/DuiLib/Core/UIDlgBuilder.h b/DuiLib/Core/UIDlgBuilder.h index ea91174e..8ff03b4a 100644 --- a/DuiLib/Core/UIDlgBuilder.h +++ b/DuiLib/Core/UIDlgBuilder.h @@ -12,7 +12,7 @@ class IDialogBuilderCallback }; -class UILIB_API CDialogBuilder +class DUILIB_API CDialogBuilder { public: CDialogBuilder(); diff --git a/DuiLib/Core/UIManager.cpp b/DuiLib/Core/UIManager.cpp index fca0f956..4b43c8cb 100644 --- a/DuiLib/Core/UIManager.cpp +++ b/DuiLib/Core/UIManager.cpp @@ -87,8 +87,8 @@ bool CPaintManagerUI::m_bUseHSL = false; short CPaintManagerUI::m_H = 180; short CPaintManagerUI::m_S = 100; short CPaintManagerUI::m_L = 100; -CStdPtrArray CPaintManagerUI::m_aPreMessages; -CStdPtrArray CPaintManagerUI::m_aPlugins; +CDuiPtrArray CPaintManagerUI::m_aPreMessages; +CDuiPtrArray CPaintManagerUI::m_aPlugins; CPaintManagerUI::CPaintManagerUI() : m_hWndPaint(NULL), @@ -102,6 +102,7 @@ m_pBackgroundBits(NULL), m_iTooltipWidth(-1), m_hwndTooltip(NULL), m_iHoverTime(1000), +m_bNoActivate(false), m_bShowUpdateRect(false), m_uTimerID(0x1000), m_pRoot(NULL), @@ -174,10 +175,10 @@ m_bLayeredChanged(false) CPaintManagerUI::~CPaintManagerUI() { // Delete the control-tree structures - for( int i = 0; i < m_aDelayedCleanup.GetSize(); i++ ) delete static_cast(m_aDelayedCleanup[i]); + for( int i = 0; i < m_aDelayedCleanup.GetSize(); i++ ) static_cast(m_aDelayedCleanup[i])->Delete(); for( int i = 0; i < m_aAsyncNotify.GetSize(); i++ ) delete static_cast(m_aAsyncNotify[i]); m_mNameHash.Resize(0); - if( m_pRoot != NULL ) delete m_pRoot; + if( m_pRoot != NULL ) m_pRoot->Delete(); ::DeleteObject(m_ResInfo.m_DefaultFontInfo.hFont); RemoveAllFonts(); @@ -369,7 +370,7 @@ CPaintManagerUI* CPaintManagerUI::GetPaintManager(LPCTSTR pstrName) return NULL; } -CStdPtrArray* CPaintManagerUI::GetPaintManagers() +CDuiPtrArray* CPaintManagerUI::GetPaintManagers() { return &m_aPreMessages; } @@ -390,7 +391,7 @@ bool CPaintManagerUI::LoadPlugin(LPCTSTR pstrModuleName) return false; } -CStdPtrArray* CPaintManagerUI::GetPlugins() +CDuiPtrArray* CPaintManagerUI::GetPlugins() { return &m_aPlugins; } @@ -536,6 +537,16 @@ void CPaintManagerUI::SetShowUpdateRect(bool show) m_bShowUpdateRect = show; } +bool CPaintManagerUI::IsNoActivate() +{ + return m_bNoActivate; +} + +void CPaintManagerUI::SetNoActivate(bool bNoActivate) +{ + m_bNoActivate = bNoActivate; +} + BYTE CPaintManagerUI::GetOpacity() const { return m_nOpacity; @@ -655,7 +666,7 @@ bool CPaintManagerUI::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, { // Tabbing between controls if( wParam == VK_TAB ) { - if( m_pFocus && m_pFocus->IsVisible() && m_pFocus->IsEnabled() && _tcsstr(m_pFocus->GetClass(), _T("RichEditUI")) != NULL ) { + if( m_pFocus && m_pFocus->IsVisible() && m_pFocus->IsEnabled() && _tcsstr(m_pFocus->GetClass(), DUI_CTR_RICHEDIT) != NULL ) { if( static_cast(m_pFocus)->IsWantTab() ) return false; } SetNextTabControl(::GetKeyState(VK_SHIFT) >= 0); @@ -760,9 +771,6 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR case WM_APP + 1: { m_bAsyncNotifyPosted = false; - for( int i = 0; i < m_aDelayedCleanup.GetSize(); i++ ) - delete static_cast(m_aDelayedCleanup[i]); - m_aDelayedCleanup.Empty(); TNotifyUI* pMsg = NULL; while( pMsg = static_cast(m_aAsyncNotify.GetAt(0)) ) { @@ -775,6 +783,10 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR } delete pMsg; } + + for( int i = 0; i < m_aDelayedCleanup.GetSize(); i++ ) + static_cast(m_aDelayedCleanup[i])->Delete(); + m_aDelayedCleanup.Empty(); } break; case WM_CLOSE: @@ -799,11 +811,10 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR if( ::GetActiveWindow() == m_hWndPaint ) { HWND hwndParent = GetWindowOwner(m_hWndPaint); + if ((GetWindowStyle(m_hWndPaint) & WS_CHILD) !=0 ) hwndParent = GetParent(m_hWndPaint); if( hwndParent != NULL ) ::SetFocus(hwndParent); } - if (m_hwndTooltip != NULL) //by jiangdong 修改当父窗体以成员变量形式在窗口类中存在时候,当点击父窗体关闭按钮的时候 - //提示框内容还停留在页面中,没有销毁。 - { + if (m_hwndTooltip != NULL) { ::DestroyWindow(m_hwndTooltip); m_hwndTooltip = NULL; } @@ -846,6 +857,11 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR if( !::GetUpdateRect(m_hWndPaint, &rcPaint, FALSE) ) return true; } + // Set focus to first control? + if( m_bFocusNeeded ) { + SetNextTabControl(); + } + SetPainting(true); if( m_bUpdateNeeded ) { m_bUpdateNeeded = false; @@ -902,10 +918,6 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR rcRoot.bottom -= m_rcLayeredInset.bottom; m_pRoot->SetPos(rcRoot, true); } - // Set focus to first control? - if( m_bFocusNeeded ) { - SetNextTabControl(); - } // // Render screen // @@ -1138,6 +1150,14 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR } } break; + case WM_MOUSEACTIVATE: + { + if (m_bNoActivate) { + lRes = MA_NOACTIVATE; + return true; + } + } + break; case WM_MOUSEHOVER: { if( m_pRoot == NULL ) break; @@ -1234,6 +1254,14 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR if( pNewHover != m_pEventHover && m_pEventHover != NULL ) { event.Type = UIEVENT_MOUSELEAVE; event.pSender = m_pEventHover; + + CDuiPtrArray aNeedMouseLeaveNeeded(m_aNeedMouseLeaveNeeded.GetSize()); + aNeedMouseLeaveNeeded.Resize(m_aNeedMouseLeaveNeeded.GetSize()); + ::CopyMemory(aNeedMouseLeaveNeeded.GetData(), m_aNeedMouseLeaveNeeded.GetData(), m_aNeedMouseLeaveNeeded.GetSize() * sizeof(LPVOID)); + for( int i = 0; i < aNeedMouseLeaveNeeded.GetSize(); i++ ) { + static_cast(aNeedMouseLeaveNeeded[i])->Event(event); + } + m_pEventHover->Event(event); m_pEventHover = NULL; if( m_hwndTooltip != NULL ) ::SendMessage(m_hwndTooltip, TTM_TRACKACTIVATE, FALSE, (LPARAM) &m_ToolTip); @@ -1262,7 +1290,7 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR // We alway set focus back to our app (this helps // when Win32 child windows are placed on the dialog // and we need to remove them on focus change). - ::SetFocus(m_hWndPaint); + if (!m_bNoActivate) ::SetFocus(m_hWndPaint); if( m_pRoot == NULL ) break; POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; m_ptLastMousePos = pt; @@ -1285,7 +1313,7 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR break; case WM_LBUTTONDBLCLK: { - ::SetFocus(m_hWndPaint); + if (!m_bNoActivate) ::SetFocus(m_hWndPaint); POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; m_ptLastMousePos = pt; CControlUI* pControl = FindControl(pt); @@ -1330,7 +1358,7 @@ bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LR break; case WM_RBUTTONDOWN: { - ::SetFocus(m_hWndPaint); + if (!m_bNoActivate) ::SetFocus(m_hWndPaint); POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; m_ptLastMousePos = pt; CControlUI* pControl = FindControl(pt); @@ -1562,6 +1590,11 @@ bool CPaintManagerUI::AttachDialog(CControlUI* pControl) // a result of an event fired or similar, so we cannot just delete the objects and // pull the internal memory of the calling code. We'll delay the cleanup. if( m_pRoot != NULL ) { + for( int i = 0; i < m_aDelayedCleanup.GetSize(); i++ ) static_cast(m_aDelayedCleanup[i])->Delete(); + m_aDelayedCleanup.Empty(); + for( int i = 0; i < m_aAsyncNotify.GetSize(); i++ ) delete static_cast(m_aAsyncNotify[i]); + m_aAsyncNotify.Empty(); + m_mNameHash.Resize(0); m_aPostPaintControls.Empty(); m_aNativeWindow.Empty(); AddDelayedCleanup(m_pRoot); @@ -1617,9 +1650,11 @@ void CPaintManagerUI::ReapObjects(CControlUI* pControl) bool CPaintManagerUI::AddOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl) { + if (pControl == NULL || pStrGroupName == NULL) return false; + LPVOID lp = m_mOptionGroup.Find(pStrGroupName); if( lp ) { - CStdPtrArray* aOptionGroup = static_cast(lp); + CDuiPtrArray* aOptionGroup = static_cast(lp); for( int i = 0; i < aOptionGroup->GetSize(); i++ ) { if( static_cast(aOptionGroup->GetAt(i)) == pControl ) { return false; @@ -1628,17 +1663,17 @@ bool CPaintManagerUI::AddOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl aOptionGroup->Add(pControl); } else { - CStdPtrArray* aOptionGroup = new CStdPtrArray(6); + CDuiPtrArray* aOptionGroup = new CDuiPtrArray(6); aOptionGroup->Add(pControl); m_mOptionGroup.Insert(pStrGroupName, aOptionGroup); } return true; } -CStdPtrArray* CPaintManagerUI::GetOptionGroup(LPCTSTR pStrGroupName) +CDuiPtrArray* CPaintManagerUI::GetOptionGroup(LPCTSTR pStrGroupName) { LPVOID lp = m_mOptionGroup.Find(pStrGroupName); - if( lp ) return static_cast(lp); + if( lp ) return static_cast(lp); return NULL; } @@ -1646,7 +1681,7 @@ void CPaintManagerUI::RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pCont { LPVOID lp = m_mOptionGroup.Find(pStrGroupName); if( lp ) { - CStdPtrArray* aOptionGroup = static_cast(lp); + CDuiPtrArray* aOptionGroup = static_cast(lp); if( aOptionGroup == NULL ) return; for( int i = 0; i < aOptionGroup->GetSize(); i++ ) { if( static_cast(aOptionGroup->GetAt(i)) == pControl ) { @@ -1663,10 +1698,10 @@ void CPaintManagerUI::RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pCont void CPaintManagerUI::RemoveAllOptionGroups() { - CStdPtrArray* aOptionGroup; + CDuiPtrArray* aOptionGroup; for( int i = 0; i< m_mOptionGroup.GetSize(); i++ ) { if(LPCTSTR key = m_mOptionGroup.GetAt(i)) { - aOptionGroup = static_cast(m_mOptionGroup.Find(key)); + aOptionGroup = static_cast(m_mOptionGroup.Find(key)); delete aOptionGroup; } } @@ -1709,7 +1744,7 @@ void CPaintManagerUI::SetFocus(CControlUI* pControl, bool bFocusWnd) { // Paint manager window has focus? HWND hFocusWnd = ::GetFocus(); - if( bFocusWnd && hFocusWnd != m_hWndPaint && pControl != m_pFocus ) ::SetFocus(m_hWndPaint); + if( bFocusWnd && hFocusWnd != m_hWndPaint && pControl != m_pFocus && !m_bNoActivate) ::SetFocus(m_hWndPaint); // Already has focus? if( pControl == m_pFocus ) return; // Remove focus from old control @@ -1742,7 +1777,7 @@ void CPaintManagerUI::SetFocus(CControlUI* pControl, bool bFocusWnd) void CPaintManagerUI::SetFocusNeeded(CControlUI* pControl) { - ::SetFocus(m_hWndPaint); + if (!m_bNoActivate) ::SetFocus(m_hWndPaint); if( pControl == NULL ) return; if( m_pFocus != NULL ) { TEventUI event = { 0 }; @@ -1903,6 +1938,8 @@ bool CPaintManagerUI::SetNextTabControl(bool bForward) bool CPaintManagerUI::AddNotifier(INotifyUI* pNotifier) { + if (pNotifier == NULL) return false; + ASSERT(m_aNotifiers.Find(pNotifier)<0); return m_aNotifiers.Add(pNotifier); } @@ -1919,6 +1956,8 @@ bool CPaintManagerUI::RemoveNotifier(INotifyUI* pNotifier) bool CPaintManagerUI::AddPreMessageFilter(IMessageFilterUI* pFilter) { + if (pFilter == NULL) return false; + ASSERT(m_aPreMessageFilters.Find(pFilter)<0); return m_aPreMessageFilters.Add(pFilter); } @@ -1935,6 +1974,8 @@ bool CPaintManagerUI::RemovePreMessageFilter(IMessageFilterUI* pFilter) bool CPaintManagerUI::AddMessageFilter(IMessageFilterUI* pFilter) { + if (pFilter == NULL) return false; + ASSERT(m_aMessageFilters.Find(pFilter)<0); return m_aMessageFilters.Add(pFilter); } @@ -1956,6 +1997,8 @@ int CPaintManagerUI::GetPostPaintCount() const bool CPaintManagerUI::AddPostPaint(CControlUI* pControl) { + if (pControl == NULL) return false; + ASSERT(m_aPostPaintControls.Find(pControl) < 0); return m_aPostPaintControls.Add(pControl); } @@ -1972,6 +2015,8 @@ bool CPaintManagerUI::RemovePostPaint(CControlUI* pControl) bool CPaintManagerUI::SetPostPaintIndex(CControlUI* pControl, int iIndex) { + if (pControl == NULL) return false; + RemovePostPaint(pControl); return m_aPostPaintControls.InsertAt(iIndex, pControl); } @@ -1992,6 +2037,8 @@ RECT CPaintManagerUI::GetNativeWindowRect(HWND hChildWnd) bool CPaintManagerUI::AddNativeWindow(CControlUI* pControl, HWND hChildWnd) { + if (pControl == NULL || hChildWnd == NULL) return false; + RECT rcChildWnd = GetNativeWindowRect(hChildWnd); Invalidate(rcChildWnd); @@ -2019,11 +2066,34 @@ bool CPaintManagerUI::RemoveNativeWindow(HWND hChildWnd) void CPaintManagerUI::AddDelayedCleanup(CControlUI* pControl) { + if (pControl == NULL) return; pControl->SetManager(this, NULL, false); m_aDelayedCleanup.Add(pControl); PostAsyncNotify(); } +void CPaintManagerUI::AddMouseLeaveNeeded(CControlUI* pControl) +{ + if (pControl == NULL) return; + for( int i = 0; i < m_aNeedMouseLeaveNeeded.GetSize(); i++ ) { + if( static_cast(m_aNeedMouseLeaveNeeded[i]) == pControl ) { + return; + } + } + m_aNeedMouseLeaveNeeded.Add(pControl); +} + +bool CPaintManagerUI::RemoveMouseLeaveNeeded(CControlUI* pControl) +{ + if (pControl == NULL) return false; + for( int i = 0; i < m_aNeedMouseLeaveNeeded.GetSize(); i++ ) { + if( static_cast(m_aNeedMouseLeaveNeeded[i]) == pControl ) { + return m_aNeedMouseLeaveNeeded.Remove(i); + } + } + return false; +} + void CPaintManagerUI::SendNotify(CControlUI* pControl, LPCTSTR pstrMessage, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/, bool bAsync /*= false*/, bool bEnableRepeat /*= true*/) { TNotifyUI Msg; @@ -2934,8 +3004,8 @@ void CPaintManagerUI::AddWindowCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAtt if( pstrName == NULL || pstrName[0] == _T('\0') || pstrAttr == NULL || pstrAttr[0] == _T('\0') ) return; CDuiString* pCostomAttr = new CDuiString(pstrAttr); if (pCostomAttr != NULL) { - if (m_mWindowCustomAttrHash.Find(pstrName) == NULL) - m_mWindowCustomAttrHash.Set(pstrName, (LPVOID)pCostomAttr); + if (m_mWindowAttrHash.Find(pstrName) == NULL) + m_mWindowAttrHash.Set(pstrName, (LPVOID)pCostomAttr); else delete pCostomAttr; } @@ -2944,7 +3014,7 @@ void CPaintManagerUI::AddWindowCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAtt LPCTSTR CPaintManagerUI::GetWindowCustomAttribute(LPCTSTR pstrName) const { if( pstrName == NULL || pstrName[0] == _T('\0') ) return NULL; - CDuiString* pCostomAttr = static_cast(m_mWindowCustomAttrHash.Find(pstrName)); + CDuiString* pCostomAttr = static_cast(m_mWindowAttrHash.Find(pstrName)); if( pCostomAttr ) return pCostomAttr->GetData(); return NULL; } @@ -2952,23 +3022,226 @@ LPCTSTR CPaintManagerUI::GetWindowCustomAttribute(LPCTSTR pstrName) const bool CPaintManagerUI::RemoveWindowCustomAttribute(LPCTSTR pstrName) { if( pstrName == NULL || pstrName[0] == _T('\0') ) return NULL; - CDuiString* pCostomAttr = static_cast(m_mWindowCustomAttrHash.Find(pstrName)); + CDuiString* pCostomAttr = static_cast(m_mWindowAttrHash.Find(pstrName)); if( !pCostomAttr ) return false; delete pCostomAttr; - return m_mWindowCustomAttrHash.Remove(pstrName); + return m_mWindowAttrHash.Remove(pstrName); } void CPaintManagerUI::RemoveAllWindowCustomAttribute() { CDuiString* pCostomAttr; - for( int i = 0; i< m_mWindowCustomAttrHash.GetSize(); i++ ) { - if(LPCTSTR key = m_mWindowCustomAttrHash.GetAt(i)) { - pCostomAttr = static_cast(m_mWindowCustomAttrHash.Find(key)); + for( int i = 0; i< m_mWindowAttrHash.GetSize(); i++ ) { + if(LPCTSTR key = m_mWindowAttrHash.GetAt(i)) { + pCostomAttr = static_cast(m_mWindowAttrHash.Find(key)); delete pCostomAttr; } } - m_mWindowCustomAttrHash.Resize(); + m_mWindowAttrHash.Resize(); +} + +CDuiString CPaintManagerUI::GetWindowAttribute(LPCTSTR pstrName) +{ + return _T(""); +} + +void CPaintManagerUI::SetWindowAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) +{ + if( _tcsicmp(pstrName, _T("size")) == 0 ) { + LPTSTR pstr = NULL; + int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetInitSize(cx, cy); + } + else if( _tcsicmp(pstrName, _T("sizebox")) == 0 ) { + RECT rcSizeBox = { 0 }; + LPTSTR pstr = NULL; + rcSizeBox.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + rcSizeBox.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + rcSizeBox.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + rcSizeBox.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetSizeBox(rcSizeBox); + } + else if( _tcsicmp(pstrName, _T("caption")) == 0 ) { + RECT rcCaption = { 0 }; + LPTSTR pstr = NULL; + rcCaption.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + rcCaption.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + rcCaption.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + rcCaption.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetCaptionRect(rcCaption); + } + else if( _tcsicmp(pstrName, _T("roundcorner")) == 0 ) { + LPTSTR pstr = NULL; + int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetRoundCorner(cx, cy); + } + else if( _tcsicmp(pstrName, _T("mininfo")) == 0 ) { + LPTSTR pstr = NULL; + int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetMinInfo(cx, cy); + } + else if( _tcsicmp(pstrName, _T("maxinfo")) == 0 ) { + LPTSTR pstr = NULL; + int cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + int cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + SetMaxInfo(cx, cy); + } + else if( _tcsicmp(pstrName, _T("showdirty")) == 0 ) { + SetShowUpdateRect(_tcsicmp(pstrValue, _T("true")) == 0); + } + else if( _tcscmp(pstrName, _T("noactivate")) == 0 ) { + SetNoActivate(_tcsicmp(pstrValue, _T("true")) == 0); + } + else if( _tcsicmp(pstrName, _T("opacity")) == 0 ) { + SetOpacity(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("layeredopacity")) == 0 ) { + SetLayeredOpacity(_ttoi(pstrValue)); + } + else if( _tcscmp(pstrName, _T("layeredimage")) == 0 ) { + SetLayered(true); + SetLayeredImage(pstrValue); + } + else if( _tcsicmp(pstrName, _T("disabledfontcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetDefaultDisabledColor(clrColor); + } + else if( _tcsicmp(pstrName, _T("defaultfontcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetDefaultFontColor(clrColor); + } + else if( _tcsicmp(pstrName, _T("linkfontcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetDefaultLinkFontColor(clrColor); + } + else if( _tcsicmp(pstrName, _T("linkhoverfontcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetDefaultLinkHoverFontColor(clrColor); + } + else if( _tcsicmp(pstrName, _T("selectedcolor")) == 0 ) { + if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); + LPTSTR pstr = NULL; + DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); + SetDefaultSelectedBkColor(clrColor); + } + else + AddWindowCustomAttribute(pstrName, pstrValue); +} + +CDuiString CPaintManagerUI::GetWindowAttributeList(bool bIgnoreDefault) +{ + return _T(""); +} + +void CPaintManagerUI::SetWindowAttributeList(LPCTSTR pstrList) +{ + CDuiString sItem; + CDuiString sValue; + while( *pstrList != _T('\0') ) { + sItem.Empty(); + sValue.Empty(); + while( *pstrList != _T('\0') && *pstrList != _T('=') ) { + LPTSTR pstrTemp = ::CharNext(pstrList); + while( pstrList < pstrTemp) { + sItem += *pstrList++; + } + } + ASSERT( *pstrList == _T('=') ); + if( *pstrList++ != _T('=') ) return; + ASSERT( *pstrList == _T('\"') ); + if( *pstrList++ != _T('\"') ) return; + while( *pstrList != _T('\0') && *pstrList != _T('\"') ) { + LPTSTR pstrTemp = ::CharNext(pstrList); + while( pstrList < pstrTemp) { + sValue += *pstrList++; + } + } + ASSERT( *pstrList == _T('\"') ); + if( *pstrList++ != _T('\"') ) return; + SetWindowAttribute(sItem, sValue); + if( *pstrList++ != _T(' ') ) return; + } +} + +bool CPaintManagerUI::RemoveWindowAttribute(LPCTSTR pstrName) +{ + return false; +} + +CDuiString CPaintManagerUI::GetWindowXML() +{ + CDuiString sWindowXML; + sWindowXML.Append(_T("(m_SharedResInfo.m_CustomFonts.Find(key))->GetData(); + // sWindowXML.Append(_T("\n\t")); + // } + //} + //for( int i = 0; i< m_ResInfo.m_CustomFonts.GetSize(); i++ ) { + // if(LPCTSTR key = m_ResInfo.m_CustomFonts.GetAt(i)) { + // sDefaultAttr = static_cast(m_ResInfo.m_CustomFonts.Find(key))->GetData(); + // sDefaultAttr.Replace(_T("\""), _T(""")); + // sWindowXML.Append(_T("\n\t")); + // } + //} + + // image + + // MultiLanguage + + // Default + CDuiString sDefaultAttr; + for( int i = 0; i< m_SharedResInfo.m_AttrHash.GetSize(); i++ ) { + if(LPCTSTR key = m_SharedResInfo.m_AttrHash.GetAt(i)) { + sDefaultAttr = static_cast(m_SharedResInfo.m_AttrHash.Find(key))->GetData(); + sDefaultAttr.Replace(_T("\""), _T(""")); + sWindowXML.Append(_T("\n\t")); + } + } + for( int i = 0; i< m_ResInfo.m_AttrHash.GetSize(); i++ ) { + if(LPCTSTR key = m_ResInfo.m_AttrHash.GetAt(i)) { + sDefaultAttr = static_cast(m_ResInfo.m_AttrHash.Find(key))->GetData(); + sDefaultAttr.Replace(_T("\""), _T(""")); + sWindowXML.Append(_T("\n\t")); + } + } + + // Controls + return _T(""); } void CPaintManagerUI::AddMultiLanguageString(int id, LPCTSTR pStrMultiLanguage) @@ -3079,7 +3352,7 @@ CControlUI* CPaintManagerUI::FindSubControlByClass(CControlUI* pParent, LPCTSTR return pParent->FindControl(__FindControlFromClass, (LPVOID)pstrClass, UIFIND_ALL); } -CStdPtrArray* CPaintManagerUI::FindSubControlsByClass(CControlUI* pParent, LPCTSTR pstrClass) +CDuiPtrArray* CPaintManagerUI::FindSubControlsByClass(CControlUI* pParent, LPCTSTR pstrClass) { if( pParent == NULL ) pParent = GetRoot(); ASSERT(pParent); @@ -3088,7 +3361,7 @@ CStdPtrArray* CPaintManagerUI::FindSubControlsByClass(CControlUI* pParent, LPCTS return &m_aFoundControls; } -CStdPtrArray* CPaintManagerUI::GetFoundControls() +CDuiPtrArray* CPaintManagerUI::GetFoundControls() { return &m_aFoundControls; } @@ -3135,7 +3408,7 @@ CControlUI* CALLBACK CPaintManagerUI::__FindControlFromShortcut(CControlUI* pThi if( !pThis->IsVisible() ) return NULL; FINDSHORTCUT* pFS = static_cast(pData); if( pFS->ch == toupper(pThis->GetShortcut()) ) pFS->bPickNext = true; - if( _tcsstr(pThis->GetClass(), _T("LabelUI")) != NULL ) return NULL; // Labels never get focus! + if( _tcsstr(pThis->GetClass(), DUI_CTR_LABEL) != NULL ) return NULL; // Labels never get focus! return pFS->bPickNext ? pThis : NULL; } @@ -3151,7 +3424,7 @@ CControlUI* CALLBACK CPaintManagerUI::__FindControlFromClass(CControlUI* pThis, { LPCTSTR pstrType = static_cast(pData); LPCTSTR pType = pThis->GetClass(); - CStdPtrArray* pFoundControls = pThis->GetManager()->GetFoundControls(); + CDuiPtrArray* pFoundControls = pThis->GetManager()->GetFoundControls(); if( _tcscmp(pstrType, _T("*")) == 0 || _tcscmp(pstrType, pType) == 0 ) { int iIndex = -1; while( pFoundControls->GetAt(++iIndex) != NULL ) ; diff --git a/DuiLib/Core/UIManager.h b/DuiLib/Core/UIManager.h index 9960261b..2b4e4e44 100644 --- a/DuiLib/Core/UIManager.h +++ b/DuiLib/Core/UIManager.h @@ -83,7 +83,7 @@ typedef enum EVENTTYPE_UI ///////////////////////////////////////////////////////////////////////////////////// // -typedef struct UILIB_API tagTFontInfo +typedef struct DUILIB_API tagTFontInfo { HFONT hFont; CDuiString sFontName; @@ -94,7 +94,7 @@ typedef struct UILIB_API tagTFontInfo TEXTMETRIC tm; } TFontInfo; -typedef struct UILIB_API tagTImageInfo +typedef struct DUILIB_API tagTImageInfo { HBITMAP hBitmap; LPBYTE pBits; @@ -107,7 +107,7 @@ typedef struct UILIB_API tagTImageInfo DWORD dwMask; } TImageInfo; -typedef struct UILIB_API tagTDrawInfo +typedef struct DUILIB_API tagTDrawInfo { tagTDrawInfo(); tagTDrawInfo(LPCTSTR lpsz); @@ -125,7 +125,7 @@ typedef struct UILIB_API tagTDrawInfo bool bTiledY; } TDrawInfo; -typedef struct UILIB_API tagTPercentInfo +typedef struct DUILIB_API tagTPercentInfo { double left; double top; @@ -133,7 +133,7 @@ typedef struct UILIB_API tagTPercentInfo double bottom; } TPercentInfo; -typedef struct UILIB_API tagTResInfo +typedef struct DUILIB_API tagTResInfo { DWORD m_dwDefaultDisabledColor; DWORD m_dwDefaultFontColor; @@ -141,15 +141,15 @@ typedef struct UILIB_API tagTResInfo DWORD m_dwDefaultLinkHoverFontColor; DWORD m_dwDefaultSelectedBkColor; TFontInfo m_DefaultFontInfo; - CStdStringPtrMap m_CustomFonts; - CStdStringPtrMap m_ImageHash; - CStdStringPtrMap m_AttrHash; - CStdStringPtrMap m_MultiLanguageHash; + CDuiStringPtrMap m_CustomFonts; + CDuiStringPtrMap m_ImageHash; + CDuiStringPtrMap m_AttrHash; + CDuiStringPtrMap m_MultiLanguageHash; } TResInfo; // Structure for notifications from the system // to the control implementation. -typedef struct UILIB_API tagTEventUI +typedef struct DUILIB_API tagTEventUI { int Type; CControlUI* pSender; @@ -162,20 +162,20 @@ typedef struct UILIB_API tagTEventUI } TEventUI; // Listener interface -class UILIB_API INotifyUI +class DUILIB_API INotifyUI { public: virtual void Notify(TNotifyUI& msg) = 0; }; // MessageFilter interface -class UILIB_API IMessageFilterUI +class DUILIB_API IMessageFilterUI { public: virtual LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled) = 0; }; -class UILIB_API ITranslateAccelerator +class DUILIB_API ITranslateAccelerator { public: virtual LRESULT TranslateAccelerator(MSG *pMsg) = 0; @@ -187,7 +187,7 @@ class UILIB_API ITranslateAccelerator typedef CControlUI* (*LPCREATECONTROL)(LPCTSTR pstrType); -class UILIB_API CPaintManagerUI +class DUILIB_API CPaintManagerUI { public: CPaintManagerUI(); @@ -226,6 +226,8 @@ class UILIB_API CPaintManagerUI void SetMaxInfo(int cx, int cy); bool IsShowUpdateRect() const; void SetShowUpdateRect(bool show); + bool IsNoActivate(); + void SetNoActivate(bool bNoActivate); BYTE GetOpacity() const; void SetOpacity(BYTE nOpacity); @@ -257,9 +259,9 @@ class UILIB_API CPaintManagerUI static void SetHSL(bool bUseHSL, short H, short S, short L); // H:0~360, S:0~200, L:0~200 static void ReloadSkin(); static CPaintManagerUI* GetPaintManager(LPCTSTR pstrName); - static CStdPtrArray* GetPaintManagers(); + static CDuiPtrArray* GetPaintManagers(); static bool LoadPlugin(LPCTSTR pstrModuleName); - static CStdPtrArray* GetPlugins(); + static CDuiPtrArray* GetPlugins(); bool IsForceUseSharedRes() const; void SetForceUseSharedRes(bool bForce); @@ -274,6 +276,7 @@ class UILIB_API CPaintManagerUI void SetDefaultLinkHoverFontColor(DWORD dwColor, bool bShared = false); DWORD GetDefaultSelectedBkColor() const; void SetDefaultSelectedBkColor(DWORD dwColor, bool bShared = false); + TFontInfo* GetDefaultFontInfo(); void SetDefaultFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic, bool bShared = false); DWORD GetCustomFontCount(bool bShared = false) const; @@ -302,10 +305,18 @@ class UILIB_API CPaintManagerUI bool RemoveDefaultAttributeList(LPCTSTR pStrControlName, bool bShared = false); void RemoveAllDefaultAttributeList(bool bShared = false); - void AddWindowCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAttr); - LPCTSTR GetWindowCustomAttribute(LPCTSTR pstrName) const; - bool RemoveWindowCustomAttribute(LPCTSTR pstrName); - void RemoveAllWindowCustomAttribute(); + void AddWindowCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAttr); + LPCTSTR GetWindowCustomAttribute(LPCTSTR pstrName) const; + bool RemoveWindowCustomAttribute(LPCTSTR pstrName); + void RemoveAllWindowCustomAttribute(); + + CDuiString GetWindowAttribute(LPCTSTR pstrName); + void SetWindowAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); + CDuiString GetWindowAttributeList(bool bIgnoreDefault = true); + void SetWindowAttributeList(LPCTSTR pstrList); + bool RemoveWindowAttribute(LPCTSTR pstrName); + + CDuiString GetWindowXML(); static void AddMultiLanguageString(int id, LPCTSTR pStrMultiLanguage); static LPCTSTR GetMultiLanguageString(int id); @@ -319,7 +330,7 @@ class UILIB_API CPaintManagerUI void ReapObjects(CControlUI* pControl); bool AddOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl); - CStdPtrArray* GetOptionGroup(LPCTSTR pStrGroupName); + CDuiPtrArray* GetOptionGroup(LPCTSTR pStrGroupName); void RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl); void RemoveAllOptionGroups(); @@ -363,6 +374,8 @@ class UILIB_API CPaintManagerUI bool RemoveNativeWindow(HWND hChildWnd); void AddDelayedCleanup(CControlUI* pControl); + void AddMouseLeaveNeeded(CControlUI* pControl); + bool RemoveMouseLeaveNeeded(CControlUI* pControl); bool AddTranslateAccelerator(ITranslateAccelerator *pTranslateAccelerator); bool RemoveTranslateAccelerator(ITranslateAccelerator *pTranslateAccelerator); @@ -374,7 +387,7 @@ class UILIB_API CPaintManagerUI CControlUI* FindSubControlByPoint(CControlUI* pParent, POINT pt) const; CControlUI* FindSubControlByName(CControlUI* pParent, LPCTSTR pstrName) const; CControlUI* FindSubControlByClass(CControlUI* pParent, LPCTSTR pstrClass, int iIndex = 0); - CStdPtrArray* FindSubControlsByClass(CControlUI* pParent, LPCTSTR pstrClass); + CDuiPtrArray* FindSubControlsByClass(CControlUI* pParent, LPCTSTR pstrClass); static void MessageLoop(); static bool TranslateMessage(const LPMSG pMsg); @@ -385,7 +398,7 @@ class UILIB_API CPaintManagerUI void UsedVirtualWnd(bool bUsed); private: - CStdPtrArray* GetFoundControls(); + CDuiPtrArray* GetFoundControls(); static CControlUI* CALLBACK __FindControlFromNameHash(CControlUI* pThis, LPVOID pData); static CControlUI* CALLBACK __FindControlFromCount(CControlUI* pThis, LPVOID pData); static CControlUI* CALLBACK __FindControlFromPoint(CControlUI* pThis, LPVOID pData); @@ -414,6 +427,7 @@ class UILIB_API CPaintManagerUI HWND m_hwndTooltip; TOOLINFO m_ToolTip; int m_iHoverTime; + bool m_bNoActivate; bool m_bShowUpdateRect; // CControlUI* m_pRoot; @@ -449,19 +463,20 @@ class UILIB_API CPaintManagerUI bool m_bAsyncNotifyPosted; // - CStdPtrArray m_aNotifiers; - CStdPtrArray m_aTimers; - CStdPtrArray m_aPreMessageFilters; - CStdPtrArray m_aMessageFilters; - CStdPtrArray m_aPostPaintControls; - CStdPtrArray m_aNativeWindow; - CStdPtrArray m_aNativeWindowControl; - CStdPtrArray m_aDelayedCleanup; - CStdPtrArray m_aAsyncNotify; - CStdPtrArray m_aFoundControls; - CStdStringPtrMap m_mNameHash; - CStdStringPtrMap m_mWindowCustomAttrHash; - CStdStringPtrMap m_mOptionGroup; + CDuiPtrArray m_aNotifiers; + CDuiPtrArray m_aTimers; + CDuiPtrArray m_aPreMessageFilters; + CDuiPtrArray m_aMessageFilters; + CDuiPtrArray m_aPostPaintControls; + CDuiPtrArray m_aNativeWindow; + CDuiPtrArray m_aNativeWindowControl; + CDuiPtrArray m_aDelayedCleanup; + CDuiPtrArray m_aAsyncNotify; + CDuiPtrArray m_aFoundControls; + CDuiPtrArray m_aNeedMouseLeaveNeeded; + CDuiStringPtrMap m_mNameHash; + CDuiStringPtrMap m_mWindowAttrHash; + CDuiStringPtrMap m_mOptionGroup; // bool m_bForceUseSharedRes; @@ -480,11 +495,11 @@ class UILIB_API CPaintManagerUI static short m_H; static short m_S; static short m_L; - static CStdPtrArray m_aPreMessages; - static CStdPtrArray m_aPlugins; + static CDuiPtrArray m_aPreMessages; + static CDuiPtrArray m_aPlugins; public: - CStdPtrArray m_aTranslateAccelerator; + CDuiPtrArray m_aTranslateAccelerator; }; } // namespace DuiLib diff --git a/DuiLib/Core/UIMarkup.h b/DuiLib/Core/UIMarkup.h index b5305da7..fc518732 100644 --- a/DuiLib/Core/UIMarkup.h +++ b/DuiLib/Core/UIMarkup.h @@ -16,7 +16,7 @@ class CMarkup; class CMarkupNode; -class UILIB_API CMarkup +class DUILIB_API CMarkup { friend class CMarkupNode; public: @@ -68,7 +68,7 @@ class UILIB_API CMarkup }; -class UILIB_API CMarkupNode +class DUILIB_API CMarkupNode { friend class CMarkup; private: diff --git a/DuiLib/Core/UIRender.cpp b/DuiLib/Core/UIRender.cpp index 54da22c6..7d8f0a20 100644 --- a/DuiLib/Core/UIRender.cpp +++ b/DuiLib/Core/UIRender.cpp @@ -1255,7 +1255,7 @@ void CRenderEngine::DrawText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, LPCTS ::SelectObject(hDC, hOldFont); } -void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, LPCTSTR pstrText, DWORD dwTextColor, RECT* prcLinks, CDuiString* sLinks, int& nLinkRects, UINT uStyle) +void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, LPCTSTR pstrText, DWORD dwTextColor, RECT* prcLinks, CDuiString* sLinks, int& nLinkRects, int iDefaultFont, UINT uStyle) { // 考虑到在xml编辑器中使用<>符号不方便,可以使用{}符号代替 // 支持标签嵌套(如text),但是交叉嵌套是应该避免的(如text) @@ -1282,10 +1282,10 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L bool bDraw = (uStyle & DT_CALCRECT) == 0; - CStdPtrArray aFontArray(10); - CStdPtrArray aColorArray(10); - CStdPtrArray aPIndentArray(10); - CStdPtrArray aVAlignArray(10); + CDuiPtrArray aFontArray(10); + CDuiPtrArray aColorArray(10); + CDuiPtrArray aPIndentArray(10); + CDuiPtrArray aVAlignArray(10); RECT rcClip = { 0 }; ::GetClipBox(hDC, &rcClip); @@ -1297,8 +1297,8 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L CPaintManagerUI::ProcessMultiLanguageTokens(sText); pstrText = sText; - TEXTMETRIC* pTm = &pManager->GetDefaultFontInfo()->tm; - HFONT hOldFont = (HFONT) ::SelectObject(hDC, pManager->GetDefaultFontInfo()->hFont); + TEXTMETRIC* pTm = &pManager->GetFontInfo(iDefaultFont)->tm; + HFONT hOldFont = (HFONT) ::SelectObject(hDC, pManager->GetFontInfo(iDefaultFont)->hFont); ::SetBkMode(hDC, TRANSPARENT); ::SetTextColor(hDC, RGB(GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor))); DWORD dwBkColor = pManager->GetDefaultSelectedBkColor(); @@ -1313,7 +1313,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L rcText.bottom = rc.bottom - rc.top; } int nLinks = 0; - DrawHtmlText(hDC, pManager, rcText, pstrText, dwTextColor, NULL, NULL, nLinks, uStyle | DT_CALCRECT & ~DT_CENTER & ~DT_RIGHT & ~DT_VCENTER & ~DT_BOTTOM); + DrawHtmlText(hDC, pManager, rcText, pstrText, dwTextColor, NULL, NULL, nLinks, iDefaultFont, uStyle | DT_CALCRECT & ~DT_CENTER & ~DT_RIGHT & ~DT_VCENTER & ~DT_BOTTOM); if( (uStyle & DT_SINGLELINE) != 0 ){ if( (uStyle & DT_CENTER) != 0 ) { rc.left = rc.left + ((rc.right - rc.left) / 2) - ((rcText.right - rcText.left) / 2); @@ -1356,10 +1356,10 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L int iLineLinkIndex = 0; // 排版习惯是图文底部对齐,所以每行绘制都要分两步,先计算高度,再绘制 - CStdPtrArray aLineFontArray; - CStdPtrArray aLineColorArray; - CStdPtrArray aLinePIndentArray; - CStdPtrArray aLineVAlignArray; + CDuiPtrArray aLineFontArray; + CDuiPtrArray aLineColorArray; + CDuiPtrArray aLinePIndentArray; + CDuiPtrArray aLineVAlignArray; LPCTSTR pstrLineBegin = pstrText; bool bLineInRaw = false; bool bLineInLink = false; @@ -1448,7 +1448,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L //} aColorArray.Add((LPVOID)clrColor); ::SetTextColor(hDC, RGB(GetBValue(clrColor), GetGValue(clrColor), GetRValue(clrColor))); - TFontInfo* pFontInfo = pManager->GetDefaultFontInfo(); + TFontInfo* pFontInfo = pManager->GetFontInfo(iDefaultFont); if( aFontArray.GetSize() > 0 ) pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); if( pFontInfo->bUnderline == false ) { HFONT hFont = pManager->GetFont(pFontInfo->sFontName, pFontInfo->iSize, pFontInfo->bBold, true, pFontInfo->bItalic); @@ -1469,7 +1469,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L case _T('b'): // Bold { pstrText++; - TFontInfo* pFontInfo = pManager->GetDefaultFontInfo(); + TFontInfo* pFontInfo = pManager->GetFontInfo(iDefaultFont); if( aFontArray.GetSize() > 0 ) pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); if( pFontInfo->bBold == false ) { HFONT hFont = pManager->GetFont(pFontInfo->sFontName, pFontInfo->iSize, true, pFontInfo->bUnderline, pFontInfo->bItalic); @@ -1567,7 +1567,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L } if( sName.IsEmpty() ) { // Italic pstrNextStart = NULL; - TFontInfo* pFontInfo = pManager->GetDefaultFontInfo(); + TFontInfo* pFontInfo = pManager->GetFontInfo(iDefaultFont); if( aFontArray.GetSize() > 0 ) pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); if( pFontInfo->bItalic == false ) { HFONT hFont = pManager->GetFont(pFontInfo->sFontName, pFontInfo->iSize, pFontInfo->bBold, pFontInfo->bUnderline, true); @@ -1734,7 +1734,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L case _T('u'): // Underline text { pstrText++; - TFontInfo* pFontInfo = pManager->GetDefaultFontInfo(); + TFontInfo* pFontInfo = pManager->GetFontInfo(iDefaultFont); if( aFontArray.GetSize() > 0 ) pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); if( pFontInfo->bUnderline == false ) { HFONT hFont = pManager->GetFont(pFontInfo->sFontName, pFontInfo->iSize, pFontInfo->bBold, true, pFontInfo->bItalic); @@ -1827,7 +1827,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L pstrText++; aFontArray.Remove(aFontArray.GetSize() - 1); TFontInfo* pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); - if( pFontInfo == NULL ) pFontInfo = pManager->GetDefaultFontInfo(); + if( pFontInfo == NULL ) pFontInfo = pManager->GetFontInfo(iDefaultFont); if( pTm->tmItalic && pFontInfo->bItalic == false ) { ABC abc; ::GetCharABCWidths(hDC, _T(' '), _T(' '), &abc); @@ -1926,7 +1926,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L ::GetTextExtentPoint32(hDC, pstrText, cchSize, &szText); } if( pt.x + szText.cx > rc.right ) { - if( pt.x + szText.cx > rc.right && pt.x != rc.left) { + if( pt.x + szText.cx > rc.right && cchChars > 1) { cchChars--; cchSize -= (int)(pstrNext - p); } @@ -2004,7 +2004,7 @@ void CRenderEngine::DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, L if( aColorArray.GetSize() > 0 ) clrColor = (int)aColorArray.GetAt(aColorArray.GetSize() - 1); ::SetTextColor(hDC, RGB(GetBValue(clrColor), GetGValue(clrColor), GetRValue(clrColor))); TFontInfo* pFontInfo = (TFontInfo*)aFontArray.GetAt(aFontArray.GetSize() - 1); - if( pFontInfo == NULL ) pFontInfo = pManager->GetDefaultFontInfo(); + if( pFontInfo == NULL ) pFontInfo = pManager->GetFontInfo(iDefaultFont); pTm = &pFontInfo->tm; ::SelectObject(hDC, pFontInfo->hFont); if( bInSelected ) ::SetBkMode(hDC, OPAQUE); diff --git a/DuiLib/Core/UIRender.h b/DuiLib/Core/UIRender.h index 4fed3c4d..a320a2dc 100644 --- a/DuiLib/Core/UIRender.h +++ b/DuiLib/Core/UIRender.h @@ -7,7 +7,7 @@ namespace DuiLib { ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CRenderClip +class DUILIB_API CRenderClip { public: ~CRenderClip(); @@ -25,7 +25,7 @@ class UILIB_API CRenderClip ///////////////////////////////////////////////////////////////////////////////////// // -class UILIB_API CRenderEngine +class DUILIB_API CRenderEngine { public: static DWORD AdjustColor(DWORD dwColor, short H, short S, short L); @@ -48,7 +48,7 @@ class UILIB_API CRenderEngine static void DrawText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, LPCTSTR pstrText, \ DWORD dwTextColor, int iFont, UINT uStyle); static void DrawHtmlText(HDC hDC, CPaintManagerUI* pManager, RECT& rc, LPCTSTR pstrText, - DWORD dwTextColor, RECT* pLinks, CDuiString* sLinks, int& nLinkRects, UINT uStyle); + DWORD dwTextColor, RECT* pLinks, CDuiString* sLinks, int& nLinkRects, int iDefaultFont, UINT uStyle); static HBITMAP GenerateBitmap(CPaintManagerUI* pManager, RECT rc, CControlUI* pStopControl = NULL, DWORD dwFilterColor = 0); static HBITMAP GenerateBitmap(CPaintManagerUI* pManager, CControlUI* pControl, RECT rc, DWORD dwFilterColor = 0); static SIZE GetTextSize(HDC hDC, CPaintManagerUI* pManager , LPCTSTR pstrText, int iFont, UINT uStyle); diff --git a/DuiLib/DuiLib.vcxproj b/DuiLib/DuiLib.vcxproj index 3030312a..46f718b9 100644 --- a/DuiLib/DuiLib.vcxproj +++ b/DuiLib/DuiLib.vcxproj @@ -25,25 +25,25 @@ DynamicLibrary - v110 + v110_xp false Unicode DynamicLibrary - v110 + v110_xp false Unicode DynamicLibrary - v110 + v110_xp false MultiByte DynamicLibrary - v110 + v110_xp false MultiByte @@ -253,6 +253,7 @@ + Create .\Build\Debug/DuiLib.pch @@ -275,6 +276,7 @@ + @@ -312,10 +314,10 @@ - + @@ -353,8 +355,8 @@ - + diff --git a/DuiLib/DuiLib.vcxproj.filters b/DuiLib/DuiLib.vcxproj.filters index 50576b57..cec8f64d 100644 --- a/DuiLib/DuiLib.vcxproj.filters +++ b/DuiLib/DuiLib.vcxproj.filters @@ -45,9 +45,6 @@ Source Files - - Source Files - Source Files\Utils @@ -138,15 +135,21 @@ Source Files\Control - - Source Files\Control - Source Files\Control Source Files\Control + + Source Files\Utils + + + Source Files\Utils + + + Source Files\Control + @@ -257,14 +260,17 @@ Header Files\Control - - Header Files\Control - Header Files\Control Header Files\Control + + Header Files\Utils + + + Header Files\Control + \ No newline at end of file diff --git a/DuiLib/Layout/UIChildLayout.cpp b/DuiLib/Layout/UIChildLayout.cpp index 4ec5d981..68afd18f 100644 --- a/DuiLib/Layout/UIChildLayout.cpp +++ b/DuiLib/Layout/UIChildLayout.cpp @@ -51,6 +51,6 @@ namespace DuiLib LPCTSTR CChildLayoutUI::GetClass() const { - return _T("ChildLayoutUI"); + return DUI_CTR_CHILDLAYOUT; } } // namespace DuiLib diff --git a/DuiLib/Layout/UIChildLayout.h b/DuiLib/Layout/UIChildLayout.h index edb99afb..c598ac2e 100644 --- a/DuiLib/Layout/UIChildLayout.h +++ b/DuiLib/Layout/UIChildLayout.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CChildLayoutUI : public CContainerUI + class DUILIB_API CChildLayoutUI : public CContainerUI { public: CChildLayoutUI(); diff --git a/DuiLib/Layout/UIHorizontalLayout.cpp b/DuiLib/Layout/UIHorizontalLayout.cpp index 565449c8..84c7c4fa 100644 --- a/DuiLib/Layout/UIHorizontalLayout.cpp +++ b/DuiLib/Layout/UIHorizontalLayout.cpp @@ -11,7 +11,7 @@ namespace DuiLib LPCTSTR CHorizontalLayoutUI::GetClass() const { - return _T("HorizontalLayoutUI"); + return DUI_CTR_HORIZONTALLAYOUT; } LPVOID CHorizontalLayoutUI::GetInterface(LPCTSTR pstrName) @@ -179,7 +179,6 @@ namespace DuiLib // Process the scrollbar ProcessScrollBar(rc, cxNeeded, cyNeeded); - } void CHorizontalLayoutUI::DoPostPaint(HDC hDC, const RECT& rcPaint) diff --git a/DuiLib/Layout/UIHorizontalLayout.h b/DuiLib/Layout/UIHorizontalLayout.h index 0b5c8498..aca6f0da 100644 --- a/DuiLib/Layout/UIHorizontalLayout.h +++ b/DuiLib/Layout/UIHorizontalLayout.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CHorizontalLayoutUI : public CContainerUI + class DUILIB_API CHorizontalLayoutUI : public CContainerUI { public: CHorizontalLayoutUI(); diff --git a/DuiLib/Layout/UITabLayout.cpp b/DuiLib/Layout/UITabLayout.cpp index ce7fd562..73619765 100644 --- a/DuiLib/Layout/UITabLayout.cpp +++ b/DuiLib/Layout/UITabLayout.cpp @@ -9,7 +9,7 @@ namespace DuiLib LPCTSTR CTabLayoutUI::GetClass() const { - return _T("TabLayoutUI"); + return DUI_CTR_TABLAYOUT; } LPVOID CTabLayoutUI::GetInterface(LPCTSTR pstrName) @@ -56,12 +56,12 @@ namespace DuiLib return ret; } - bool CTabLayoutUI::Remove(CControlUI* pControl) + bool CTabLayoutUI::Remove(CControlUI* pControl, bool bDoNotDestroy) { if( pControl == NULL) return false; int index = GetItemIndex(pControl); - bool ret = CContainerUI::Remove(pControl); + bool ret = CContainerUI::Remove(pControl, bDoNotDestroy); if( !ret ) return false; if( m_iCurSel == index) diff --git a/DuiLib/Layout/UITabLayout.h b/DuiLib/Layout/UITabLayout.h index 562f55ac..bc975fd9 100644 --- a/DuiLib/Layout/UITabLayout.h +++ b/DuiLib/Layout/UITabLayout.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CTabLayoutUI : public CContainerUI + class DUILIB_API CTabLayoutUI : public CContainerUI { public: CTabLayoutUI(); @@ -15,7 +15,7 @@ namespace DuiLib bool Add(CControlUI* pControl); bool AddAt(CControlUI* pControl, int iIndex); - bool Remove(CControlUI* pControl); + bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); void RemoveAll(); int GetCurSel() const; bool SelectItem(int iIndex, bool bTriggerEvent=true); diff --git a/DuiLib/Layout/UITileLayout.cpp b/DuiLib/Layout/UITileLayout.cpp index 089081f9..12da0bee 100644 --- a/DuiLib/Layout/UITileLayout.cpp +++ b/DuiLib/Layout/UITileLayout.cpp @@ -11,7 +11,7 @@ namespace DuiLib LPCTSTR CTileLayoutUI::GetClass() const { - return _T("TileLayoutUI"); + return DUI_CTR_TILELAYOUT; } LPVOID CTileLayoutUI::GetInterface(LPCTSTR pstrName) diff --git a/DuiLib/Layout/UITileLayout.h b/DuiLib/Layout/UITileLayout.h index 31fda815..470619b9 100644 --- a/DuiLib/Layout/UITileLayout.h +++ b/DuiLib/Layout/UITileLayout.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CTileLayoutUI : public CContainerUI + class DUILIB_API CTileLayoutUI : public CContainerUI { public: CTileLayoutUI(); diff --git a/DuiLib/Layout/UIVerticalLayout.cpp b/DuiLib/Layout/UIVerticalLayout.cpp index 37ddafda..25ad5a18 100644 --- a/DuiLib/Layout/UIVerticalLayout.cpp +++ b/DuiLib/Layout/UIVerticalLayout.cpp @@ -11,7 +11,7 @@ namespace DuiLib LPCTSTR CVerticalLayoutUI::GetClass() const { - return _T("VerticalLayoutUI"); + return DUI_CTR_VERTICALLAYOUT; } LPVOID CVerticalLayoutUI::GetInterface(LPCTSTR pstrName) diff --git a/DuiLib/Layout/UIVerticalLayout.h b/DuiLib/Layout/UIVerticalLayout.h index c47f527d..21ec62cb 100644 --- a/DuiLib/Layout/UIVerticalLayout.h +++ b/DuiLib/Layout/UIVerticalLayout.h @@ -5,7 +5,7 @@ namespace DuiLib { - class UILIB_API CVerticalLayoutUI : public CContainerUI + class DUILIB_API CVerticalLayoutUI : public CContainerUI { public: CVerticalLayoutUI(); diff --git a/DuiLib/UIlib.cpp b/DuiLib/UIlib.cpp index 4cf78b18..82b3e7ea 100644 --- a/DuiLib/UIlib.cpp +++ b/DuiLib/UIlib.cpp @@ -63,4 +63,3 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID /*lpReserved*/) } return TRUE; } - diff --git a/DuiLib/UIlib.h b/DuiLib/UIlib.h index a1571cd9..49a0b606 100644 --- a/DuiLib/UIlib.h +++ b/DuiLib/UIlib.h @@ -28,19 +28,19 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef UILIB_STATIC -# define UILIB_API +# define DUILIB_API #else # if defined(UILIB_EXPORTS) # if defined(_MSC_VER) -# define UILIB_API __declspec(dllexport) +# define DUILIB_API __declspec(dllexport) # else -# define UILIB_API +# define DUILIB_API # endif # else # if defined(_MSC_VER) -# define UILIB_API __declspec(dllimport) +# define DUILIB_API __declspec(dllimport) # else -# define UILIB_API +# define DUILIB_API # endif # endif #endif @@ -66,6 +66,7 @@ #include #include #include +#include #include "Utils/Utils.h" #include "Utils/UIDelegate.h" @@ -78,6 +79,7 @@ #include "Core/UIDlgBuilder.h" #include "Core/UIRender.h" #include "Utils/WinImplBase.h" +#include "Utils/WndShadow.h" #include "Layout/UIVerticalLayout.h" #include "Layout/UIHorizontalLayout.h" @@ -108,4 +110,3 @@ #include "Control/UIWebBrowser.h" #include "Control/UIGifAnim.h" //#include "Control/UIFlash.h" - diff --git a/DuiLib/Utils/UIDelegate.h b/DuiLib/Utils/UIDelegate.h index b4638f9f..37b02d93 100644 --- a/DuiLib/Utils/UIDelegate.h +++ b/DuiLib/Utils/UIDelegate.h @@ -5,7 +5,7 @@ namespace DuiLib { -class UILIB_API CDelegateBase +class DUILIB_API CDelegateBase { public: CDelegateBase(void* pObject, void* pFn); @@ -77,7 +77,7 @@ inline CDelegateStatic MakeDelegate(bool (*pFn)(void*)) return CDelegateStatic(pFn); } -class UILIB_API CEventSource +class DUILIB_API CEventSource { typedef bool (*FnType)(void*); public: @@ -90,7 +90,7 @@ class UILIB_API CEventSource bool operator() (void* param); protected: - CStdPtrArray m_aDelegates; + CDuiPtrArray m_aDelegates; }; } // namespace DuiLib diff --git a/DuiLib/Utils/Utils.cpp b/DuiLib/Utils/Utils.cpp index 2aed20a9..86ba6982 100644 --- a/DuiLib/Utils/Utils.cpp +++ b/DuiLib/Utils/Utils.cpp @@ -3,11 +3,312 @@ namespace DuiLib { + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + STRINGorID::STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) + { + } + + STRINGorID::STRINGorID(unsigned int nID) : m_lpstr(MAKEINTRESOURCE(nID)) + { + } ///////////////////////////////////////////////////////////////////////////////////// // // + CDuiChar::CDuiChar() : m_cValue(0) + { + } + + CDuiChar::CDuiChar(char cValue) + { + m_cValue = cValue; + } + + CDuiChar::CDuiChar(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_cValue = 0; + else m_cValue = (char)_ttol(pstrValue); + } + + CDuiString CDuiChar::ToString() + { + TCHAR tBuffer[16] = {0}; + long lValue = m_cValue; + _ltot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiByte::CDuiByte() : m_byValue(0) + { + } + + CDuiByte::CDuiByte(byte byValue) + { + m_byValue = byValue; + } + + CDuiByte::CDuiByte(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_byValue = 0; + else m_byValue = (byte)_ttol(pstrValue); + } + + CDuiString CDuiByte::ToString() + { + TCHAR tBuffer[16] = {0}; + unsigned long ulValue = m_byValue; + _ultot(ulValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiTChar::CDuiTChar() : m_tValue(_T(' ')) + { + } + + CDuiTChar::CDuiTChar(TCHAR tValue) + { + m_tValue = tValue; + } + + CDuiTChar::CDuiTChar(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_tValue = _T(' '); + else m_tValue = pstrValue[0]; + } + + CDuiString CDuiTChar::ToString() + { + return m_tValue; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiWord::CDuiWord() : m_wValue(0) + { + } + + CDuiWord::CDuiWord(WORD wValue) + { + m_wValue = wValue; + } + + CDuiWord::CDuiWord(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_wValue = 0; + else m_wValue = (WORD)_ttol(pstrValue); + } + + CDuiString CDuiWord::ToString() + { + TCHAR tBuffer[16] = {0}; + unsigned long lValue = m_wValue; + _ultot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiDWord::CDuiDWord() : m_dwValue(0) + { + } + + CDuiDWord::CDuiDWord(DWORD dwValue) + { + m_dwValue = dwValue; + } + + CDuiDWord::CDuiDWord(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_dwValue = 0; + else m_dwValue = (DWORD)_ttoi64(pstrValue); + } + + CDuiString CDuiDWord::ToString() + { + TCHAR tBuffer[32] = {0}; + unsigned long lValue = m_dwValue; + _ultot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiInt::CDuiInt() : m_iValue(0) + { + } + + CDuiInt::CDuiInt(int iValue) + { + m_iValue = iValue; + } + + CDuiInt::CDuiInt(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_iValue = 0; + else m_iValue = (int)_ttoi(pstrValue); + } + + CDuiString CDuiInt::ToString() + { + TCHAR tBuffer[32] = {0}; + int lValue = m_iValue; + _itot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiUInt::CDuiUInt() : m_uValue(0) + { + } + + CDuiUInt::CDuiUInt(unsigned int uValue) + { + m_uValue = uValue; + } + + CDuiUInt::CDuiUInt(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_uValue = 0; + else m_uValue = (unsigned int)_ttoi64(pstrValue); + } + + CDuiString CDuiUInt::ToString() + { + TCHAR tBuffer[32] = {0}; + unsigned int lValue = m_uValue; + _ui64tot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiLong::CDuiLong() : m_lValue(0) + { + } + + CDuiLong::CDuiLong(long lValue) + { + m_lValue = lValue; + } + + CDuiLong::CDuiLong(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_lValue = 0; + else m_lValue = (long)_ttol(pstrValue); + } + + CDuiString CDuiLong::ToString() + { + TCHAR tBuffer[32] = {0}; + long lValue = m_lValue; + _ltot(lValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiULong::CDuiULong() : m_ulValue(0) + { + } + + CDuiULong::CDuiULong(unsigned long ulValue) + { + m_ulValue = ulValue; + } + + CDuiULong::CDuiULong(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_ulValue = 0; + else m_ulValue = (unsigned long)_ttoi64(pstrValue); + } + + CDuiString CDuiULong::ToString() + { + TCHAR tBuffer[32] = {0}; + _ultot(m_ulValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiInt64::CDuiInt64() : m_iiValue(0) + { + } + + CDuiInt64::CDuiInt64(__int64 iiValue) + { + m_iiValue = iiValue; + } + + CDuiInt64::CDuiInt64(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) m_iiValue = 0; + else m_iiValue = _ttoi64(pstrValue); + } + + CDuiString CDuiInt64::ToString() + { + TCHAR tBuffer[32] = {0}; + _i64tot(m_iiValue, tBuffer, 10); + return tBuffer; + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + + CDuiBool::CDuiBool() : m_bValue(false) + { + } + + CDuiBool::CDuiBool(bool bValue) + { + m_bValue = bValue; + } + + CDuiBool::CDuiBool(LPCTSTR pstrValue) + { + if (pstrValue == NULL) m_bValue = false; + else m_bValue = (_tcsicmp(pstrValue, _T("true")) == 0); + } + + CDuiString CDuiBool::ToString() + { + if (m_bValue) return _T("true"); + else return _T("false"); + } + + ///////////////////////////////////////////////////////////////////////////////////// + // + // + CDuiPoint::CDuiPoint() { x = y = 0; @@ -19,7 +320,7 @@ namespace DuiLib y = src.y; } - CDuiPoint::CDuiPoint(int _x, int _y) + CDuiPoint::CDuiPoint(long _x, long _y) { x = _x; y = _y; @@ -31,6 +332,20 @@ namespace DuiLib y = GET_Y_LPARAM(lParam); } + CDuiPoint::CDuiPoint(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) x = y = 0; + LPTSTR pstr = NULL; + x = y = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + y = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + } + + CDuiString CDuiPoint::ToString() + { + CDuiString sPoint; + sPoint.SmallFormat(_T("%ld,%ld"), x, y); + return sPoint; + } ///////////////////////////////////////////////////////////////////////////////////// // @@ -53,12 +368,26 @@ namespace DuiLib cy = rc.bottom - rc.top; } - CDuiSize::CDuiSize(int _cx, int _cy) + CDuiSize::CDuiSize(long _cx, long _cy) { cx = _cx; cy = _cy; } + CDuiSize::CDuiSize(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) cx = cy = 0; + LPTSTR pstr = NULL; + cx = cy = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + } + + CDuiString CDuiSize::ToString() + { + CDuiString sSize; + sSize.SmallFormat(_T("%ld,%ld"), cx, cy); + return sSize; + } ///////////////////////////////////////////////////////////////////////////////////// // @@ -77,7 +406,7 @@ namespace DuiLib bottom = src.bottom; } - CDuiRect::CDuiRect(int iLeft, int iTop, int iRight, int iBottom) + CDuiRect::CDuiRect(long iLeft, long iTop, long iRight, long iBottom) { left = iLeft; top = iTop; @@ -85,6 +414,23 @@ namespace DuiLib bottom = iBottom; } + CDuiRect::CDuiRect(LPCTSTR pstrValue) + { + if (pstrValue == NULL || *pstrValue == _T('\0')) left = top = right = bottom = 0; + LPTSTR pstr = NULL; + left = top = right = bottom = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); + top = bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); + } + + CDuiString CDuiRect::ToString() + { + CDuiString sRect; + sRect.SmallFormat(_T("%ld,%ld,%ld,%ld"), left, top, right, bottom); + return sRect; + } + int CDuiRect::GetWidth() const { return right - left; @@ -149,31 +495,31 @@ namespace DuiLib // // - CStdPtrArray::CStdPtrArray(int iPreallocSize) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(iPreallocSize) + CDuiPtrArray::CDuiPtrArray(int iPreallocSize) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(iPreallocSize) { ASSERT(iPreallocSize>=0); if( iPreallocSize > 0 ) m_ppVoid = static_cast(malloc(iPreallocSize * sizeof(LPVOID))); } - CStdPtrArray::CStdPtrArray(const CStdPtrArray& src) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(0) + CDuiPtrArray::CDuiPtrArray(const CDuiPtrArray& src) : m_ppVoid(NULL), m_nCount(0), m_nAllocated(0) { for(int i=0; i(malloc(iSize * sizeof(LPVOID))); @@ -182,12 +528,12 @@ namespace DuiLib m_nCount = iSize; } - bool CStdPtrArray::IsEmpty() const + bool CDuiPtrArray::IsEmpty() const { return m_nCount == 0; } - bool CStdPtrArray::Add(LPVOID pData) + bool CDuiPtrArray::Add(LPVOID pData) { if( ++m_nCount >= m_nAllocated) { int nAllocated = m_nAllocated * 2; @@ -206,7 +552,7 @@ namespace DuiLib return true; } - bool CStdPtrArray::InsertAt(int iIndex, LPVOID pData) + bool CDuiPtrArray::InsertAt(int iIndex, LPVOID pData) { if( iIndex == m_nCount ) return Add(pData); if( iIndex < 0 || iIndex > m_nCount ) return false; @@ -228,43 +574,44 @@ namespace DuiLib return true; } - bool CStdPtrArray::SetAt(int iIndex, LPVOID pData) + bool CDuiPtrArray::SetAt(int iIndex, LPVOID pData) { if( iIndex < 0 || iIndex >= m_nCount ) return false; m_ppVoid[iIndex] = pData; return true; } - bool CStdPtrArray::Remove(int iIndex) - { - if( iIndex < 0 || iIndex >= m_nCount ) return false; - if( iIndex < --m_nCount ) ::CopyMemory(m_ppVoid + iIndex, m_ppVoid + iIndex + 1, (m_nCount - iIndex) * sizeof(LPVOID)); - return true; - } + bool CDuiPtrArray::Remove(int iIndex, int iCount) + { + if( iIndex < 0 || iCount <= 0 || iIndex + iCount > m_nCount ) return false; + if (iIndex + iCount < m_nCount) ::CopyMemory(m_ppVoid + iIndex, m_ppVoid + iIndex + iCount, (m_nCount - iIndex - iCount) * sizeof(LPVOID)); + m_nCount -= iCount; + return true; + } - int CStdPtrArray::Find(LPVOID pData) const + int CDuiPtrArray::Find(LPVOID pData) const { for( int i = 0; i < m_nCount; i++ ) if( m_ppVoid[i] == pData ) return i; return -1; } - int CStdPtrArray::GetSize() const + int CDuiPtrArray::GetSize() const { return m_nCount; } - LPVOID* CStdPtrArray::GetData() + LPVOID* CDuiPtrArray::GetData() { return m_ppVoid; } - LPVOID CStdPtrArray::GetAt(int iIndex) const + LPVOID CDuiPtrArray::GetAt(int iIndex) const { if( iIndex < 0 || iIndex >= m_nCount ) return NULL; return m_ppVoid[iIndex]; } - LPVOID CStdPtrArray::operator[] (int iIndex) const + LPVOID CDuiPtrArray::operator[] (int iIndex) const { ASSERT(iIndex>=0 && iIndex 0 ) m_pVoid = static_cast(malloc(iPreallocSize * m_iElementSize)); } - CStdValArray::~CStdValArray() + CDuiValArray::~CDuiValArray() { if( m_pVoid != NULL ) free(m_pVoid); } - void CStdValArray::Empty() + void CDuiValArray::Empty() { m_nCount = 0; // NOTE: We keep the memory in place } - bool CStdValArray::IsEmpty() const + bool CDuiValArray::IsEmpty() const { return m_nCount == 0; } - bool CStdValArray::Add(LPCVOID pData) + bool CDuiValArray::Add(LPCVOID pData) { if( ++m_nCount >= m_nAllocated) { int nAllocated = m_nAllocated * 2; @@ -320,30 +667,31 @@ namespace DuiLib return true; } - bool CStdValArray::Remove(int iIndex) + bool CDuiValArray::Remove(int iIndex, int iCount) { - if( iIndex < 0 || iIndex >= m_nCount ) return false; - if( iIndex < --m_nCount ) ::CopyMemory(m_pVoid + (iIndex * m_iElementSize), m_pVoid + ((iIndex + 1) * m_iElementSize), (m_nCount - iIndex) * m_iElementSize); + if( iIndex < 0 || iCount <= 0 || iIndex + iCount > m_nCount ) return false; + if (iIndex + iCount < m_nCount) ::CopyMemory(m_pVoid + (iIndex * m_iElementSize), m_pVoid + (iIndex + iCount) * m_iElementSize, (m_nCount - iIndex - iCount) * m_iElementSize); + m_nCount -= iCount; return true; } - int CStdValArray::GetSize() const + int CDuiValArray::GetSize() const { return m_nCount; } - LPVOID CStdValArray::GetData() + LPVOID CDuiValArray::GetData() { return static_cast(m_pVoid); } - LPVOID CStdValArray::GetAt(int iIndex) const + LPVOID CDuiValArray::GetAt(int iIndex) const { if( iIndex < 0 || iIndex >= m_nCount ) return NULL; return m_pVoid + (iIndex * m_iElementSize); } - LPVOID CStdValArray::operator[] (int iIndex) const + LPVOID CDuiValArray::operator[] (int iIndex) const { ASSERT(iIndex>=0 && iIndexResize(m_nBuckets); } - void CStdStringPtrMap::Resize(int nSize) + void CDuiStringPtrMap::Resize(int nSize) { if( m_aT ) { int len = m_nBuckets; @@ -805,7 +1165,7 @@ namespace DuiLib m_nCount = 0; } - LPVOID CStdStringPtrMap::Find(LPCTSTR key, bool optimize) const + LPVOID CDuiStringPtrMap::Find(LPCTSTR key, bool optimize) const { if( m_nBuckets == 0 || GetSize() == 0 ) return NULL; @@ -830,7 +1190,7 @@ namespace DuiLib return NULL; } - bool CStdStringPtrMap::Insert(LPCTSTR key, LPVOID pData) + bool CDuiStringPtrMap::Insert(LPCTSTR key, LPVOID pData) { if( m_nBuckets == 0 ) return false; if( Find(key) ) return false; @@ -849,7 +1209,7 @@ namespace DuiLib return true; } - LPVOID CStdStringPtrMap::Set(LPCTSTR key, LPVOID pData) + LPVOID CDuiStringPtrMap::Set(LPCTSTR key, LPVOID pData) { if( m_nBuckets == 0 ) return pData; @@ -869,7 +1229,7 @@ namespace DuiLib return NULL; } - bool CStdStringPtrMap::Remove(LPCTSTR key) + bool CDuiStringPtrMap::Remove(LPCTSTR key) { if( m_nBuckets == 0 || GetSize() == 0 ) return false; @@ -891,7 +1251,7 @@ namespace DuiLib return false; } - int CStdStringPtrMap::GetSize() const + int CDuiStringPtrMap::GetSize() const { #if 0//def _DEBUG int nCount = 0; @@ -904,7 +1264,7 @@ namespace DuiLib return m_nCount; } - LPCTSTR CStdStringPtrMap::GetAt(int iIndex) const + LPCTSTR CDuiStringPtrMap::GetAt(int iIndex) const { if( m_nBuckets == 0 || GetSize() == 0 ) return false; @@ -921,7 +1281,7 @@ namespace DuiLib return NULL; } - LPCTSTR CStdStringPtrMap::operator[] (int nIndex) const + LPCTSTR CDuiStringPtrMap::operator[] (int nIndex) const { return GetAt(nIndex); } diff --git a/DuiLib/Utils/Utils.h b/DuiLib/Utils/Utils.h index 2d181cd5..0f5acc88 100644 --- a/DuiLib/Utils/Utils.h +++ b/DuiLib/Utils/Utils.h @@ -8,51 +8,219 @@ namespace DuiLib ///////////////////////////////////////////////////////////////////////////////////// // - class STRINGorID + class DUILIB_API STRINGorID { public: - STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) - { } - STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) - { } + STRINGorID(LPCTSTR lpString); + STRINGorID(unsigned int nID); + LPCTSTR m_lpstr; }; + ///////////////////////////////////////////////////////////////////////////////////// + // + + class CDuiString; + class DUILIB_API IDuiBaseType + { + public: + void FromString(); + CDuiString ToString(); + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiChar : public IDuiBaseType + { + public: + CDuiChar(); + CDuiChar(char cValue); + CDuiChar(LPCTSTR pstrValue); + CDuiString ToString(); + + char m_cValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiByte : public IDuiBaseType + { + public: + CDuiByte(); + CDuiByte(byte byValue); + CDuiByte(LPCTSTR pstrValue); + CDuiString ToString(); + + byte m_byValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiTChar : public IDuiBaseType + { + public: + CDuiTChar(); + CDuiTChar(TCHAR tValue); + CDuiTChar(LPCTSTR pstrValue); + CDuiString ToString(); + + TCHAR m_tValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiWord : public IDuiBaseType + { + public: + CDuiWord(); + CDuiWord(WORD wValue); + CDuiWord(LPCTSTR pstrValue); + CDuiString ToString(); + + WORD m_wValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiDWord : public IDuiBaseType + { + public: + CDuiDWord(); + CDuiDWord(DWORD dwValue); + CDuiDWord(LPCTSTR pstrValue); + CDuiString ToString(); + + DWORD m_dwValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiInt : public IDuiBaseType + { + public: + CDuiInt(); + CDuiInt(int iValue); + CDuiInt(LPCTSTR pstrValue); + CDuiString ToString(); + + int m_iValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiUInt : public IDuiBaseType + { + public: + CDuiUInt(); + CDuiUInt(unsigned int uValue); + CDuiUInt(LPCTSTR pstrValue); + CDuiString ToString(); + + unsigned int m_uValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiLong : public IDuiBaseType + { + public: + CDuiLong(); + CDuiLong(long lValue); + CDuiLong(LPCTSTR pstrValue); + CDuiString ToString(); + + long m_lValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiULong : public IDuiBaseType + { + public: + CDuiULong(); + CDuiULong(unsigned long ulValue); + CDuiULong(LPCTSTR pstrValue); + CDuiString ToString(); + + unsigned long m_ulValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiInt64 : public IDuiBaseType + { + public: + CDuiInt64(); + CDuiInt64(__int64 iiValue); + CDuiInt64(LPCTSTR pstrValue); + CDuiString ToString(); + + __int64 m_iiValue; + }; + + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiBool : public IDuiBaseType + { + public: + CDuiBool(); + CDuiBool(bool bValue); + CDuiBool(LPCTSTR pstrValue); + CDuiString ToString(); + + bool m_bValue; + }; + ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CDuiPoint : public tagPOINT + class DUILIB_API CDuiPoint : public tagPOINT, public IDuiBaseType { public: CDuiPoint(); CDuiPoint(const POINT& src); - CDuiPoint(int x, int y); + CDuiPoint(long x, long y); CDuiPoint(LPARAM lParam); + CDuiPoint(LPCTSTR pstrValue); + CDuiString ToString(); }; - ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CDuiSize : public tagSIZE + class DUILIB_API CDuiSize : public tagSIZE, public IDuiBaseType { public: CDuiSize(); CDuiSize(const SIZE& src); CDuiSize(const RECT rc); - CDuiSize(int cx, int cy); + CDuiSize(long cx, long cy); + CDuiSize(LPCTSTR pstrValue); + CDuiString ToString(); }; - ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CDuiRect : public tagRECT + class DUILIB_API CDuiRect : public tagRECT, public IDuiBaseType { public: CDuiRect(); CDuiRect(const RECT& src); - CDuiRect(int iLeft, int iTop, int iRight, int iBottom); + CDuiRect(long iLeft, long iTop, long iRight, long iBottom); + CDuiRect(LPCTSTR pstrValue); + CDuiString ToString(); int GetWidth() const; int GetHeight() const; @@ -67,15 +235,88 @@ namespace DuiLib void Union(CDuiRect& rc); }; + ///////////////////////////////////////////////////////////////////////////////////// + // + + class DUILIB_API CDuiString : public IDuiBaseType + { + public: + enum { MAX_LOCAL_STRING_LEN = 63 }; + + CDuiString(); + CDuiString(const TCHAR ch); + CDuiString(const CDuiString& src); + CDuiString(LPCTSTR lpsz, int nLen = -1); + ~CDuiString(); + CDuiString ToString(); + + void Empty(); + int GetLength() const; + bool IsEmpty() const; + TCHAR GetAt(int nIndex) const; + void Append(LPCTSTR pstr); + void Assign(LPCTSTR pstr, int nLength = -1); + LPCTSTR GetData() const; + + void SetAt(int nIndex, TCHAR ch); + operator LPCTSTR() const; + + TCHAR operator[] (int nIndex) const; + const CDuiString& operator=(const CDuiString& src); + const CDuiString& operator=(const TCHAR ch); + const CDuiString& operator=(LPCTSTR pstr); +#ifdef _UNICODE + const CDuiString& CDuiString::operator=(LPCSTR lpStr); + const CDuiString& CDuiString::operator+=(LPCSTR lpStr); +#else + const CDuiString& CDuiString::operator=(LPCWSTR lpwStr); + const CDuiString& CDuiString::operator+=(LPCWSTR lpwStr); +#endif + CDuiString operator+(const CDuiString& src) const; + CDuiString operator+(LPCTSTR pstr) const; + const CDuiString& operator+=(const CDuiString& src); + const CDuiString& operator+=(LPCTSTR pstr); + const CDuiString& operator+=(const TCHAR ch); + + bool operator == (LPCTSTR str) const; + bool operator != (LPCTSTR str) const; + bool operator <= (LPCTSTR str) const; + bool operator < (LPCTSTR str) const; + bool operator >= (LPCTSTR str) const; + bool operator > (LPCTSTR str) const; + + int Compare(LPCTSTR pstr) const; + int CompareNoCase(LPCTSTR pstr) const; + + void MakeUpper(); + void MakeLower(); + + CDuiString Left(int nLength) const; + CDuiString Mid(int iPos, int nLength = -1) const; + CDuiString Right(int nLength) const; + + int Find(TCHAR ch, int iPos = 0) const; + int Find(LPCTSTR pstr, int iPos = 0) const; + int ReverseFind(TCHAR ch) const; + int Replace(LPCTSTR pstrFrom, LPCTSTR pstrTo); + + int __cdecl Format(LPCTSTR pstrFormat, ...); + int __cdecl SmallFormat(LPCTSTR pstrFormat, ...); + + protected: + LPTSTR m_pstr; + TCHAR m_szBuffer[MAX_LOCAL_STRING_LEN + 1]; + }; + ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CStdPtrArray + class DUILIB_API CDuiPtrArray { public: - CStdPtrArray(int iPreallocSize = 0); - CStdPtrArray(const CStdPtrArray& src); - ~CStdPtrArray(); + CDuiPtrArray(int iPreallocSize = 0); + CDuiPtrArray(const CDuiPtrArray& src); + ~CDuiPtrArray(); void Empty(); void Resize(int iSize); @@ -84,7 +325,7 @@ namespace DuiLib bool Add(LPVOID pData); bool SetAt(int iIndex, LPVOID pData); bool InsertAt(int iIndex, LPVOID pData); - bool Remove(int iIndex); + bool Remove(int iIndex, int iCount = 1); int GetSize() const; LPVOID* GetData(); @@ -101,16 +342,16 @@ namespace DuiLib ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CStdValArray + class DUILIB_API CDuiValArray { public: - CStdValArray(int iElementSize, int iPreallocSize = 0); - ~CStdValArray(); + CDuiValArray(int iElementSize, int iPreallocSize = 0); + ~CDuiValArray(); void Empty(); bool IsEmpty() const; bool Add(LPCVOID pData); - bool Remove(int iIndex); + bool Remove(int iIndex, int iCount = 1); int GetSize() const; LPVOID GetData(); @@ -124,96 +365,15 @@ namespace DuiLib int m_nAllocated; }; - ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CDuiString - { - public: - enum { MAX_LOCAL_STRING_LEN = 63 }; - - CDuiString(); - CDuiString(const TCHAR ch); - CDuiString(const CDuiString& src); - CDuiString(LPCTSTR lpsz, int nLen = -1); - ~CDuiString(); - - void Empty(); - int GetLength() const; - bool IsEmpty() const; - TCHAR GetAt(int nIndex) const; - void Append(LPCTSTR pstr); - void Assign(LPCTSTR pstr, int nLength = -1); - LPCTSTR GetData() const; - - void SetAt(int nIndex, TCHAR ch); - operator LPCTSTR() const; - - TCHAR operator[] (int nIndex) const; - const CDuiString& operator=(const CDuiString& src); - const CDuiString& operator=(const TCHAR ch); - const CDuiString& operator=(LPCTSTR pstr); -#ifdef _UNICODE - const CDuiString& CDuiString::operator=(LPCSTR lpStr); - const CDuiString& CDuiString::operator+=(LPCSTR lpStr); -#else - const CDuiString& CDuiString::operator=(LPCWSTR lpwStr); - const CDuiString& CDuiString::operator+=(LPCWSTR lpwStr); -#endif - CDuiString operator+(const CDuiString& src) const; - CDuiString operator+(LPCTSTR pstr) const; - const CDuiString& operator+=(const CDuiString& src); - const CDuiString& operator+=(LPCTSTR pstr); - const CDuiString& operator+=(const TCHAR ch); - - bool operator == (LPCTSTR str) const; - bool operator != (LPCTSTR str) const; - bool operator <= (LPCTSTR str) const; - bool operator < (LPCTSTR str) const; - bool operator >= (LPCTSTR str) const; - bool operator > (LPCTSTR str) const; - - int Compare(LPCTSTR pstr) const; - int CompareNoCase(LPCTSTR pstr) const; - - void MakeUpper(); - void MakeLower(); - - CDuiString Left(int nLength) const; - CDuiString Mid(int iPos, int nLength = -1) const; - CDuiString Right(int nLength) const; - - int Find(TCHAR ch, int iPos = 0) const; - int Find(LPCTSTR pstr, int iPos = 0) const; - int ReverseFind(TCHAR ch) const; - int Replace(LPCTSTR pstrFrom, LPCTSTR pstrTo); - - int __cdecl Format(LPCTSTR pstrFormat, ...); - int __cdecl SmallFormat(LPCTSTR pstrFormat, ...); - - protected: - LPTSTR m_pstr; - TCHAR m_szBuffer[MAX_LOCAL_STRING_LEN + 1]; - }; - - - ///////////////////////////////////////////////////////////////////////////////////// - // - - struct TITEM - { - CDuiString Key; - LPVOID Data; - struct TITEM* pPrev; - struct TITEM* pNext; - }; - - class UILIB_API CStdStringPtrMap + struct TITEM; + class DUILIB_API CDuiStringPtrMap { public: - CStdStringPtrMap(int nSize = 83); - ~CStdStringPtrMap(); + CDuiStringPtrMap(int nSize = 83); + ~CDuiStringPtrMap(); void Resize(int nSize = 83); LPVOID Find(LPCTSTR key, bool optimize = true) const; @@ -234,7 +394,7 @@ namespace DuiLib ///////////////////////////////////////////////////////////////////////////////////// // - class UILIB_API CWaitCursor + class DUILIB_API CWaitCursor { public: CWaitCursor(); diff --git a/DuiLib/Utils/WinImplBase.cpp b/DuiLib/Utils/WinImplBase.cpp index f8e16b89..02095032 100644 --- a/DuiLib/Utils/WinImplBase.cpp +++ b/DuiLib/Utils/WinImplBase.cpp @@ -164,9 +164,9 @@ LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOO if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_PaintManager.FindControl(pt)); - if( pControl && _tcsicmp(pControl->GetClass(), _T("ButtonUI")) != 0 && - _tcsicmp(pControl->GetClass(), _T("OptionUI")) != 0 && - _tcsicmp(pControl->GetClass(), _T("TextUI")) != 0 ) + if( pControl && _tcsicmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 && + _tcsicmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 && + _tcsicmp(pControl->GetClass(), DUI_CTR_TEXT) != 0 ) return HTCAPTION; } diff --git a/DuiLib/Utils/WinImplBase.h b/DuiLib/Utils/WinImplBase.h index dfd12dd1..ae3de951 100644 --- a/DuiLib/Utils/WinImplBase.h +++ b/DuiLib/Utils/WinImplBase.h @@ -12,7 +12,7 @@ namespace DuiLib UILIB_ZIPRESOURCE, // 来自资源的zip压缩包 }; - class UILIB_API WindowImplBase + class DUILIB_API WindowImplBase : public CWindowWnd , public CNotifyPump , public INotifyUI diff --git a/DuiLib/Utils/WndShadow.cpp b/DuiLib/Utils/WndShadow.cpp new file mode 100644 index 00000000..55472663 --- /dev/null +++ b/DuiLib/Utils/WndShadow.cpp @@ -0,0 +1,648 @@ +// WndShadow.h : header file +// +// Version 0.1 +// +// Copyright (c) 2006 Perry Zhu, All Rights Reserved. +// +// mailto:perry@live.com +// +// +// This source file may be redistributed unmodified by any means PROVIDING +// it is NOT sold for profit without the authors expressed written +// consent, and providing that this notice and the author's name and all +// copyright notices remain intact. This software is by no means to be +// included as part of any third party components library, or as part any +// development solution that offers MFC extensions that are sold for profit. +// +// If the source code is used in any commercial applications then a statement +// along the lines of: +// +// "Portions Copyright (c) 2006 Perry Zhu" must be included in the "Startup +// Banner", "About Box" or "Printed Documentation". This software is provided +// "as is" without express or implied warranty. Use it at your own risk! The +// author accepts no liability for any damage/loss of business that this +// product may cause. +// +///////////////////////////////////////////////////////////////////////////// +//**************************************************************************** + +#include "StdAfx.h" +#include "WndShadow.h" +#include +#include + +// Some extra work to make this work in VC++ 6.0 + +// walk around the for iterator scope bug of VC++6.0 +#ifdef _MSC_VER +#if _MSC_VER == 1200 +#define for if(false);else for +#endif +#endif + +// Some definitions for VC++ 6.0 without newest SDK +#ifndef WS_EX_LAYERED +#define WS_EX_LAYERED 0x00080000 +#endif + +#ifndef AC_SRC_ALPHA +#define AC_SRC_ALPHA 0x01 +#endif + +#ifndef ULW_ALPHA +#define ULW_ALPHA 0x00000002 +#endif + +using namespace DuiLib; +CWndShadow::pfnUpdateLayeredWindow CWndShadow::s_UpdateLayeredWindow = NULL; + +const TCHAR *strWndClassName = _T("DuiShadowWnd"); + +HINSTANCE CWndShadow::s_hInstance = (HINSTANCE)INVALID_HANDLE_VALUE; + +std::map CWndShadow::s_Shadowmap; + +CWndShadow::CWndShadow(void) +: m_hWnd((HWND)INVALID_HANDLE_VALUE) +, m_OriParentProc(NULL) +, m_nDarkness(150) +, m_nSharpness(5) +, m_nSize(0) +, m_nxOffset(5) +, m_nyOffset(5) +, m_Color(RGB(0, 0, 0)) +, m_pImageInfo(NULL) +, m_WndSize(0) +, m_bUpdate(false) +{ + ::ZeroMemory(&m_rcCorner, sizeof(m_rcCorner)); +} + +CWndShadow::~CWndShadow(void) +{ + if( ::IsWindow(m_hWnd) ) PostMessage(m_hWnd, WM_CLOSE, (WPARAM)0, 0L); + if (m_pImageInfo) + { + CRenderEngine::FreeImage(m_pImageInfo); + m_pImageInfo = NULL; + } +} + +bool CWndShadow::Initialize(HINSTANCE hInstance) +{ + // Should not initiate more than once + if (NULL != s_UpdateLayeredWindow) + return false; + + HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL")); + s_UpdateLayeredWindow = + (pfnUpdateLayeredWindow)GetProcAddress(hUser32, + "UpdateLayeredWindow"); + + // If the import did not succeed, make sure your app can handle it! + if (NULL == s_UpdateLayeredWindow) + return false; + + // Store the instance handle + s_hInstance = hInstance; + + // Register window class for shadow window + WNDCLASSEX wcex; + + memset(&wcex, 0, sizeof(wcex)); + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = CWndShadow::WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = NULL; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = NULL; + wcex.lpszClassName = strWndClassName; + wcex.hIconSm = NULL; + + RegisterClassEx(&wcex); + + return true; +} + +HWND CWndShadow::GetHWND() const +{ + return m_hWnd; +} + +CWndShadow::operator HWND() const +{ + return m_hWnd; +} + +void CWndShadow::Create(HWND hParentWnd) +{ + // Do nothing if the system does not support layered windows + if(NULL == s_UpdateLayeredWindow) + return; + + // Already initialized + _ASSERT(s_hInstance != INVALID_HANDLE_VALUE); + + // Add parent window - shadow pair to the map + _ASSERT(s_Shadowmap.find(hParentWnd) == s_Shadowmap.end()); // Only one shadow for each window + s_Shadowmap[hParentWnd] = this; + + // Create the shadow window + m_hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, strWndClassName, NULL, + /*WS_VISIBLE | *//*WS_CAPTION | */WS_POPUPWINDOW, + CW_USEDEFAULT, 0, 0, 0, hParentWnd, NULL, s_hInstance, NULL); + + // Determine the initial show state of shadow according to parent window's state + LONG lParentStyle = GetWindowLong(hParentWnd, GWL_STYLE); + if(!(WS_VISIBLE & lParentStyle)) // Parent invisible + m_Status = SS_ENABLED; + else if((WS_MAXIMIZE | WS_MINIMIZE) & lParentStyle) // Parent visible but does not need shadow + m_Status = SS_ENABLED | SS_PARENTVISIBLE; + else // Show the shadow + { + m_Status = SS_ENABLED | SS_VISABLE | SS_PARENTVISIBLE; + ::ShowWindow(m_hWnd, SW_SHOWNA); + Update(hParentWnd); + } + + // Replace the original WndProc of parent window to steal messages + m_OriParentProc = GetWindowLong(hParentWnd, GWL_WNDPROC); + +#pragma warning(disable: 4311) // temporrarily disable the type_cast warning in Win32 + SetWindowLong(hParentWnd, GWL_WNDPROC, (LONG)ParentProc); +#pragma warning(default: 4311) + +} + +LRESULT CALLBACK CWndShadow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CWindowWnd* pThis = NULL; + if( uMsg == WM_MOUSEACTIVATE ) return MA_NOACTIVATE; + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +LRESULT CALLBACK CWndShadow::ParentProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + _ASSERT(s_Shadowmap.find(hwnd) != s_Shadowmap.end()); // Shadow must have been attached + + CWndShadow *pThis = s_Shadowmap[hwnd]; + + switch(uMsg) + { + case WM_MOVE: + if(pThis->m_Status & SS_VISABLE) + { + RECT WndRect; + GetWindowRect(hwnd, &WndRect); + if (pThis->m_pImageInfo) { + SetWindowPos(pThis->m_hWnd, NULL, + WndRect.left - pThis->m_rcCorner.left, WndRect.top - pThis->m_rcCorner.top, + 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + + } + else { + SetWindowPos(pThis->m_hWnd, NULL, + WndRect.left + pThis->m_nxOffset - pThis->m_nSize, WndRect.top + pThis->m_nyOffset - pThis->m_nSize, + 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + } + break; + + case WM_SIZE: + if(pThis->m_Status & SS_ENABLED) + { + if(SIZE_MAXIMIZED == wParam || SIZE_MINIMIZED == wParam) + { + ::ShowWindow(pThis->m_hWnd, SW_HIDE); + pThis->m_Status &= ~SS_VISABLE; + } + else if(pThis->m_Status & SS_PARENTVISIBLE) // Parent maybe resized even if invisible + { + // Awful! It seems that if the window size was not decreased + // the window region would never be updated until WM_PAINT was sent. + // So do not Update() until next WM_PAINT is received in this case + if(LOWORD(lParam) > LOWORD(pThis->m_WndSize) || HIWORD(lParam) > HIWORD(pThis->m_WndSize)) + pThis->m_bUpdate = true; + else + pThis->Update(hwnd); + if(!(pThis->m_Status & SS_VISABLE)) + { + ::ShowWindow(pThis->m_hWnd, SW_SHOWNA); + pThis->m_Status |= SS_VISABLE; + } + } + pThis->m_WndSize = lParam; + } + break; + + case WM_PAINT: + { + if(pThis->m_bUpdate) + { + pThis->Update(hwnd); + pThis->m_bUpdate = false; + } + //return hr; + break; + } + + // In some cases of sizing, the up-right corner of the parent window region would not be properly updated + // Update() again when sizing is finished + case WM_EXITSIZEMOVE: + if(pThis->m_Status & SS_VISABLE) + { + pThis->Update(hwnd); + } + break; + + case WM_SHOWWINDOW: + if(pThis->m_Status & SS_ENABLED) + { + if(!wParam) // the window is being hidden + { + ::ShowWindow(pThis->m_hWnd, SW_HIDE); + pThis->m_Status &= ~(SS_VISABLE | SS_PARENTVISIBLE); + } + else if(!(pThis->m_Status & SS_PARENTVISIBLE)) + { + //pThis->Update(hwnd); + pThis->m_bUpdate = true; + ::ShowWindow(pThis->m_hWnd, SW_SHOWNA); + pThis->m_Status |= SS_VISABLE | SS_PARENTVISIBLE; + } + } + break; + + case WM_DESTROY: + DestroyWindow(pThis->m_hWnd); // Destroy the shadow + break; + + case WM_NCDESTROY: + s_Shadowmap.erase(hwnd); // Remove this window and shadow from the map + break; + + } + + +#pragma warning(disable: 4312) // temporrarily disable the type_cast warning in Win32 + // Call the default(original) window procedure for other messages or messages processed but not returned + return ((WNDPROC)pThis->m_OriParentProc)(hwnd, uMsg, wParam, lParam); +#pragma warning(default: 4312) + +} + +void CWndShadow::Update(HWND hParent) +{ + //int ShadSize = 5; + //int Multi = 100 / ShadSize; + + RECT WndRect; + GetWindowRect(hParent, &WndRect); + int nShadWndWid = WndRect.right - WndRect.left + m_nSize * 2; + int nShadWndHei = WndRect.bottom - WndRect.top + m_nSize * 2; + if (m_pImageInfo) { + nShadWndWid = WndRect.right - WndRect.left + m_rcCorner.left + m_rcCorner.right; + nShadWndHei = WndRect.bottom - WndRect.top + m_rcCorner.top + m_rcCorner.bottom; + } + + // Create the alpha blending bitmap + BITMAPINFO bmi; // bitmap header + + ZeroMemory(&bmi, sizeof(BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = nShadWndWid; + bmi.bmiHeader.biHeight = nShadWndHei; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; // four 8-bit components + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = nShadWndWid * nShadWndHei * 4; + BYTE *pvBits; // pointer to DIB section + HBITMAP hbitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pvBits, NULL, 0); + ZeroMemory(pvBits, bmi.bmiHeader.biSizeImage); + + HDC hMemDC = CreateCompatibleDC(NULL); + HBITMAP hOriBmp = NULL; + if (m_pImageInfo) + { + hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap); + RECT rc = {0, 0, nShadWndWid, nShadWndHei}; + RECT rcBmpPart = {0, 0, m_pImageInfo->nX, m_pImageInfo->nY}; + RECT rcCorner = {m_rcCorner.left + m_rcHoleOffset.left, m_rcCorner.top + m_rcHoleOffset.top, + m_rcCorner.right + m_rcHoleOffset.right, m_rcCorner.bottom + m_rcHoleOffset.bottom}; + CRenderEngine::DrawImage(hMemDC, m_pImageInfo->hBitmap, rc, rc, rcBmpPart, rcCorner, true, 255, true); + } + else + { + MakeShadow((UINT32 *)pvBits, hParent, &WndRect); + hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap); + } + + POINT ptDst = {WndRect.left + m_nxOffset - m_nSize, WndRect.top + m_nyOffset - m_nSize}; + if (m_pImageInfo) { + ptDst.x = WndRect.left - m_rcCorner.left; + ptDst.y = WndRect.top - m_rcCorner.top; + } + POINT ptSrc = {0, 0}; + SIZE WndSize = {nShadWndWid, nShadWndHei}; + BLENDFUNCTION blendPixelFunction= { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + + MoveWindow(m_hWnd, ptDst.x, ptDst.y, nShadWndWid, nShadWndHei, FALSE); + + BOOL bRet= s_UpdateLayeredWindow(m_hWnd, NULL, &ptDst, &WndSize, hMemDC, + &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); + + _ASSERT(bRet); // something was wrong.... + + // Delete used resources + if (hOriBmp) SelectObject(hMemDC, hOriBmp); + if (hbitmap) DeleteObject(hbitmap); + DeleteDC(hMemDC); +} + +void CWndShadow::MakeShadow(UINT32 *pShadBits, HWND hParent, RECT *rcParent) +{ + // The shadow algorithm: + // Get the region of parent window, + // Apply morphologic erosion to shrink it into the size (ShadowWndSize - Sharpness) + // Apply modified (with blur effect) morphologic dilation to make the blurred border + // The algorithm is optimized by assuming parent window is just "one piece" and without "wholes" on it + + // Get the region of parent window, + HRGN hParentRgn = CreateRectRgn(0, 0, 0, 0); + GetWindowRgn(hParent, hParentRgn); + + // Determine the Start and end point of each horizontal scan line + SIZE szParent = {rcParent->right - rcParent->left, rcParent->bottom - rcParent->top}; + SIZE szShadow = {szParent.cx + 2 * m_nSize, szParent.cy + 2 * m_nSize}; + // Extra 2 lines (set to be empty) in ptAnchors are used in dilation + int nAnchors = max(szParent.cy, szShadow.cy); // # of anchor points pares + int (*ptAnchors)[2] = new int[nAnchors + 2][2]; + int (*ptAnchorsOri)[2] = new int[szParent.cy][2]; // anchor points, will not modify during erosion + ptAnchors[0][0] = szParent.cx; + ptAnchors[0][1] = 0; + ptAnchors[nAnchors + 1][0] = szParent.cx; + ptAnchors[nAnchors + 1][1] = 0; + if(m_nSize > 0) + { + // Put the parent window anchors at the center + for(int i = 0; i < m_nSize; i++) + { + ptAnchors[i + 1][0] = szParent.cx; + ptAnchors[i + 1][1] = 0; + ptAnchors[szShadow.cy - i][0] = szParent.cx; + ptAnchors[szShadow.cy - i][1] = 0; + } + ptAnchors += m_nSize; + } + for(int i = 0; i < szParent.cy; i++) + { + // find start point + int j; + for(j = 0; j < szParent.cx; j++) + { + if(PtInRegion(hParentRgn, j, i)) + { + ptAnchors[i + 1][0] = j + m_nSize; + ptAnchorsOri[i][0] = j; + break; + } + } + + if(j >= szParent.cx) // Start point not found + { + ptAnchors[i + 1][0] = szParent.cx; + ptAnchorsOri[i][1] = 0; + ptAnchors[i + 1][0] = szParent.cx; + ptAnchorsOri[i][1] = 0; + } + else + { + // find end point + for(j = szParent.cx - 1; j >= ptAnchors[i + 1][0]; j--) + { + if(PtInRegion(hParentRgn, j, i)) + { + ptAnchors[i + 1][1] = j + 1 + m_nSize; + ptAnchorsOri[i][1] = j + 1; + break; + } + } + } + } + + if(m_nSize > 0) + ptAnchors -= m_nSize; // Restore pos of ptAnchors for erosion + int (*ptAnchorsTmp)[2] = new int[nAnchors + 2][2]; // Store the result of erosion + // First and last line should be empty + ptAnchorsTmp[0][0] = szParent.cx; + ptAnchorsTmp[0][1] = 0; + ptAnchorsTmp[nAnchors + 1][0] = szParent.cx; + ptAnchorsTmp[nAnchors + 1][1] = 0; + int nEroTimes = 0; + // morphologic erosion + for(int i = 0; i < m_nSharpness - m_nSize; i++) + { + nEroTimes++; + //ptAnchorsTmp[1][0] = szParent.cx; + //ptAnchorsTmp[1][1] = 0; + //ptAnchorsTmp[szParent.cy + 1][0] = szParent.cx; + //ptAnchorsTmp[szParent.cy + 1][1] = 0; + for(int j = 1; j < nAnchors + 1; j++) + { + ptAnchorsTmp[j][0] = max(ptAnchors[j - 1][0], max(ptAnchors[j][0], ptAnchors[j + 1][0])) + 1; + ptAnchorsTmp[j][1] = min(ptAnchors[j - 1][1], min(ptAnchors[j][1], ptAnchors[j + 1][1])) - 1; + } + // Exchange ptAnchors and ptAnchorsTmp; + int (*ptAnchorsXange)[2] = ptAnchorsTmp; + ptAnchorsTmp = ptAnchors; + ptAnchors = ptAnchorsXange; + } + + // morphologic dilation + ptAnchors += (m_nSize < 0 ? -m_nSize : 0) + 1; // now coordinates in ptAnchors are same as in shadow window + // Generate the kernel + int nKernelSize = m_nSize > m_nSharpness ? m_nSize : m_nSharpness; + int nCenterSize = m_nSize > m_nSharpness ? (m_nSize - m_nSharpness) : 0; + UINT32 *pKernel = new UINT32[(2 * nKernelSize + 1) * (2 * nKernelSize + 1)]; + UINT32 *pKernelIter = pKernel; + for(int i = 0; i <= 2 * nKernelSize; i++) + { + for(int j = 0; j <= 2 * nKernelSize; j++) + { + double dLength = sqrt((i - nKernelSize) * (i - nKernelSize) + (j - nKernelSize) * (double)(j - nKernelSize)); + if(dLength < nCenterSize) + *pKernelIter = m_nDarkness << 24 | PreMultiply(m_Color, m_nDarkness); + else if(dLength <= nKernelSize) + { + UINT32 nFactor = ((UINT32)((1 - (dLength - nCenterSize) / (m_nSharpness + 1)) * m_nDarkness)); + *pKernelIter = nFactor << 24 | PreMultiply(m_Color, nFactor); + } + else + *pKernelIter = 0; + //TRACE("%d ", *pKernelIter >> 24); + pKernelIter ++; + } + //TRACE("\n"); + } + // Generate blurred border + for(int i = nKernelSize; i < szShadow.cy - nKernelSize; i++) + { + int j; + if(ptAnchors[i][0] < ptAnchors[i][1]) + { + + // Start of line + for(j = ptAnchors[i][0]; + j < min(max(ptAnchors[i - 1][0], ptAnchors[i + 1][0]) + 1, ptAnchors[i][1]); + j++) + { + for(int k = 0; k <= 2 * nKernelSize; k++) + { + UINT32 *pPixel = pShadBits + + (szShadow.cy - i - 1 + nKernelSize - k) * szShadow.cx + j - nKernelSize; + UINT32 *pKernelPixel = pKernel + k * (2 * nKernelSize + 1); + for(int l = 0; l <= 2 * nKernelSize; l++) + { + if(*pPixel < *pKernelPixel) + *pPixel = *pKernelPixel; + pPixel++; + pKernelPixel++; + } + } + } // for() start of line + + // End of line + for(j = max(j, min(ptAnchors[i - 1][1], ptAnchors[i + 1][1]) - 1); + j < ptAnchors[i][1]; + j++) + { + for(int k = 0; k <= 2 * nKernelSize; k++) + { + UINT32 *pPixel = pShadBits + + (szShadow.cy - i - 1 + nKernelSize - k) * szShadow.cx + j - nKernelSize; + UINT32 *pKernelPixel = pKernel + k * (2 * nKernelSize + 1); + for(int l = 0; l <= 2 * nKernelSize; l++) + { + if(*pPixel < *pKernelPixel) + *pPixel = *pKernelPixel; + pPixel++; + pKernelPixel++; + } + } + } // for() end of line + + } + } // for() Generate blurred border + + // Erase unwanted parts and complement missing + UINT32 clCenter = m_nDarkness << 24 | PreMultiply(m_Color, m_nDarkness); + for(int i = min(nKernelSize, max(m_nSize - m_nyOffset, 0)); + i < max(szShadow.cy - nKernelSize, min(szParent.cy + m_nSize - m_nyOffset, szParent.cy + 2 * m_nSize)); + i++) + { + UINT32 *pLine = pShadBits + (szShadow.cy - i - 1) * szShadow.cx; + if(i - m_nSize + m_nyOffset < 0 || i - m_nSize + m_nyOffset >= szParent.cy) // Line is not covered by parent window + { + for(int j = ptAnchors[i][0]; j < ptAnchors[i][1]; j++) + { + *(pLine + j) = clCenter; + } + } + else + { + for(int j = ptAnchors[i][0]; + j < min(ptAnchorsOri[i - m_nSize + m_nyOffset][0] + m_nSize - m_nxOffset, ptAnchors[i][1]); + j++) + *(pLine + j) = clCenter; + for(int j = max(ptAnchorsOri[i - m_nSize + m_nyOffset][0] + m_nSize - m_nxOffset, 0); + j < min(ptAnchorsOri[i - m_nSize + m_nyOffset][1] + m_nSize - m_nxOffset, szShadow.cx); + j++) + *(pLine + j) = 0; + for(int j = max(ptAnchorsOri[i - m_nSize + m_nyOffset][1] + m_nSize - m_nxOffset, ptAnchors[i][0]); + j < ptAnchors[i][1]; + j++) + *(pLine + j) = clCenter; + } + } + + // Delete used resources + delete[] (ptAnchors - (m_nSize < 0 ? -m_nSize : 0) - 1); + delete[] ptAnchorsTmp; + delete[] ptAnchorsOri; + delete[] pKernel; + DeleteObject(hParentRgn); +} + +bool CWndShadow::SetImage(LPCTSTR image, RECT rcCorner, RECT rcHoleOffset) +{ + TImageInfo* pImageInfo = CRenderEngine::LoadImage(image); + if (pImageInfo == NULL) return false; + + if (m_pImageInfo) CRenderEngine::FreeImage(m_pImageInfo); + m_pImageInfo = pImageInfo; + m_rcCorner = rcCorner; + m_rcHoleOffset = rcHoleOffset; + + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} + +bool CWndShadow::SetSize(int NewSize) +{ + //if(NewSize > 20 || NewSize < -20) + // return false; + + m_nSize = (signed char)NewSize; + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} + +bool CWndShadow::SetSharpness(unsigned int NewSharpness) +{ + if(NewSharpness > 20) + return false; + + m_nSharpness = (unsigned char)NewSharpness; + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} + +bool CWndShadow::SetDarkness(unsigned int NewDarkness) +{ + if(NewDarkness > 255) + return false; + + m_nDarkness = (unsigned char)NewDarkness; + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} + +bool CWndShadow::SetPosition(int NewXOffset, int NewYOffset) +{ + if(NewXOffset > 20 || NewXOffset < -20 || + NewYOffset > 20 || NewYOffset < -20) + return false; + + m_nxOffset = (signed char)NewXOffset; + m_nyOffset = (signed char)NewYOffset; + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} + +bool CWndShadow::SetColor(COLORREF NewColor) +{ + m_Color = NewColor; + if(SS_VISABLE & m_Status) + Update(GetParent(m_hWnd)); + return true; +} diff --git a/DuiLib/Utils/WndShadow.h b/DuiLib/Utils/WndShadow.h new file mode 100644 index 00000000..c14e7ad3 --- /dev/null +++ b/DuiLib/Utils/WndShadow.h @@ -0,0 +1,124 @@ +// WndShadow.h : header file +// +// Version 0.1 +// +// Copyright (c) 2006 Perry Zhu, All Rights Reserved. +// +// mailto:perry@live.com +// +// +// This source file may be redistributed unmodified by any means PROVIDING +// it is NOT sold for profit without the authors expressed written +// consent, and providing that this notice and the author's name and all +// copyright notices remain intact. This software is by no means to be +// included as part of any third party components library, or as part any +// development solution that offers MFC extensions that are sold for profit. +// +// If the source code is used in any commercial applications then a statement +// along the lines of: +// +// "Portions Copyright (c) 2006 Perry Zhu" must be included in the "Startup +// Banner", "About Box" or "Printed Documentation". This software is provided +// "as is" without express or implied warranty. Use it at your own risk! The +// author accepts no liability for any damage/loss of business that this +// product may cause. +// +///////////////////////////////////////////////////////////////////////////// +//**************************************************************************** + + +#pragma once + +#include + +class DUILIB_API CWndShadow +{ +public: + CWndShadow(void); +public: + virtual ~CWndShadow(void); + +protected: + + // Instance handle, used to register window class and create window + static HINSTANCE s_hInstance; + + // Parent HWND and CWndShadow object pares, in order to find CWndShadow in ParentProc() + static std::map s_Shadowmap; + + // + typedef BOOL (WINAPI *pfnUpdateLayeredWindow)(HWND hWnd, HDC hdcDst, POINT *pptDst, + SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, + BLENDFUNCTION *pblend, DWORD dwFlags); + static pfnUpdateLayeredWindow s_UpdateLayeredWindow; + + HWND m_hWnd; + + LONG m_OriParentProc; // Original WndProc of parent window + + enum ShadowStatus + { + SS_ENABLED = 1, // Shadow is enabled, if not, the following one is always false + SS_VISABLE = 1 << 1, // Shadow window is visible + SS_PARENTVISIBLE = 1<< 2 // Parent window is visible, if not, the above one is always false + }; + BYTE m_Status; + + unsigned char m_nDarkness; // Darkness, transparency of blurred area + unsigned char m_nSharpness; // Sharpness, width of blurred border of shadow window + signed char m_nSize; // Shadow window size, relative to parent window size + + // The X and Y offsets of shadow window, + // relative to the parent window, at center of both windows (not top-left corner), signed + signed char m_nxOffset; + signed char m_nyOffset; + + // Restore last parent window size, used to determine the update strategy when parent window is resized + LPARAM m_WndSize; + + // Set this to true if the shadow should not be update until next WM_PAINT is received + bool m_bUpdate; + + COLORREF m_Color; // Color of shadow + + DuiLib::TImageInfo* m_pImageInfo; + RECT m_rcCorner; + RECT m_rcHoleOffset; + +public: + static bool Initialize(HINSTANCE hInstance); + + HWND GetHWND() const; + operator HWND() const; + void Create(HWND hParentWnd); + + // 使用图片只需要调用这个方法(rcHoleOffset作用是修复圆角显示空白的bug) + bool SetImage(LPCTSTR image, RECT rcCorner, RECT rcHoleOffset); + + // 使用颜色可以使用如下几个方法 + bool SetSize(int NewSize = 0); + bool SetSharpness(unsigned int NewSharpness = 5); + bool SetDarkness(unsigned int NewDarkness = 200); + bool SetPosition(int NewXOffset = 5, int NewYOffset = 5); + bool SetColor(COLORREF NewColor = 0); + +protected: + static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK ParentProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // Redraw, resize and move the shadow + // called when window resized or shadow properties changed, but not only moved without resizing + void Update(HWND hParent); + + // Fill in the shadow window alpha blend bitmap with shadow image pixels + void MakeShadow(UINT32 *pShadBits, HWND hParent, RECT *rcParent); + + // Helper to calculate the alpha-premultiled value for a pixel + inline DWORD PreMultiply(COLORREF cl, unsigned char nAlpha) + { + // It's strange that the byte order of RGB in 32b BMP is reverse to in COLORREF + return (GetRValue(cl) * (DWORD)nAlpha / 255) << 16 | + (GetGValue(cl) * (DWORD)nAlpha / 255) << 8 | + (GetBValue(cl) * (DWORD)nAlpha / 255); + } +}; diff --git a/FlashDemo/App.cpp b/FlashDemo/App.cpp index ee84a9a1..09ca55a4 100644 --- a/FlashDemo/App.cpp +++ b/FlashDemo/App.cpp @@ -94,7 +94,7 @@ class CFrameWnd : public CWindowWnd, public INotifyUI if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_pm.FindControl(pt)); - if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 ) + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 ) return HTCAPTION; } diff --git a/GameDemo/ControlEx.h b/GameDemo/ControlEx.h index cc9c396e..810842aa 100644 --- a/GameDemo/ControlEx.h +++ b/GameDemo/ControlEx.h @@ -88,38 +88,38 @@ class GameListUI : public CListUI bool Add(CControlUI* pControl) { if( !pControl ) return false; - if( _tcscmp(pControl->GetClass(), _T("ListLabelElementUI")) != 0 ) return false; + if( _tcscmp(pControl->GetClass(), DUI_CTR_LISTLABELELEMENT) != 0 ) return false; return CListUI::Add(pControl); } bool AddAt(CControlUI* pControl, int iIndex) { if( !pControl ) return false; - if( _tcscmp(pControl->GetClass(), _T("ListLabelElementUI")) != 0 ) return false; + if( _tcscmp(pControl->GetClass(), DUI_CTR_LISTLABELELEMENT) != 0 ) return false; return CListUI::AddAt(pControl, iIndex); } - bool Remove(CControlUI* pControl) + bool Remove(CControlUI* pControl, bool bDoNotDestroy=false) { if( !pControl ) return false; - if( _tcscmp(pControl->GetClass(), _T("ListLabelElementUI")) != 0 ) return false; + if( _tcscmp(pControl->GetClass(), DUI_CTR_LISTLABELELEMENT) != 0 ) return false; - if (reinterpret_cast(static_cast(pControl->GetInterface(_T("ListLabelElement")))->GetTag()) == NULL) - return CListUI::Remove(pControl); + if (reinterpret_cast(static_cast(pControl->GetInterface(DUI_CTR_LISTLABELELEMENT))->GetTag()) == NULL) + return CListUI::Remove(pControl, bDoNotDestroy); else - return RemoveNode(reinterpret_cast(static_cast(pControl->GetInterface(_T("ListLabelElement")))->GetTag())); + return RemoveNode(reinterpret_cast(static_cast(pControl->GetInterface(DUI_CTR_LISTLABELELEMENT))->GetTag())); } - bool RemoveAt(int iIndex) + bool RemoveAt(int iIndex, bool bDoNotDestroy=false) { CControlUI* pControl = GetItemAt(iIndex); if( !pControl ) return false; - if( _tcscmp(pControl->GetClass(), _T("ListLabelElementUI")) != 0 ) return false; + if( _tcscmp(pControl->GetClass(), DUI_CTR_LISTLABELELEMENT) != 0 ) return false; - if (reinterpret_cast(static_cast(pControl->GetInterface(_T("ListLabelElement")))->GetTag()) == NULL) - return CListUI::RemoveAt(iIndex); + if (reinterpret_cast(static_cast(pControl->GetInterface(DUI_CTR_LISTLABELELEMENT))->GetTag()) == NULL) + return CListUI::RemoveAt(iIndex, bDoNotDestroy); else - return RemoveNode(reinterpret_cast(static_cast(pControl->GetInterface(_T("ListLabelElement")))->GetTag())); + return RemoveNode(reinterpret_cast(static_cast(pControl->GetInterface(DUI_CTR_LISTLABELELEMENT))->GetTag())); } void RemoveAll() @@ -221,8 +221,8 @@ class GameListUI : public CListUI html_text += _T(""); } if( node->data()._level < 3 ) { - if( node->data()._expand ) html_text += _T(""); - else html_text += _T(""); + if( node->data()._expand ) html_text += _T(""); + else html_text += _T(""); } html_text += node->data()._text; pListElement->SetText(html_text); @@ -277,8 +277,8 @@ class GameListUI : public CListUI html_text += _T(""); } if( node->data()._level < 3 ) { - if( node->data()._expand ) html_text += _T(""); - else html_text += _T(""); + if( node->data()._expand ) html_text += _T(""); + else html_text += _T(""); } html_text += node->data()._text; node->data()._pListElement->SetText(html_text); @@ -290,7 +290,7 @@ class GameListUI : public CListUI Node* end = node->get_last_child(); for( int i = begin->data()._pListElement->GetIndex(); i <= end->data()._pListElement->GetIndex(); ++i ) { CControlUI* control = GetItemAt(i); - if( _tcscmp(control->GetClass(), _T("ListLabelElementUI")) == 0 ) { + if( _tcscmp(control->GetClass(), DUI_CTR_LISTLABELELEMENT) == 0 ) { Node* local_parent = ((GameListUI::Node*)control->GetTag())->parent(); control->SetInternVisible(local_parent->data()._expand && local_parent->data()._pListElement->IsVisible()); } diff --git a/GameDemo/GameDemo.cpp b/GameDemo/GameDemo.cpp index d1f49d92..b60432b1 100644 --- a/GameDemo/GameDemo.cpp +++ b/GameDemo/GameDemo.cpp @@ -90,7 +90,7 @@ class CLoginFrameWnd : public CWindowWnd, public INotifyUI, public IMessageFilte if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_pm.FindControl(pt)); - if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 ) + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 ) return HTCAPTION; } @@ -305,8 +305,8 @@ class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackU COptionUI* pControl = static_cast(m_pm.FindControl(_T("hallswitch"))); pControl->Activate(); - CHorizontalLayoutUI* pH = static_cast(m_pm.FindControl(_T("roomswitchpanel"))); - if( pH ) pH->SetVisible(false); + pControl = static_cast(m_pm.FindControl(_T("roomswitch"))); + if( pControl ) pControl->SetVisible(false); } else if( name == _T("fontswitch") ) { TFontInfo* pFontInfo = m_pm.GetDefaultFontInfo(); @@ -326,8 +326,8 @@ class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackU COptionUI* pControl = static_cast(m_pm.FindControl(_T("hallswitch"))); if( pControl ) { pControl->Activate(); - CHorizontalLayoutUI* pH = static_cast(m_pm.FindControl(_T("roomswitchpanel"))); - if( pH ) pH->SetVisible(false); + pControl = static_cast(m_pm.FindControl(_T("roomswitch"))); + if( pControl ) pControl->SetVisible(false); } } else if( name == _T("sendbtn") ) { @@ -367,7 +367,7 @@ class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackU GameListUI* pGameList = static_cast(m_pm.FindControl(_T("gamelist"))); if( pGameList->GetItemIndex(msg.pSender) != -1 ) { - if( _tcscmp(msg.pSender->GetClass(), _T("ListLabelElementUI")) == 0 ) { + if( _tcscmp(msg.pSender->GetClass(), DUI_CTR_LISTLABELELEMENT) == 0 ) { GameListUI::Node* node = (GameListUI::Node*)msg.pSender->GetTag(); POINT pt = { 0 }; @@ -384,16 +384,16 @@ class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackU GameListUI* pGameList = static_cast(m_pm.FindControl(_T("gamelist"))); if( pGameList->GetItemIndex(msg.pSender) != -1 ) { - if( _tcscmp(msg.pSender->GetClass(), _T("ListLabelElementUI")) == 0 ) { + if( _tcscmp(msg.pSender->GetClass(), DUI_CTR_LISTLABELELEMENT) == 0 ) { GameListUI::Node* node = (GameListUI::Node*)msg.pSender->GetTag(); pGameList->ExpandNode(node, !node->data()._expand); if( node->data()._level == 3 ) { COptionUI* pControl = static_cast(m_pm.FindControl(_T("roomswitch"))); if( pControl ) { - CHorizontalLayoutUI* pH = static_cast(m_pm.FindControl(_T("roomswitchpanel"))); - if( pH ) pH->SetVisible(true); + pControl->SetVisible(true); pControl->SetText(node->parent()->parent()->data()._text); pControl->Activate(); + } } } @@ -504,9 +504,9 @@ class CGameFrameWnd : public CWindowWnd, public INotifyUI, public IListCallbackU if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_pm.FindControl(pt)); - if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("OptionUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("TextUI")) != 0 ) + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_TEXT) != 0 ) return HTCAPTION; } diff --git a/ListDemo/Main.cpp b/ListDemo/Main.cpp index 7a563b97..bc9fe6ad 100644 --- a/ListDemo/Main.cpp +++ b/ListDemo/Main.cpp @@ -345,9 +345,9 @@ class ListMainForm : public CWindowWnd, public INotifyUI, public IListCallbackUI if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) { CControlUI* pControl = static_cast(m_pm.FindControl(pt)); - if( pControl && _tcscmp(pControl->GetClass(), _T("ButtonUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("OptionUI")) != 0 && - _tcscmp(pControl->GetClass(), _T("TextUI")) != 0 ) + if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_OPTION) != 0 && + _tcscmp(pControl->GetClass(), DUI_CTR_TEXT) != 0 ) return HTCAPTION; } diff --git a/MenuDemo/MenuDemo.vcxproj b/MenuDemo/MenuDemo.vcxproj index f65394f1..fc9448b0 100644 --- a/MenuDemo/MenuDemo.vcxproj +++ b/MenuDemo/MenuDemo.vcxproj @@ -24,27 +24,27 @@ Application - v110 false Unicode + v110_xp Application - v110 false Unicode + v110_xp Application - v110 false MultiByte + v110_xp Application - v110 false MultiByte + v110_xp @@ -67,27 +67,31 @@ - <_ProjectFileVersion>11.0.61030.0 - - - .\Release\ - .\Release\ - false - - - .\Debug\ - .\Debug\ - false - - - .\Debug_u\ - .\Debug_u\ - false - - - .\Release_u\ - .\Release_u\ - false + <_ProjectFileVersion>10.0.40219.1 + .\Release\ + .\Release\ + false + .\Debug\ + .\Debug\ + false + $(SolutionDir)bin\ + $(Configuration)\ + false + .\Release_u\ + .\Release_u\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + @@ -96,7 +100,8 @@ true Win32 .\Release/MenuDemo.tlb - + + MinSpace @@ -105,7 +110,8 @@ true MultiThreaded true - + + stdafx.h .\Release/MenuDemo.pch .\Release/ @@ -137,7 +143,8 @@ true Win32 .\Debug/MenuDemo.tlb - + + Disabled @@ -145,7 +152,8 @@ true EnableFastChecks MultiThreadedDebug - + + stdafx.h .\Debug/MenuDemo.pch .\Debug/ @@ -182,15 +190,17 @@ true Win32 .\Debug/MenuDemo.tlb - + + Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;UILIB_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug - + + stdafx.h .\Debug_u/MenuDemo.pch .\Debug_u/ @@ -227,7 +237,8 @@ true Win32 .\Release/MenuDemo.tlb - + + MinSpace @@ -236,7 +247,8 @@ true MultiThreaded true - + + stdafx.h .\Release_u/MenuDemo.pch .\Release_u/ @@ -264,15 +276,21 @@ - + + + Create + + + + @@ -282,8 +300,8 @@ - - + + diff --git a/MenuDemo/MenuDemo.vcxproj.filters b/MenuDemo/MenuDemo.vcxproj.filters index f76e6204..9b2eda01 100644 --- a/MenuDemo/MenuDemo.vcxproj.filters +++ b/MenuDemo/MenuDemo.vcxproj.filters @@ -2,14 +2,14 @@ - {9d1b2cb3-6e9d-4ce9-bb2f-b5cf6ad7d0ca} + {20b1c3d9-376c-4de4-b604-48ec3c5c00e2} cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - {5db0c30b-7a4d-43ae-afca-161fcaa377f9} + {1db34056-bb54-457c-b98c-2e032760fe94} - {d299cb3e-f627-4966-bcff-20a4419ed1aa} + {4fad4cf7-23cc-414e-8d39-b6128b5cc42a} @@ -31,6 +31,9 @@ Header Files + + Source Files + @@ -54,6 +57,15 @@ Resource Files + + Header Files + + + Header Files + + + Header Files + @@ -61,11 +73,11 @@ - + Resource Files - - + + Resource Files - + \ No newline at end of file diff --git a/MenuDemo/UIMenu.cpp b/MenuDemo/UIMenu.cpp index ff0fefcf..84ee32b0 100644 --- a/MenuDemo/UIMenu.cpp +++ b/MenuDemo/UIMenu.cpp @@ -87,13 +87,13 @@ bool CMenuUI::SetItemIndex(CControlUI* pControl, int iIndex) return __super::SetItemIndex(pControl, iIndex); } -bool CMenuUI::Remove(CControlUI* pControl) +bool CMenuUI::Remove(CControlUI* pControl, bool bDoNotDestroy) { CMenuElementUI* pMenuItem = static_cast(pControl->GetInterface(kMenuElementUIInterfaceName)); if (pMenuItem == NULL) return false; - return __super::Remove(pControl); + return __super::Remove(pControl, bDoNotDestroy); } SIZE CMenuUI::EstimateSize(SIZE szAvailable) @@ -235,7 +235,7 @@ LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) m_pLayout->SetManager(&m_pm, NULL, true); LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName); if( pDefaultAttributes ) { - m_pLayout->ApplyAttributeList(pDefaultAttributes); + m_pLayout->SetAttributeList(pDefaultAttributes); } m_pLayout->SetBkColor(0xFFFFFFFF); m_pLayout->SetBorderColor(0xFF85E4FF); @@ -463,7 +463,7 @@ LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) // // MenuElementUI -const TCHAR* const kMenuElementUIClassName = _T("MenuElementUI"); +const TCHAR* const kMenuElementUIClassName = _T("MenuElement"); const TCHAR* const kMenuElementUIInterfaceName = _T("MenuElement"); CMenuElementUI::CMenuElementUI(): @@ -472,7 +472,7 @@ m_pWindow(NULL) m_cxyFixed.cy = 25; m_bMouseChildEnabled = true; - SetMouseChildEnabled(false); + //SetMouseChildEnabled(false); } CMenuElementUI::~CMenuElementUI() @@ -489,17 +489,79 @@ LPVOID CMenuElementUI::GetInterface(LPCTSTR pstrName) return CListContainerElementUI::GetInterface(pstrName); } -void CMenuElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) +bool CMenuElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) { - CMenuElementUI::DrawItemBk(hDC, m_rcItem); - DrawItemText(hDC, m_rcItem); - for (int i = 0; i < GetCount(); ++i) { - CControlUI* pControl = static_cast(m_items[i]); - if( pControl == pStopControl ) break; - if( !pControl->IsVisible() ) continue; - if( pControl->GetInterface(kMenuElementUIInterfaceName) != NULL) continue; - pControl->Paint(hDC, rcPaint, pStopControl); - } + RECT rcTemp = { 0 }; + if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true; + + CRenderClip clip; + CRenderClip::GenerateClip(hDC, rcTemp, clip); + CMenuElementUI::DrawItemBk(hDC, m_rcItem); + DrawItemText(hDC, m_rcItem); + + if( m_items.GetSize() > 0 ) { + RECT rc = m_rcItem; + rc.left += m_rcInset.left; + rc.top += m_rcInset.top; + rc.right -= m_rcInset.right; + rc.bottom -= m_rcInset.bottom; + if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth(); + if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); + + if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) { + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( pControl->GetInterface(kMenuElementUIInterfaceName) != NULL ) continue; + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + else { + CRenderClip childClip; + CRenderClip::GenerateClip(hDC, rcTemp, childClip); + for( int it = 0; it < m_items.GetSize(); it++ ) { + CControlUI* pControl = static_cast(m_items[it]); + if( pControl == pStopControl ) return false; + if( !pControl->IsVisible() ) continue; + if( pControl->GetInterface(kMenuElementUIInterfaceName) != NULL ) continue; + if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue; + if( pControl->IsFloat() ) { + if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue; + CRenderClip::UseOldClipBegin(hDC, childClip); + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + CRenderClip::UseOldClipEnd(hDC, childClip); + } + else { + if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue; + if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + } + + if( m_pVerticalScrollBar != NULL ) { + if( m_pVerticalScrollBar == pStopControl ) return false; + if (m_pVerticalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) { + if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + + if( m_pHorizontalScrollBar != NULL ) { + if( m_pHorizontalScrollBar == pStopControl ) return false; + if (m_pHorizontalScrollBar->IsVisible()) { + if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) { + if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false; + } + } + } + return true; } void CMenuElementUI::DrawItemText(HDC hDC, const RECT& rcItem) @@ -527,7 +589,7 @@ void CMenuElementUI::DrawItemText(HDC hDC, const RECT& rcItem) if( pInfo->bShowHtml ) CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, iTextColor, \ - NULL, NULL, nLinks, DT_SINGLELINE | pInfo->uTextStyle); + NULL, NULL, nLinks, pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle); else CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, iTextColor, \ pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle); @@ -564,10 +626,10 @@ SIZE CMenuElementUI::EstimateSize(SIZE szAvailable) rcText.right -= pInfo->rcTextPadding.right; if( pInfo->bShowHtml ) { int nLinks = 0; - CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, NULL, NULL, nLinks, DT_CALCRECT | pInfo->uTextStyle); + CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); } else { - CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle); + CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER); } cXY.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right + 20; cXY.cy = rcText.bottom - rcText.top + pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; @@ -607,7 +669,6 @@ void CMenuElementUI::DoEvent(TEventUI& event) s_context_menu_observer.RBroadcast(param); m_pOwner->SelectItem(GetIndex(), true); } - return; } if( event.Type == UIEVENT_BUTTONDOWN ) diff --git a/MenuDemo/UIMenu.h b/MenuDemo/UIMenu.h index d5548d96..724ee117 100644 --- a/MenuDemo/UIMenu.h +++ b/MenuDemo/UIMenu.h @@ -53,7 +53,7 @@ class CMenuUI : public CListUI virtual int GetItemIndex(CControlUI* pControl) const; virtual bool SetItemIndex(CControlUI* pControl, int iIndex); - virtual bool Remove(CControlUI* pControl); + virtual bool Remove(CControlUI* pControl, bool bDoNotDestroy=false); SIZE EstimateSize(SIZE szAvailable); @@ -64,7 +64,7 @@ class CMenuUI : public CListUI // // MenuElementUI -extern const TCHAR* const kMenuElementUIClassName;// = _T("MenuElementUI"); +extern const TCHAR* const kMenuElementUIClassName;// = _T("MenuElement"); extern const TCHAR* const kMenuElementUIInterfaceName;// = _T("MenuElement); class CMenuElementUI; @@ -101,7 +101,7 @@ class CMenuElementUI : public CListContainerElementUI LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); - void DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); + bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl); void DrawItemText(HDC hDC, const RECT& rcItem); diff --git a/MenuDemo/res/menutest.xml b/MenuDemo/res/menutest.xml index a48cad72..38a15345 100644 --- a/MenuDemo/res/menutest.xml +++ b/MenuDemo/res/menutest.xml @@ -7,7 +7,7 @@ - +