1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "views/widget/aero_tooltip_manager.h"
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include "app/l10n_util_win.h"
#include "base/message_loop.h"
#include "gfx/point.h"
namespace views {
///////////////////////////////////////////////////////////////////////////////
// AeroTooltipManager, public:
AeroTooltipManager::AeroTooltipManager(Widget* widget)
: TooltipManagerWin(widget),
initial_delay_(0) {
}
AeroTooltipManager::~AeroTooltipManager() {
if (initial_timer_)
initial_timer_->Disown();
}
void AeroTooltipManager::OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param) {
if (initial_timer_)
initial_timer_->Disown();
if (u_msg == WM_MOUSEMOVE || u_msg == WM_NCMOUSEMOVE) {
gfx::Point mouse_pos(l_param);
if (u_msg == WM_NCMOUSEMOVE) {
// NC message coordinates are in screen coordinates.
POINT temp = mouse_pos.ToPOINT();
::MapWindowPoints(HWND_DESKTOP, GetParent(), &temp, 1);
mouse_pos.SetPoint(temp.x, temp.y);
}
if (last_mouse_pos_ != mouse_pos) {
last_mouse_pos_ = mouse_pos;
HideKeyboardTooltip();
UpdateTooltip(mouse_pos);
}
// Delay opening of the tooltip just in case the user moves their
// mouse to another control. We defer this from Init because we get
// zero if we query it too soon.
if (!initial_delay_) {
initial_delay_ = static_cast<int>(
::SendMessage(tooltip_hwnd_, TTM_GETDELAYTIME, TTDT_INITIAL, 0));
}
initial_timer_ = new InitialTimer(this);
initial_timer_->Start(initial_delay_);
} else {
// Hide the tooltip and cancel any timers.
::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
::SendMessage(tooltip_hwnd_, TTM_TRACKACTIVATE, false, (LPARAM)&toolinfo_);
return;
}
}
void AeroTooltipManager::OnMouseLeave() {
last_mouse_pos_.SetPoint(-1, -1);
UpdateTooltip();
}
///////////////////////////////////////////////////////////////////////////////
// AeroTooltipManager, private:
void AeroTooltipManager::Init() {
// Create the tooltip control.
tooltip_hwnd_ = CreateWindowEx(
WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(),
TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0,
GetParent(), NULL, NULL, NULL);
l10n_util::AdjustUIFontForWindow(tooltip_hwnd_);
// Add one tool that is used for all tooltips.
toolinfo_.cbSize = sizeof(toolinfo_);
// We use tracking tooltips on Vista to allow us to manually control the
// visibility of the tooltip.
toolinfo_.uFlags = TTF_TRANSPARENT | TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
toolinfo_.hwnd = GetParent();
toolinfo_.uId = (UINT_PTR)GetParent();
// Setting this tells windows to call GetParent() back (using a WM_NOTIFY
// message) for the actual tooltip contents.
toolinfo_.lpszText = LPSTR_TEXTCALLBACK;
SetRectEmpty(&toolinfo_.rect);
::SendMessage(tooltip_hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolinfo_);
}
void AeroTooltipManager::OnTimer() {
initial_timer_ = NULL;
POINT pt = last_mouse_pos_.ToPOINT();
::ClientToScreen(GetParent(), &pt);
// Set the position and visibility.
if (!tooltip_showing_) {
::SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0);
::SendMessage(tooltip_hwnd_, TTM_TRACKPOSITION, 0, MAKELPARAM(pt.x, pt.y));
::SendMessage(tooltip_hwnd_, TTM_TRACKACTIVATE, true, (LPARAM)&toolinfo_);
}
}
///////////////////////////////////////////////////////////////////////////////
// AeroTooltipManager::InitialTimer
AeroTooltipManager::InitialTimer::InitialTimer(AeroTooltipManager* manager)
: manager_(manager) {
}
void AeroTooltipManager::InitialTimer::Start(int time) {
MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
this, &InitialTimer::Execute), time);
}
void AeroTooltipManager::InitialTimer::Disown() {
manager_ = NULL;
}
void AeroTooltipManager::InitialTimer::Execute() {
if (manager_)
manager_->OnTimer();
}
} // namespace views
|