⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textdisplayitem.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "TextDisplayItem.hpp"
#include "PaintHelper.hpp"
#include "Common.hpp"
#include "Layout.hpp"


EXTERN_C
HRESULT
WINAPI
PHCreateTextDisplayItem(
    const WCHAR* pText,
    IVoIPDisplayItem** ppItem
    )
{
    if (!ppItem)
    {
        ASSERT(0);
        return E_INVALIDARG;
    }

    *ppItem = NULL;

    TextDisplayItem_t* pNewItem = new TextDisplayItem_t();
    if (!pNewItem)
    {
        return E_OUTOFMEMORY;
    }

    HRESULT hr = pNewItem->SetText(pText);
    if (SUCCEEDED(hr))
    {
        *ppItem = pNewItem;
    }
    else
    {
        delete pNewItem;
    }

    return hr;
}

//forward declarations (helper function/structure for
//drawing a highlighted string
struct DRAW_HIGHLIGHTED_TEXT
{
    COLORREF crTextHighlighted;
    COLORREF crBkHighlighted;
    INT      bkModeHighlighted;
    INT      idxHighlightStart;
    INT      idxHighlightEnd;
};

HRESULT DrawHighlightedText(
    HDC   hdc,
    __in const WCHAR* pText,
    INT   cchText,
    __in const RECT*  prc,
    UINT  dtFlags,
    __in const DRAW_HIGHLIGHTED_TEXT* pHighlightParams
    );

/*------------------------------------------------------------------------------
    TextDisplayItem_t::TextDisplayItem_t

    Constructor
------------------------------------------------------------------------------*/
TextDisplayItem_t::TextDisplayItem_t()
{
    m_HighlightStart = -1;
    m_HighlightEnd   = -1;
    m_Cookie         = 0;
    m_pUnk          = NULL;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::~TextDisplayItem_t

    Destructor
------------------------------------------------------------------------------*/
TextDisplayItem_t::~TextDisplayItem_t()
{
    if(m_pUnk != NULL)
    {
        m_pUnk->Release();     
    }
}

HRESULT
TextDisplayItem_t::QueryInterface(
    REFIID riid, 
    __deref_out void** ppvObject
    )
{
    if (ppvObject && riid == IID_IVoIPTextDisplayItem)
    {
        *ppvObject = static_cast<IVoIPTextDisplayItem*>(this);
        return S_OK;
    }

    return CVoIPDisplayItem::QueryInterface(riid, ppvObject);
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::Draw

    Draws the text of the simple item on one line

    Parameters:
        hdc: the DC to draw into
        pRectangle: the rect to draw into
        IsSelected: TRUE if we are the selected item
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::Draw(
    HDC hdc,
    const RECT* pRectangle,
    BOOL IsSelected,
    BOOL IsTopItem
    )
{
    if (!pRectangle)
    {
        return E_INVALIDARG;
    }

    HRESULT hr = S_OK;
    PaintHelper_t paint;
    RECT DrawRectangle = *pRectangle;

    hr = paint.Attach(hdc);
    if (FAILED(hr))
    {
        return hr;
    }

    //Draw the band around the item
    DrawBand(paint, pRectangle, IsSelected, IsTopItem);

    //if there is no text, don't do anymore drawing
    ASSERT(!m_Text.empty());

    //draw the first run
    if (! m_Text.length())
    {
        goto exit;
    }

    //if the beginning is highlighted, start this way...
    
    //Set up the rects and the DC
    InflateRect(
        &DrawRectangle,
        -Layout_t::TextItemHorzMargin(),
        -Layout_t::TextItemVerMargin()
        );

    paint.SetFont(Fonts_t::InformationText());
    paint.SetBkMode(TRANSPARENT);

    if (! IsSelected && (m_HighlightStart >= 0 || m_HighlightEnd >= 0))
    {
        paint.SetTextColor(Colors_t::DisplayItemTextColor());

        DRAW_HIGHLIGHTED_TEXT drawHighlight = {0};
        drawHighlight.bkModeHighlighted = OPAQUE;
        drawHighlight.crBkHighlighted   = Colors_t::DisplayItemSelectedBackgroundColor();
        drawHighlight.crTextHighlighted = Colors_t::DisplayItemTextColor();
        drawHighlight.idxHighlightStart = m_HighlightStart;
        drawHighlight.idxHighlightEnd   = m_HighlightEnd;

        hr = DrawHighlightedText(
            hdc, 
            m_Text,
            m_Text.length(),
            &DrawRectangle,
            DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS,
            &drawHighlight
            );
    }
    else
    {
        paint.SetTextColor(
            IsSelected ?
                Colors_t::DisplayItemSelectedTextColor() :
                Colors_t::DisplayItemTextColor()
            );

        //Draw the text on 1 line
        hr = paint.DrawText(
            m_Text,
            m_Text.length(),
            &DrawRectangle,
            DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS
            );
    }

exit:
    paint.End();
    return hr;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::SetComPtr

    Stores a ComPtr
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::SetComPtr(
    IUnknown* pUnk
    )
{
    if (m_pUnk != NULL)
    {
        m_pUnk->Release();
    }
    m_pUnk = pUnk;
    
    if (m_pUnk != NULL)
    {
        m_pUnk->AddRef();
    }
    return S_OK;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::SetComPtr

    Returns the stored ComPtr
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::GetComPtr(
    IUnknown** ppUnk
    )
{
    if (ppUnk == NULL)
    {
        return E_POINTER;
    }
    *ppUnk = m_pUnk;
    if (*ppUnk)
    {
        (*ppUnk)->AddRef();
    }
    return  S_OK;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::SetText

    Sets the main text of the item
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::SetText(
    const WCHAR* pText
    )
{
    if (!pText)
    {
        ASSERT(0);
        return E_INVALIDARG;
    }

    return m_Text.assign(pText) ? S_OK : E_OUTOFMEMORY;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::GetText

    Gets the text of the item
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::GetText(
    WCHAR* pBuffer,
    int cchBuffer
    )
{
    if (!pBuffer || (cchBuffer <= 0))
    {
        return E_INVALIDARG;
    }

    return StringCchCopyW(pBuffer, cchBuffer, m_Text);
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::GetSubItemText

    Gets the text of the item as subitem with index zero
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::GetSubItemText(
    int Index,
    WCHAR* pBuffer,
    UINT cchBuffer
    )
{
    if (Index != 0)
    {
        return S_FALSE;
    }

    return GetText(pBuffer, cchBuffer);
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::GetHeight

    Gets the height of the item
------------------------------------------------------------------------------*/
BOOL
TextDisplayItem_t::GetHeight(
    UINT* pHeight
    )
{
    if (!pHeight)
    {
        return FALSE;
    }

    *pHeight = Layout_t::TextItemHeight();
    return TRUE;
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::NeedsToolTip

    Determines whether this item needs a tool tip or not
------------------------------------------------------------------------------*/
BOOL
TextDisplayItem_t::NeedsToolTip(
    RECT* pRectangle
    )
{
    if (!pRectangle)
    {
        ASSERT(0);
        return FALSE;
    }

    RECT CalculateRect = {0};
    PaintHelper_t::CalculateTextDimensions(
        m_Text,
        m_Text.length(),
        Fonts_t::InformationText(),
        &CalculateRect,
        DT_TOP | DT_LEFT | DT_NOPREFIX
        );

    return (RECTWIDTH(CalculateRect) >=
        RECTWIDTH(*pRectangle)-2*Layout_t::TextItemHorzMargin());
}

/*------------------------------------------------------------------------------
    TextDisplayItem_t::SetHighlightIndices

    Sets the indices for highlighting the string
------------------------------------------------------------------------------*/
HRESULT
TextDisplayItem_t::SetHighlightIndices(
    int Start,
    int End
    )
{
    m_HighlightStart = Start;
    m_HighlightEnd = End;
    return S_OK;
}

HRESULT DrawHighlightedText(
    HDC                    hdc,
    const WCHAR*           pText,
    INT                    cchText,
    const RECT*            prc,
    UINT                   dtFlags,
    const DRAW_HIGHLIGHTED_TEXT* pHighlightParams
    )
{
    PREFAST_ASSERT(prc && pText && pHighlightParams);

    if (dtFlags & DT_VCENTER)
    {
        ASSERT(! "This function won't allow vertical centering of text");
        dtFlags &= ~DT_VCENTER;
        dtFlags |= DT_LEFT;
    }
    
    HRESULT hr = S_OK;

    INT idxDraw = 0,
        cchDraw = (cchText > 0) ? cchText : wcslen(pText);

    RECT     rcDraw      = *prc;

    SIZE     sizeText;
    INT      cchSegment;
    BOOL     InsideHighlight;
    INT      bkOld;
    COLORREF crBkOld, crTxOld;
    
    while (idxDraw < cchDraw)
    {
        ZeroMemory(&sizeText, sizeof(SIZE));

        //We are inside the highlight zone, if the index to draw is the highlight starting index
        InsideHighlight = (idxDraw == pHighlightParams->idxHighlightStart);
        
        if (InsideHighlight)
        {
            //Set up the DC for highlight drawing
            bkOld   = SetBkMode   (hdc, pHighlightParams->bkModeHighlighted);
            crBkOld = SetBkColor  (hdc, pHighlightParams->crBkHighlighted  );
            crTxOld = SetTextColor(hdc, pHighlightParams->crTextHighlighted);

            //the lenght of the segment is the length of the highlight
            cchSegment  = pHighlightParams->idxHighlightEnd - pHighlightParams->idxHighlightStart + 1;
        }
        else
        {
            //otherwise - we're not in a highlight and the length of the segment is either
            //from [0 - idxHighlightStart] if we are before the highlight, 
            // OR all the way to the end of the string if we are after the highlight
            cchSegment = (idxDraw > pHighlightParams->idxHighlightEnd) ? -1 : pHighlightParams->idxHighlightStart;
        }

        //draw the text with the current dc
        hr = CommonUtilities_t::ToHR(::DrawText(
            hdc,
            pText + idxDraw,
            cchSegment,
            &rcDraw,
            dtFlags | (cchSegment == -1 ? DT_END_ELLIPSIS : 0)
            ));

        if (InsideHighlight)
        {
            //restore the dc if it was changed
            SetTextColor(hdc, crTxOld);
            SetBkMode   (hdc, bkOld  );
            SetBkColor  (hdc, crBkOld);
        }

        //figure out how far to move the rectangle for the next draw 
        if (SUCCEEDED(hr))
        {
            hr = CommonUtilities_t::ToHR(GetTextExtentPoint(
                hdc, 
                pText + idxDraw, 
                (cchSegment > 0) ? cchSegment : (cchDraw - idxDraw),
                &sizeText
                ));
        }

        if (FAILED(hr))
        {
            break;
        }

        //we've drawn to the end of the string
        if (cchSegment == -1)
        {
            break;
        }

        //adjust the rect
        rcDraw.left += sizeText.cx;
        idxDraw     += cchSegment;
    }

    return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -