https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3e46a8673d7c82f42e381…
commit 3e46a8673d7c82f42e3819f56de8a91e16354010
Author: Carl J. Bialorucki <cbialo2(a)outlook.com>
AuthorDate: Thu Aug 10 09:21:03 2023 -0600
Commit: Stanislav Motylkov <x86corez(a)gmail.com>
CommitDate: Tue Oct 3 01:08:45 2023 +0300
[EXPLORER][COMCTL32] Fix balloon tooltips and system pager alerts (#5559)
- [EXPLORER] Set maximum balloon width for notification area
- [COMCTL32] Fix balloon tooltip shape
- Limit balloon tooltips from extending past the edges of the monitor, not the edges
of the work area.
- Instead of simply repositioning the main rectangle when the balloon is too far
towards one edge of the screen,
try flipping the balloon the other way. This is the same behavior as Windows Server
2003.
- Tweak some values used to draw the balloon tooltips to more closely follow the
Windows balloon tooltip style.
- Removing trailing whitespace.
- While the new changes are guarded, consider cancelling our Wine sync for common
controls.
Our common controls are responsible for many graphical issues and lack of features
throughout ReactOS.
CORE-19109
---
base/shell/explorer/syspager.cpp | 8 +++---
dll/win32/comctl32/tooltips.c | 54 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/base/shell/explorer/syspager.cpp b/base/shell/explorer/syspager.cpp
index 35eb0faf75f..b039f189101 100644
--- a/base/shell/explorer/syspager.cpp
+++ b/base/shell/explorer/syspager.cpp
@@ -21,6 +21,8 @@
#include "precomp.h"
+#define BALLOON_MAXWIDTH 340
+
struct InternalIconData : NOTIFYICONDATA
{
// Must keep a separate copy since the original is unioned with uTimeout.
@@ -617,19 +619,19 @@ void CBalloonQueue::Show(Info& info)
// TODO: NIF_REALTIME, NIIF_NOSOUND, other Vista+ flags
- const int index = IndexOf(info.pSource);
+ m_current = info.pSource;
RECT rc;
- m_toolbar->GetItemRect(index, &rc);
+ m_toolbar->GetItemRect(IndexOf(m_current), &rc);
m_toolbar->ClientToScreen(&rc);
const WORD x = (rc.left + rc.right) / 2;
const WORD y = (rc.top + rc.bottom) / 2;
m_tooltips->SetTitle(info.szInfoTitle, info.uIcon);
m_tooltips->TrackPosition(x, y);
+ m_tooltips->SetMaxTipWidth(BALLOON_MAXWIDTH);
m_tooltips->UpdateTipText(m_hwndParent,
reinterpret_cast<LPARAM>(m_toolbar->m_hWnd), info.szInfo);
m_tooltips->TrackActivate(m_hwndParent,
reinterpret_cast<LPARAM>(m_toolbar->m_hWnd));
- m_current = info.pSource;
int timeout = info.uTimeout;
if (timeout < MinTimeout) timeout = MinTimeout;
if (timeout > MaxTimeout) timeout = MaxTimeout;
diff --git a/dll/win32/comctl32/tooltips.c b/dll/win32/comctl32/tooltips.c
index 0d89a0256f9..8c8ef43eb08 100644
--- a/dll/win32/comctl32/tooltips.c
+++ b/dll/win32/comctl32/tooltips.c
@@ -162,10 +162,17 @@ typedef struct
#define BALLOON_TEXT_MARGIN (NORMAL_TEXT_MARGIN+8)
/* value used for CreateRoundRectRgn that specifies how much
* each corner is curved */
+#ifdef __REACTOS__
+#define BALLOON_ROUNDEDNESS 16
+#define BALLOON_STEMHEIGHT 18
+#define BALLOON_STEMWIDTH 18
+#define BALLOON_STEMINDENT 16
+#else
#define BALLOON_ROUNDEDNESS 20
#define BALLOON_STEMHEIGHT 13
#define BALLOON_STEMWIDTH 10
#define BALLOON_STEMINDENT 20
+#endif // __REACTOS__
#define BALLOON_ICON_TITLE_SPACING 8 /* horizontal spacing between icon and title */
#define BALLOON_TITLE_TEXT_SPACING 8 /* vertical spacing between icon/title and main text
*/
@@ -741,6 +748,40 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW( monitor, &mon_info );
+#ifdef __REACTOS__
+ if (rect.right > mon_info.rcMonitor.right)
+ {
+ rect.left -= size.cx - (BALLOON_STEMINDENT + BALLOON_STEMWIDTH);
+ rect.right -= size.cx - (BALLOON_STEMINDENT + BALLOON_STEMWIDTH);
+ if (rect.right > mon_info.rcMonitor.right)
+ {
+ rect.left -= (rect.right - mon_info.rcMonitor.right);
+ rect.right = mon_info.rcMonitor.right;
+ }
+ }
+
+ if (rect.left < mon_info.rcMonitor.left)
+ {
+ rect.right += abs(rect.left);
+ rect.left = 0;
+ }
+
+ if (rect.bottom > mon_info.rcMonitor.bottom)
+ {
+ RECT rc;
+ if (toolPtr->uFlags & TTF_IDISHWND)
+ {
+ GetWindowRect((HWND)toolPtr->uId, &rc);
+ }
+ else
+ {
+ rc = toolPtr->rect;
+ MapWindowPoints(toolPtr->hwnd, NULL, (LPPOINT)&rc, 2);
+ }
+ rect.bottom = rc.top - 2;
+ rect.top = rect.bottom - size.cy;
+ }
+#else
if( rect.right > mon_info.rcWork.right ) {
rect.left -= rect.right - mon_info.rcWork.right + 2;
rect.right = mon_info.rcWork.right - 2;
@@ -759,6 +800,7 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
rect.bottom = rc.top - 2;
rect.top = rect.bottom - size.cy;
}
+#endif // __REACTOS__
AdjustWindowRectEx (&rect, GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE),
FALSE, GetWindowLongW (infoPtr->hwndSelf, GWL_EXSTYLE));
@@ -775,7 +817,11 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
{
pts[0].x = ptfx;
pts[0].y = 0;
+#ifdef __REACTOS__
+ pts[1].x = max(BALLOON_STEMINDENT, ptfx - BALLOON_STEMWIDTH);
+#else
pts[1].x = max(BALLOON_STEMINDENT, ptfx - (BALLOON_STEMWIDTH / 2));
+#endif
pts[1].y = BALLOON_STEMHEIGHT;
pts[2].x = pts[1].x + BALLOON_STEMWIDTH;
pts[2].y = pts[1].y;
@@ -787,7 +833,11 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
}
else
{
+#ifdef __REACTOS__
+ pts[0].x = max(BALLOON_STEMINDENT, ptfx - BALLOON_STEMWIDTH);
+#else
pts[0].x = max(BALLOON_STEMINDENT, ptfx - (BALLOON_STEMWIDTH / 2));
+#endif
pts[0].y = (rect.bottom - rect.top) - BALLOON_STEMHEIGHT;
pts[1].x = pts[0].x + BALLOON_STEMWIDTH;
pts[1].y = pts[0].y;
@@ -805,7 +855,11 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
hRgn = CreateRoundRectRgn(0,
(infoPtr->bToolBelow ? BALLOON_STEMHEIGHT : 0),
rect.right - rect.left,
+#ifdef __REACTOS__
+ (infoPtr->bToolBelow ? rect.bottom - rect.top :
rect.bottom - rect.top - BALLOON_STEMHEIGHT + 1),
+#else
(infoPtr->bToolBelow ? rect.bottom - rect.top :
rect.bottom - rect.top - BALLOON_STEMHEIGHT),
+#endif
BALLOON_ROUNDEDNESS, BALLOON_ROUNDEDNESS);
CombineRgn(hRgn, hRgn, hrStem, RGN_OR);