📄 tooltip.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 "ToolTip.hpp"
#include "Common.hpp"
#include "PaintHelper.hpp"
#include "Debug.hpp"
#include "Layout.hpp"
//constants
const UINT ToolTipImpl_t::sc_MaximumToolTipText = MAX_PATH;
/*------------------------------------------------------------------------------
ToolTipImpl_t::ToolTipImpl_t
Constructor
------------------------------------------------------------------------------*/
ToolTipImpl_t::ToolTipImpl_t(
)
{
TRACE(ZONE_COMMON_CTOR);
}
/*------------------------------------------------------------------------------
ToolTipImpl_t::~ToolTipImpl_t
Destructor
------------------------------------------------------------------------------*/
ToolTipImpl_t::~ToolTipImpl_t(
)
{
TRACE(ZONE_COMMON_CTOR);
}
/*------------------------------------------------------------------------------
ToolTipImpl_t::ControlWindowProc
Handle messages
------------------------------------------------------------------------------*/
LRESULT
ToolTipImpl_t::ControlWindowProc(
UINT Message,
WPARAM wParam,
LPARAM lParam,
bool& Handled
)
{
LRESULT Result;
//by default assume we handled the message
Handled = true;
switch (Message)
{
case WM_TOOLTIP_GETMETRICS:
return OnGetMetrics(
wParam,
reinterpret_cast<SIZE*>(lParam)
);
case WM_PAINT:
return OnPaint(reinterpret_cast<HDC>(wParam));
case WM_CLOSE:
Handled = ForwardMessageToParent(Message, wParam, lParam, &Result);
return Result;
default:
Handled = false;
return 0;
}
}
/*------------------------------------------------------------------------------
ToolTipImpl_t::OnPaint
Handles WM_PAINT. Paints the tool tip
------------------------------------------------------------------------------*/
LRESULT
ToolTipImpl_t::OnPaint(
HDC hdc
)
{
WCHAR TextBuffer[sc_MaximumToolTipText] = L"";
PaintHelper_t paint;
RECT ClientRect;
//start the painting operation
if (FAILED(paint.Attach(hdc)) &&
FAILED(paint.Begin(m_hwnd)))
{
return 0;
}
GetClientRect(m_hwnd, &ClientRect);
if (!m_BackgroundBrush)
{
m_BackgroundBrush = CreateSolidBrush(Colors_t::ToolTipBackgroundColor());
if (!m_BackgroundBrush)
{
return 0;
}
}
paint.SetBrush(m_BackgroundBrush);
//Draw the rectangle
Rectangle(
paint,
ClientRect.left,
ClientRect.top,
ClientRect.right,
ClientRect.bottom
);
//If there is a string to display
if (GetWindowText(m_hwnd, TextBuffer, _countof(TextBuffer)) > 0)
{
paint.SetBkMode(TRANSPARENT);
paint.SetFont(Fonts_t::StandardText());
paint.SetTextColor(Colors_t::ToolTipTextColor());
InflateRect(
&ClientRect,
-Layout_t::ToolTipTextMargin(),
-Layout_t::ToolTipTextMargin()
);
//force end ellipsis if the text reaches our limit...
if (GetWindowTextLength(m_hwnd) >= _countof(TextBuffer)-1)
{
StringCchCopy(
TextBuffer + (_countof(TextBuffer) - 4),
4,
L"..."
);
}
paint.DrawText(
TextBuffer,
-1,
&ClientRect,
(DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_EDITCONTROL | DT_END_ELLIPSIS)
);
}
paint.End();
return 0;
}
/*------------------------------------------------------------------------------
ToolTipImpl_t::OnGetMetrics
Handles VMSG_TOOLTIP_GETMETRICS - determines the necessary height and width
of this window using a maximum width
Modifies the size struct to
Parameters:
WPARAM: UINT - the MAX width
lParam: SIZE* - OUT param
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
ToolTipImpl_t::OnGetMetrics(
UINT MaximumWidth,
SIZE* pSize
)
{
if (!pSize)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
ZeroMemory(pSize, sizeof(*pSize));
WCHAR TextBuffer[sc_MaximumToolTipText] = L"";
if (GetWindowText(m_hwnd, TextBuffer, _countof(TextBuffer)) < 0)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
HRESULT hr;
RECT CalculateRect = {0};
//check first if we can draw on one line, use PaintHelper_t to calculate the width/height
hr = PaintHelper_t::CalculateTextDimensions(
TextBuffer,
-1,
Fonts_t::StandardText(),
&CalculateRect,
(DT_LEFT | DT_NOPREFIX | DT_SINGLELINE)
);
if (FAILED(hr))
{
ASSERT(FALSE);
return hr;
}
//does it fit on one line?
if (RECTWIDTH(CalculateRect) < (MaximumWidth - Layout_t::ToolTipItemDelta()))
{
//yes - it does! add space for the margins
CalculateRect.right += 2*Layout_t::ToolTipTextMargin();
}
else
{
//otherwise the width will be the max (- delta) and the height determined by PaintHelper_t
//Note: padding is cancelled by shrinking width first and then adding margins back,
//after calculation below
SetRect(
&CalculateRect,
0,
0,
MaximumWidth - 2*Layout_t::ToolTipTextMargin() - Layout_t::ToolTipItemDelta(),
0
);
hr = PaintHelper_t::CalculateTextDimensions(
TextBuffer,
-1,
Fonts_t::StandardText(),
&CalculateRect,
DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_EDITCONTROL
);
if (FAILED(hr))
{
ASSERT(FALSE);
return hr;
}
//reinflate the width to include the margins
CalculateRect.left = 0;
CalculateRect.right = MaximumWidth - Layout_t::ToolTipItemDelta();
}
pSize->cx = RECTWIDTH(CalculateRect);
pSize->cy = RECTHEIGHT(CalculateRect) + 2*Layout_t::ToolTipTextMargin();
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -