📄 textdisplayitem.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 + -