|
3 | 3 |
|
4 | 4 | using System.ComponentModel;
|
5 | 5 | using System.Drawing;
|
| 6 | +using System.Drawing.Drawing2D; |
6 | 7 | using System.Drawing.Imaging;
|
7 | 8 | using System.Drawing.Text;
|
8 | 9 | using System.Windows.Forms.Layout;
|
@@ -1028,66 +1029,83 @@ private protected void OnRenderStatusStripSizingGrip(
|
1028 | 1029 | return;
|
1029 | 1030 | }
|
1030 | 1031 |
|
1031 |
| - Graphics g = eArgs.Graphics; |
1032 |
| - |
1033 |
| - // we have a set of stock rectangles. Translate them over to where the grip is to be drawn |
1034 |
| - // for the white set, then translate them up and right one pixel for the grey. |
1035 |
| - |
1036 | 1032 | if (eArgs.ToolStrip is not StatusStrip statusStrip)
|
1037 | 1033 | {
|
1038 | 1034 | return;
|
1039 | 1035 | }
|
1040 | 1036 |
|
1041 | 1037 | Rectangle sizeGripBounds = statusStrip.SizeGripBounds;
|
1042 |
| - |
1043 | 1038 | if (LayoutUtils.IsZeroWidthOrHeight(sizeGripBounds))
|
1044 | 1039 | {
|
1045 | 1040 | return;
|
1046 | 1041 | }
|
1047 | 1042 |
|
1048 |
| - Rectangle[] whiteRectangles = new Rectangle[s_baseSizeGripRectangles.Length]; |
1049 |
| - Rectangle[] greyRectangles = new Rectangle[s_baseSizeGripRectangles.Length]; |
| 1043 | + Graphics g = eArgs.Graphics; |
1050 | 1044 |
|
1051 |
| - for (int i = 0; i < s_baseSizeGripRectangles.Length; i++) |
| 1045 | + // Use device DPI for scaling |
| 1046 | + float dpiScale = 1.0f; |
| 1047 | + |
| 1048 | + if (statusStrip.DeviceDpi > 0 && ScaleHelper.IsThreadPerMonitorV2Aware) |
1052 | 1049 | {
|
1053 |
| - Rectangle baseRect = s_baseSizeGripRectangles[i]; |
| 1050 | + dpiScale = statusStrip.DeviceDpi / 96f; |
| 1051 | + } |
1054 | 1052 |
|
1055 |
| - if (statusStrip.RightToLeft == RightToLeft.Yes) |
1056 |
| - { |
1057 |
| - baseRect.X = sizeGripBounds.Width - baseRect.X - baseRect.Width; |
1058 |
| - } |
| 1053 | + // Scale the base rectangles for the grip dots |
| 1054 | + Rectangle[] scaledRects = new Rectangle[s_baseSizeGripRectangles.Length]; |
1059 | 1055 |
|
1060 |
| - // Height of pyramid (10px) + 2px padding from bottom. |
1061 |
| - baseRect.Offset( |
1062 |
| - x: sizeGripBounds.X, |
1063 |
| - y: sizeGripBounds.Bottom - 12); |
| 1056 | + for (int i = 0; i < s_baseSizeGripRectangles.Length; i++) |
| 1057 | + { |
| 1058 | + Rectangle r = s_baseSizeGripRectangles[i]; |
1064 | 1059 |
|
1065 |
| - whiteRectangles[i] = baseRect; |
| 1060 | + scaledRects[i] = new Rectangle( |
| 1061 | + (int)(r.X * dpiScale), |
| 1062 | + (int)(r.Y * dpiScale), |
| 1063 | + Math.Max((int)(r.Width * dpiScale), 2), |
| 1064 | + Math.Max((int)(r.Height * dpiScale), 2)); |
| 1065 | + } |
1066 | 1066 |
|
1067 |
| - int offset = -1 + GetCornerOffset(statusStrip); |
| 1067 | + SmoothingMode oldSmoothing = g.SmoothingMode; |
| 1068 | + g.SmoothingMode = SmoothingMode.AntiAlias; |
1068 | 1069 |
|
| 1070 | + int cornerOffset = GetCornerOffset(statusStrip); |
| 1071 | + |
| 1072 | + // Draw the grip dots, bottom-right aligned (mirrored for RTL) |
| 1073 | + foreach (Rectangle dotRect in scaledRects) |
| 1074 | + { |
| 1075 | + Rectangle actualRect; |
1069 | 1076 | if (statusStrip.RightToLeft == RightToLeft.Yes)
|
1070 | 1077 | {
|
1071 |
| - baseRect.Offset(1, -1 - offset); |
| 1078 | + actualRect = new Rectangle( |
| 1079 | + sizeGripBounds.Left + cornerOffset + dotRect.X, |
| 1080 | + sizeGripBounds.Bottom - cornerOffset - dotRect.Y - dotRect.Height, |
| 1081 | + dotRect.Width, |
| 1082 | + dotRect.Height); |
1072 | 1083 | }
|
1073 | 1084 | else
|
1074 | 1085 | {
|
1075 |
| - baseRect.Offset(-1, -1 - offset); |
| 1086 | + actualRect = new Rectangle( |
| 1087 | + sizeGripBounds.Right - cornerOffset - dotRect.X - dotRect.Width, |
| 1088 | + sizeGripBounds.Bottom - cornerOffset - dotRect.Y - dotRect.Height, |
| 1089 | + dotRect.Width, |
| 1090 | + dotRect.Height); |
1076 | 1091 | }
|
1077 | 1092 |
|
1078 |
| - greyRectangles[i] = baseRect; |
| 1093 | + // Highlight dot (top-left) |
| 1094 | + Rectangle highlightRect = actualRect; |
| 1095 | + highlightRect.Offset(-1, -1); |
| 1096 | + g.FillEllipse(highLightBrush, highlightRect); |
| 1097 | + |
| 1098 | + // Shadow dot (bottom-right) |
| 1099 | + Rectangle shadowRect = actualRect; |
| 1100 | + shadowRect.Offset(1, 1); |
| 1101 | + g.FillEllipse(shadowBrush, shadowRect); |
1079 | 1102 | }
|
1080 | 1103 |
|
1081 |
| - g.FillRectangles(highLightBrush, whiteRectangles); |
1082 |
| - g.FillRectangles(shadowBrush, greyRectangles); |
| 1104 | + g.SmoothingMode = oldSmoothing; |
1083 | 1105 |
|
1084 |
| - // We need to compensate for the rounded Window corners from Windows 11 on. |
1085 | 1106 | static int GetCornerOffset(StatusStrip statusStrip)
|
1086 | 1107 | {
|
1087 |
| - // If we're on Windows 11, offset slightly to avoid hitting rounded corners, |
1088 |
| - // _if_ we are at all dealing with rounded corners. |
1089 | 1108 | int cornerOffset = 0;
|
1090 |
| - |
1091 | 1109 | if (Environment.OSVersion.Version >= new Version(10, 0, 22000)
|
1092 | 1110 | && statusStrip.FindForm() is Form f)
|
1093 | 1111 | {
|
|
0 commit comments