diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCGIF.cs b/src/Common/src/Interop/ComCtl32/Interop.MCGIF.cs
new file mode 100644
index 00000000000..28581f27a5e
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCGIF.cs
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar Control Grid Info Flags.
+ /// Copied form CommCtrl.h
+ ///
+ [Flags]
+ public enum MCGIF
+ {
+ ///
+ /// Represetns MCGIF_DATE const.
+ ///
+ DATE = 0x00000001,
+
+ ///
+ /// Represents MCGIF_RECT cosnt.
+ ///
+ RECT = 0x00000002,
+
+ ///
+ /// Represetns MCGIF_NAME const.
+ ///
+ NAME = 0x00000004
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCGIP.cs b/src/Common/src/Interop/ComCtl32/Interop.MCGIP.cs
new file mode 100644
index 00000000000..adffede8f8e
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCGIP.cs
@@ -0,0 +1,61 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar control part constants.
+ /// Copied form CommCtrl.h
+ ///
+ public enum MCGIP : uint
+ {
+ ///
+ /// Represents MCGIP_CALENDARCONTROL const.
+ ///
+ CALENDARCONTROL = 0,
+
+ ///
+ /// Represents MCGIP_NEXT const.
+ ///
+ NEXT = 1,
+
+ ///
+ /// Represents MCGIP_PREV const.
+ ///
+ PREV = 2,
+
+ ///
+ /// Represents MCGIP_FOOTER const.
+ ///
+ FOOTER = 3,
+
+ ///
+ /// Represents MCGIP_CALENDAR const.
+ ///
+ CALENDAR = 4,
+
+ ///
+ /// Represents MCGIP_CALENDARHEADER const.
+ ///
+ CALENDARHEADER = 5,
+
+ ///
+ /// Represents MCGIP_CALENDARBODY const.
+ ///
+ CALENDARBODY = 6,
+
+ ///
+ /// Represents MCGIP_CALENDARROW const.
+ ///
+ CALENDARROW = 7,
+
+ ///
+ /// Represents MCGIP_CALENDARCELL const.
+ ///
+ CALENDARCELL = 8
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCGRIDINFO.cs b/src/Common/src/Interop/ComCtl32/Interop.MCGRIDINFO.cs
new file mode 100644
index 00000000000..6406b870904
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCGRIDINFO.cs
@@ -0,0 +1,37 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+using static System.Windows.Forms.NativeMethods;
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// MonthCalendar grid info structure.
+ /// Copied form CommCtrl.h
+ ///
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public unsafe struct MCGRIDINFO
+ {
+ public uint cbSize;
+ public MCGIP dwPart;
+ public MCGIF dwFlags;
+ public int iCalendar;
+ public int iRow;
+ public int iCol;
+ public bool bSelected;
+ public Kernel32.SYSTEMTIME stStart;
+ public Kernel32.SYSTEMTIME stEnd;
+ public RECT rc;
+ public string pszName;
+ public uint cchName;
+ }
+
+ [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
+ public extern static IntPtr SendMessage(HandleRef hWnd, int Msg, int wParam, [In, Out] ref MCGRIDINFO gridInfo);
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCHITTESTINFO.cs b/src/Common/src/Interop/ComCtl32/Interop.MCHITTESTINFO.cs
new file mode 100644
index 00000000000..c266ab9865c
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCHITTESTINFO.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ ///
+ ///
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct MCHITTESTINFO
+ {
+ public int cbSize;
+ public POINT pt;
+ public int uHit;
+ public Kernel32.SYSTEMTIME st;
+ public RECT rc;
+ public int iOffset;
+ public int iRow;
+ public int iCol;
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCHT.cs b/src/Common/src/Interop/ComCtl32/Interop.MCHT.cs
new file mode 100644
index 00000000000..78c666d79e7
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCHT.cs
@@ -0,0 +1,116 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar Control HitTest values.
+ /// Copied form CommCtrl.h
+ ///
+ public enum MCHT
+ {
+ ///
+ /// MCHT_TITLE
+ ///
+ TITLE = 0x00010000,
+
+ ///
+ /// Represents MCHT_CALENDAR const.
+ ///
+ CALENDAR = 0x00020000,
+
+ ///
+ /// Represents MCHT_TODAYLINK const.
+ ///
+ TODAYLINK = 0x00030000,
+
+ ///
+ /// Represents MCHT_CALENDARCONTROL const.
+ ///
+ CALENDARCONTROL = 0x00100000,
+
+ ///
+ /// Represents MCHT_NEXT const.
+ ///
+ NEXT = 0x01000000,
+
+ ///
+ /// Represents MCHT_PREV const.
+ ///
+ PREV = 0x02000000,
+
+ ///
+ /// Represents MCHT_NOWHERE const.
+ ///
+ NOWHERE = 0x00000000,
+
+ ///
+ /// Represents MCHT_TITLEBK const.
+ ///
+ TITLEBK = TITLE,
+
+ ///
+ /// Represents MCHT_TITLEMONTH const.
+ ///
+ TITLEMONTH = TITLE | 0x0001,
+
+ ///
+ /// Represents MCHT_TITLEYEAR const.
+ ///
+ TITLEYEAR = TITLE | 0x0002,
+
+ ///
+ /// Represents MCHT_TITLEBTNNEXT const.
+ ///
+ TITLEBTNNEXT = TITLE | NEXT | 0x0003,
+
+ ///
+ /// Represents MCHT_TITLEBTNPREV const.
+ ///
+ TITLEBTNPREV = TITLE | PREV | 0x0003,
+
+ ///
+ /// Represents MCHT_CALENDARBK const.
+ ///
+ CALENDARBK = CALENDAR,
+
+ ///
+ /// Represents MCHT_CALENDARDATE const.
+ ///
+ CALENDARDATE = CALENDAR | 0x0001,
+
+ ///
+ /// Represents MCHT_CALENDARDATENEXT const.
+ ///
+ CALENDARDATENEXT = CALENDARDATE | NEXT,
+
+ ///
+ /// Represents MCHT_CALENDARDATEPREV const.
+ ///
+ CALENDARDATEPREV = CALENDARDATE | PREV,
+
+ ///
+ /// Represents MCHT_CALENDARDAY const.
+ ///
+ CALENDARDAY = CALENDAR | 0x0002,
+
+ ///
+ /// Represents MCHT_CALENDARWEEKNUM const.
+ ///
+ CALENDARWEEKNUM = CALENDAR | 0x0003,
+
+ ///
+ /// Represents MCHT_CALENDARDATEMIN const.
+ ///
+ CALENDARDATEMIN = CALENDAR | 0x0004,
+
+ ///
+ /// Represents MCHT_CALENDARDATEMAX const.
+ ///
+ CALENDARDATEMAX = CALENDAR | 0x0005
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCM.cs b/src/Common/src/Interop/ComCtl32/Interop.MCM.cs
new file mode 100644
index 00000000000..9547c236941
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCM.cs
@@ -0,0 +1,101 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar Control Messages.
+ /// Copied form CommCtrl.h
+ ///
+ public enum MCM
+ {
+ ///
+ /// Represents MCM_FIRST const.
+ ///
+ FIRST = 0x1000,
+
+ ///
+ /// Represents MCM_GETCURSEL const.
+ ///
+ GETCURSEL = FIRST + 1,
+
+ ///
+ /// Represents MCM_SETMAXSELCOUNT const.
+ ///
+ SETMAXSELCOUNT = FIRST + 4,
+
+ ///
+ /// Represents MCM_GETSELRANGE const.
+ ///
+ GETSELRANGE = FIRST + 5,
+
+ ///
+ /// Represents MCM_SETSELRANGE const.
+ ///
+ SETSELRANGE = FIRST + 6,
+
+ ///
+ /// Represents MCM_GETMONTHRANGE const.
+ ///
+ GETMONTHRANGE = FIRST + 7,
+
+ ///
+ /// Represents MCM_GETMINREQRECT const.
+ ///
+ GETMINREQRECT = FIRST + 9,
+
+ ///
+ /// Represents MCM_SETCOLOR const.
+ ///
+ SETCOLOR = FIRST + 10,
+
+ ///
+ /// Represents MCM_SETTODAY const.
+ ///
+ SETTODAY = FIRST + 12,
+
+ ///
+ /// Represents MCM_GETTODAY const.
+ ///
+ GETTODAY = FIRST + 13,
+
+ ///
+ /// Represents MCM_HITTEST const.
+ ///
+ HITTEST = FIRST + 14,
+
+ ///
+ /// Represents MCM_SETFIRSTDAYOFWEEK const.
+ ///
+ SETFIRSTDAYOFWEEK = FIRST + 15,
+
+ ///
+ /// Represents MCM_GETRANGE const.
+ ///
+ GETRANGE = FIRST + 17,
+
+ ///
+ /// Represents MCM_SETRANGE const.
+ ///
+ SETRANGE = FIRST + 18,
+
+ ///
+ /// Represents MCM_SETMONTHDELTA const.
+ ///
+ SETMONTHDELTA = FIRST + 20,
+
+ ///
+ /// Represents MCM_GETMAXTODAYWIDTH const.
+ ///
+ GETMAXTODAYWIDTH = FIRST + 21,
+
+ ///
+ /// Represents MCM_GETCALENDARGRIDINFO const.
+ ///
+ GETCALENDARGRIDINFO = FIRST + 24
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCS.cs b/src/Common/src/Interop/ComCtl32/Interop.MCS.cs
new file mode 100644
index 00000000000..78b739dfa22
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCS.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar Control styles constatnts.
+ /// Copied form CommCtrl.h
+ ///
+ public enum MCS
+ {
+ ///
+ /// Represents MCS_DAYSTATE const.
+ ///
+ DAYSTATE = 0x0001,
+
+ ///
+ /// Represents MCS_MULTISELECT const.
+ ///
+ MULTISELECT = 0x0002,
+
+ ///
+ /// Represents MCS_WEEKNUMBERS const.
+ ///
+ WEEKNUMBERS = 0x0004,
+
+ ///
+ /// Represents MCS_NOTODAYCIRCLE const.
+ ///
+ NOTODAYCIRCLE = 0x0008,
+
+ ///
+ /// Represents MCS_NOTODAY const.
+ ///
+ NOTODAY = 0x0010
+ }
+ }
+}
diff --git a/src/Common/src/Interop/ComCtl32/Interop.MCSC.cs b/src/Common/src/Interop/ComCtl32/Interop.MCSC.cs
new file mode 100644
index 00000000000..e0a51e8c028
--- /dev/null
+++ b/src/Common/src/Interop/ComCtl32/Interop.MCSC.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class ComCtl32
+ {
+ ///
+ /// Represents MonthCalendar control size and color constants.
+ /// Copied form CommCtrl.h
+ ///
+ public enum MCSC
+ {
+ ///
+ /// Represents MCSC_BACKGROUND const.
+ ///
+ BACKGROUND = 0,
+
+ ///
+ /// Represents MCSC_TEXT const.
+ ///
+ TEXT = 1,
+
+ ///
+ /// Represents MCSC_TITLEBK const.
+ ///
+ TITLEBK = 2,
+
+ ///
+ /// Represents MCSC_TITLETEXT const.
+ ///
+ TITLETEXT = 3,
+
+ ///
+ /// Represents MCSC_MONTHBK const.
+ ///
+ MONTHBK = 4,
+
+ ///
+ /// Represents MCSC_TRAILINGTEXT const.
+ ///
+ TRAILINGTEXT = 5
+ }
+ }
+}
diff --git a/src/Common/src/Interop/Interop.POINT.cs b/src/Common/src/Interop/Interop.POINT.cs
new file mode 100644
index 00000000000..4166f242fef
--- /dev/null
+++ b/src/Common/src/Interop/Interop.POINT.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Drawing;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ ///
+ /// Represetns the point structure.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct POINT
+ {
+ internal int x;
+ internal int y;
+
+ internal POINT(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ static public explicit operator POINT(Point pt)
+ {
+ return checked(new POINT((int)pt.X, (int)pt.Y));
+ }
+ }
+}
diff --git a/src/Common/src/Interop/Kernel32/Interop.SYSTEMTIME.cs b/src/Common/src/Interop/Kernel32/Interop.SYSTEMTIME.cs
new file mode 100644
index 00000000000..965b081789d
--- /dev/null
+++ b/src/Common/src/Interop/Kernel32/Interop.SYSTEMTIME.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ public struct SYSTEMTIME
+ {
+ public short wYear;
+ public short wMonth;
+ public short wDayOfWeek;
+ public short wDay;
+ public short wHour;
+ public short wMinute;
+ public short wSecond;
+ public short wMilliseconds;
+ }
+ }
+}
diff --git a/src/Common/src/Interop/User32/Interop.MOUSEEVENTF.cs b/src/Common/src/Interop/User32/Interop.MOUSEEVENTF.cs
new file mode 100644
index 00000000000..40955b96df1
--- /dev/null
+++ b/src/Common/src/Interop/User32/Interop.MOUSEEVENTF.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+internal static partial class Interop
+{
+ internal static partial class User32
+ {
+ [Flags]
+ public enum MOUSEEVENTF : uint
+ {
+ MOVE = 0x0001,
+ LEFTDOWN = 0x0002,
+ LEFTUP = 0x0004,
+ RIGHTDOWN = 0x0008,
+ RIGHTUP = 0x0010,
+ MIDDLEDOWN = 0x0020,
+ MIDDLEUP = 0x0040,
+ XDOWN = 0x0080,
+ XUP = 0x0100,
+ WHEEL = 0x0800,
+ HWHEEL = 0x1000,
+ MOVE_NOCOALESCE = 0x2000,
+ VIRTUALDESK = 0x4000,
+ ABSOLUTE = 0x8000,
+ }
+ }
+}
diff --git a/src/Common/src/NativeMethods.cs b/src/Common/src/NativeMethods.cs
index c847ad317fc..51a7c0ef19b 100644
--- a/src/Common/src/NativeMethods.cs
+++ b/src/Common/src/NativeMethods.cs
@@ -852,48 +852,15 @@ public static int MAKELCID(int lgid, int sort)
MDITILE_VERTICAL = 0x0000,
MDITILE_HORIZONTAL = 0x0001,
MDITILE_SKIPDISABLED = 0x0002,
- MCM_SETMAXSELCOUNT = (0x1000 + 4),
- MCM_SETSELRANGE = (0x1000 + 6),
- MCM_GETMONTHRANGE = (0x1000 + 7),
- MCM_GETMINREQRECT = (0x1000 + 9),
- MCM_SETCOLOR = (0x1000 + 10),
- MCM_SETTODAY = (0x1000 + 12),
- MCM_GETTODAY = (0x1000 + 13),
- MCM_HITTEST = (0x1000 + 14),
- MCM_SETFIRSTDAYOFWEEK = (0x1000 + 15),
- MCM_SETRANGE = (0x1000 + 18),
- MCM_SETMONTHDELTA = (0x1000 + 20),
- MCM_GETMAXTODAYWIDTH = (0x1000 + 21),
- MCHT_TITLE = 0x00010000,
- MCHT_CALENDAR = 0x00020000,
- MCHT_TODAYLINK = 0x00030000,
- MCHT_TITLEBK = (0x00010000),
- MCHT_TITLEMONTH = (0x00010000 | 0x0001),
- MCHT_TITLEYEAR = (0x00010000 | 0x0002),
- MCHT_TITLEBTNNEXT = (0x00010000 | 0x01000000 | 0x0003),
- MCHT_TITLEBTNPREV = (0x00010000 | 0x02000000 | 0x0003),
- MCHT_CALENDARBK = (0x00020000),
- MCHT_CALENDARDATE = (0x00020000 | 0x0001),
- MCHT_CALENDARDATENEXT = ((0x00020000 | 0x0001) | 0x01000000),
- MCHT_CALENDARDATEPREV = ((0x00020000 | 0x0001) | 0x02000000),
- MCHT_CALENDARDAY = (0x00020000 | 0x0002),
- MCHT_CALENDARWEEKNUM = (0x00020000 | 0x0003),
- MCSC_TEXT = 1,
- MCSC_TITLEBK = 2,
- MCSC_TITLETEXT = 3,
- MCSC_MONTHBK = 4,
- MCSC_TRAILINGTEXT = 5,
+
MCN_VIEWCHANGE = (0 - 750), // MCN_SELECT -4 - give state of calendar view
MCN_SELCHANGE = ((0 - 750) + 1),
MCN_GETDAYSTATE = ((0 - 750) + 3),
MCN_SELECT = ((0 - 750) + 4),
- MCS_DAYSTATE = 0x0001,
- MCS_MULTISELECT = 0x0002,
- MCS_WEEKNUMBERS = 0x0004,
- MCS_NOTODAYCIRCLE = 0x0008,
- MCS_NOTODAY = 0x0010,
+
MSAA_MENU_SIG = (unchecked((int)0xAA0DF00D));
+
public const int NIM_ADD = 0x00000000,
NIM_MODIFY = 0x00000001,
NIM_DELETE = 0x00000002,
@@ -2707,27 +2674,6 @@ public class Ole
public const int PICTYPE_ENHMETAFILE = 4;
}
- [StructLayout(LayoutKind.Sequential)]
- public class SYSTEMTIME
- {
- public short wYear;
- public short wMonth;
- public short wDayOfWeek;
- public short wDay;
- public short wHour;
- public short wMinute;
- public short wSecond;
- public short wMilliseconds;
-
- public override string ToString()
- {
- return "[SYSTEMTIME: "
- + wDay.ToString(CultureInfo.InvariantCulture) + "/" + wMonth.ToString(CultureInfo.InvariantCulture) + "/" + wYear.ToString(CultureInfo.InvariantCulture)
- + " " + wHour.ToString(CultureInfo.InvariantCulture) + ":" + wMinute.ToString(CultureInfo.InvariantCulture) + ":" + wSecond.ToString(CultureInfo.InvariantCulture)
- + "]";
- }
- }
-
[StructLayout(LayoutKind.Sequential)]
public class COMRECT
{
@@ -3745,36 +3691,19 @@ public struct NMCUSTOMDRAW
public IntPtr lItemlParam;
}
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- public class MCHITTESTINFO
- {
- public int cbSize = Marshal.SizeOf();
- public int pt_x = 0;
- public int pt_y = 0;
- public int uHit = 0;
- public short st_wYear = 0;
- public short st_wMonth = 0;
- public short st_wDayOfWeek = 0;
- public short st_wDay = 0;
- public short st_wHour = 0;
- public short st_wMinute = 0;
- public short st_wSecond = 0;
- public short st_wMilliseconds = 0;
- }
-
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class NMSELCHANGE
{
public NMHDR nmhdr;
- public SYSTEMTIME stSelStart = null;
- public SYSTEMTIME stSelEnd = null;
+ public Interop.Kernel32.SYSTEMTIME stSelStart;
+ public Interop.Kernel32.SYSTEMTIME stSelEnd;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class NMDAYSTATE
{
public NMHDR nmhdr;
- public SYSTEMTIME stStart = null;
+ public Interop.Kernel32.SYSTEMTIME stStart;
public int cDayState = 0;
public IntPtr prgDayState;
}
@@ -4033,7 +3962,7 @@ public class NMDATETIMECHANGE
{
public NMHDR nmhdr;
public int dwFlags = 0;
- public SYSTEMTIME st = null;
+ public Interop.Kernel32.SYSTEMTIME st;
}
[StructLayout(LayoutKind.Sequential)]
@@ -4093,6 +4022,8 @@ public struct HARDWAREINPUT
public short wParamH;
}
+ public const int INPUT_MOUSE = 0;
+
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
diff --git a/src/Common/src/UnsafeNativeMethods.cs b/src/Common/src/UnsafeNativeMethods.cs
index bcd7a32c855..a8c89992027 100644
--- a/src/Common/src/UnsafeNativeMethods.cs
+++ b/src/Common/src/UnsafeNativeMethods.cs
@@ -316,6 +316,9 @@ public static StringBuilder GetModuleFileNameLongPath(HandleRef hModule)
[DllImport(ExternDll.User32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint SendInput(uint nInputs, NativeMethods.INPUT[] pInputs, int cbSize);
+ [DllImport(ExternDll.User32, SetLastError = true)]
+ internal static extern int SendInput(int nInputs, ref NativeMethods.INPUT input, int cbSize);
+
#endregion
[DllImport(ExternDll.User32, ExactSpelling = true)]
@@ -568,10 +571,10 @@ public static StringBuilder GetModuleFileNameLongPath(HandleRef hModule)
// For MonthCalendar
//
[DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, NativeMethods.MCHITTESTINFO lParam);
+ public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref Interop.ComCtl32.MCHITTESTINFO lParam);
[DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, NativeMethods.SYSTEMTIME lParam);
+ public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref Interop.Kernel32.SYSTEMTIME lParam);
[DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, NativeMethods.SYSTEMTIMEARRAY lParam);
@@ -1110,8 +1113,8 @@ int GetExtendedControl(
[PreserveSig]
Interop.HRESULT TransformCoords(
- Point *pPtlHimetric,
- PointF *pPtfContainer,
+ Point* pPtlHimetric,
+ PointF* pPtfContainer,
uint dwFlags);
[PreserveSig]
@@ -2832,7 +2835,7 @@ Interop.HRESULT GetExtent(
uint dwDrawAspect,
int lindex,
NativeMethods.tagDVTARGETDEVICE ptd,
- Size *lpsizel);
+ Size* lpsizel);
}
[ComImport(), Guid("0000010C-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
@@ -4694,5 +4697,8 @@ public interface IScrollItemProvider
///
void ScrollIntoView();
}
+
+ [DllImport(ExternDll.User32, CharSet = CharSet.Auto, ExactSpelling = true, SetLastError = true)]
+ internal static extern bool GetPhysicalCursorPos([In, Out] ref Interop.POINT pt);
}
}
diff --git a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj
index d935ace9788..372cdae3327 100644
--- a/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj
+++ b/src/System.Windows.Forms.Design/src/System.Windows.Forms.Design.csproj
@@ -44,10 +44,15 @@
+
+
+
+
+
@@ -55,6 +60,7 @@
+
diff --git a/src/System.Windows.Forms/src/Resources/SR.resx b/src/System.Windows.Forms/src/Resources/SR.resx
index c361074b762..8768e3d9f78 100644
--- a/src/System.Windows.Forms/src/Resources/SR.resx
+++ b/src/System.Windows.Forms/src/Resources/SR.resx
@@ -4511,6 +4511,9 @@ Stack trace where the illegal operation occurred was:
Indicates which annual dates should be boldface.
+
+ Calendar body
+
The number of rows and columns of months in a month calendar.
@@ -4541,12 +4544,18 @@ Stack trace where the illegal operation occurred was:
Indicates which monthly dates to bold.
+
+ Next
+
Occurs when the range of dates changes due to user selection, or through next/previous month navigation.
Occurs when the user selects a date or a range of dates.
+
+ Previous
+
Unable to set the MonthCalendar range from {0} to {1}.
@@ -4580,6 +4589,9 @@ Stack trace where the illegal operation occurred was:
The color used to display text within the calendar's title.
+
+ Today: {0}
+
The current day.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf
index 86ea6478f3f..6d7fda9be24 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf
@@ -7481,6 +7481,11 @@ Trasování zásobníku, kde došlo k neplatné operaci:
Určuje, která data v rámci roku mají být zobrazena tučně.
+
+
+ Calendar body
+
+
Počet řádků a sloupců měsíců v měsíčním kalendáři.
@@ -7531,6 +7536,11 @@ Trasování zásobníku, kde došlo k neplatné operaci:
Určuje, která data v rámci měsíce mají být zobrazena tučně.
+
+
+ Next
+
+
Vyvolá se v případě, že se rozsah dat změní z důvodu výběru uživatele nebo prostřednictvím přechodu na další nebo předchozí měsíc.
@@ -7541,6 +7551,11 @@ Trasování zásobníku, kde došlo k neplatné operaci:
Vyvolá se v případě, že uživatel vybere datum nebo rozsah dat.
+
+
+ Previous
+
+
Rozsah objektu MonthCalendar nelze nastavit od {0} do {1}.
@@ -7616,6 +7631,11 @@ Trasování zásobníku, kde došlo k neplatné operaci:
Barva pozadí použitá k zobrazení textu v nadpisu kalendáře.
+
+
+ Today: {0}
+
+
Aktuální den
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf
index e889c39c5f1..6ed0b5852f9 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf
@@ -7481,6 +7481,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat:
Gibt an, welche jährlichen Tage fett angezeigt werden sollen.
+
+
+ Calendar body
+
+
Die Anzahl der Spalten und Zeilen von Monaten in einem Monatskalender.
@@ -7531,6 +7536,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat:
Gibt an, welche monatlichen Daten fett angezeigt werden sollen.
+
+
+ Next
+
+
Tritt ein, wenn sich der Datumsbereich aufgrund einer Benutzerauswahl oder einer Navigation zum nächsten oder vorherigen Monat ändert.
@@ -7541,6 +7551,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat:
Tritt ein, wenn der Benutzer ein Datum oder einen Datumsbereich auswählt.
+
+
+ Previous
+
+
Der MonthCalendar-Bereich kann nicht auf {0} bis {1} festgelegt werden.
@@ -7616,6 +7631,11 @@ Stapelüberwachung, in der der unzulässige Vorgang auftrat:
Die Farbe, in der der Text in der Kalenderüberschrift angezeigt wird.
+
+
+ Today: {0}
+
+
Der aktuelle Tag.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf
index 3a7e21ada46..22274f5b853 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf
@@ -7481,6 +7481,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue:
Indica qué fechas anuales se deben poner en negrita.
+
+
+ Calendar body
+
+
Número de filas y columnas de meses en un calendario mensual.
@@ -7531,6 +7536,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue:
Indica qué fechas mensuales deben aparecer en negrita.
+
+
+ Next
+
+
Tiene lugar cuando cambia el intervalo de fechas debido a una selección del usuario, o por navegación al mes anterior o posterior.
@@ -7541,6 +7551,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue:
Tiene lugar cuando el usuario selecciona una fecha o intervalo de fechas.
+
+
+ Previous
+
+
No se puede establecer el intervalo del elemento MonthCalendar entre {0} y {1}.
@@ -7616,6 +7631,11 @@ El seguimiento de la pila donde tuvo lugar la operación no válida fue:
Color utilizado para mostrar texto en el título del calendario.
+
+
+ Today: {0}
+
+
Día actual.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf
index 36e25c88ec6..1725c6476fb 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf
@@ -7481,6 +7481,11 @@ Cette opération non conforme s'est produite sur la trace de la pile :
Indique les dates annuelles à mettre en gras.
+
+
+ Calendar body
+
+
Le nombre de lignes et de colonnes de mois dans un calendrier mensuel.
@@ -7531,6 +7536,11 @@ Cette opération non conforme s'est produite sur la trace de la pile :
Indique les dates mensuelles à mettre en gras.
+
+
+ Next
+
+
Se produit lorsque la plage de dates change en raison d'une sélection de l'utilisateur ou lors de l'utilisation de la navigation entre les mois.
@@ -7541,6 +7551,11 @@ Cette opération non conforme s'est produite sur la trace de la pile :
Se produit lorsqu'un utilisateur sélectionne une date ou une plage de dates.
+
+
+ Previous
+
+
Impossible de définir la plage MonthCalendar de {0} à {1}.
@@ -7616,6 +7631,11 @@ Cette opération non conforme s'est produite sur la trace de la pile :
La couleur utilisée pour afficher le texte dans le titre du calendrier.
+
+
+ Today: {0}
+
+
Le jour actuel.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf
index ac861493d42..a9eb773e9ce 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf
@@ -7481,6 +7481,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida:
Indica le date dell'anno da visualizzare in grassetto.
+
+
+ Calendar body
+
+
Numero di righe e colonne dei mesi in un calendario mensile.
@@ -7531,6 +7536,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida:
Indica le date mensili da visualizzare in grassetto.
+
+
+ Next
+
+
Generato quando l'intervallo delle date cambia in seguito alla selezione dell'utente o alla navigazione al mese precedente o successivo.
@@ -7541,6 +7551,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida:
Generato quando l'utente seleziona una data o un intervallo di date.
+
+
+ Previous
+
+
Impossibile impostare l'intervallo di MonthCalendar da {0} a {1}.
@@ -7616,6 +7631,11 @@ Traccia dello stack da cui si è verificata l'operazione non valida:
Colore utilizzato per visualizzare il testo del titolo del calendario.
+
+
+ Today: {0}
+
+
La data odierna.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf
index f9eb1adb976..16c293aeab7 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf
@@ -7481,6 +7481,11 @@ Stack trace where the illegal operation occurred was:
年間のどの日付を太字にするかを示します。
+
+
+ Calendar body
+
+
月表示カレンダーの月の行と列の数です。
@@ -7531,6 +7536,11 @@ Stack trace where the illegal operation occurred was:
月ごとに太字で表示する日付を示します。
+
+
+ Next
+
+
ユーザーの選択、または翌/先月の変更により、日にちの範囲が変更されたときに発生します。
@@ -7541,6 +7551,11 @@ Stack trace where the illegal operation occurred was:
ユーザーがある日付を選択したとき、または日数の範囲を指定したときに発生します。
+
+
+ Previous
+
+
MonthCalendar の範囲を {0} から {1} に設定できません。
@@ -7616,6 +7631,11 @@ Stack trace where the illegal operation occurred was:
カレンダーの表題内のテキストの色です。
+
+
+ Today: {0}
+
+
現在の日です。
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf
index 3d56ca01edd..d35c34c5a4a 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf
@@ -7481,6 +7481,11 @@ Stack trace where the illegal operation occurred was:
매년 굵게 표시할 날짜를 나타냅니다.
+
+
+ Calendar body
+
+
달력에서 달의 행 및 열 개수입니다.
@@ -7531,6 +7536,11 @@ Stack trace where the illegal operation occurred was:
매월 굵게 표시할 날짜를 나타냅니다.
+
+
+ Next
+
+
사용자 선택이나 달 탐색으로 인해 날짜 범위가 변경될 때 발생합니다.
@@ -7541,6 +7551,11 @@ Stack trace where the illegal operation occurred was:
날짜 또는 날짜 범위를 선택할 때 발생합니다.
+
+
+ Previous
+
+
MonthCalendar의 범위를 {0}에서 {1} 사이로 설정할 수 없습니다.
@@ -7616,6 +7631,11 @@ Stack trace where the illegal operation occurred was:
달력 제목의 텍스트를 표시하는 데 사용할 색입니다.
+
+
+ Today: {0}
+
+
현재 날짜입니다.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf
index 897c72a4910..b82077fa54b 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf
@@ -7481,6 +7481,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja:
Wskazuje, które daty lat mają być pogrubione.
+
+
+ Calendar body
+
+
Liczba wierszy i kolumn miesięcy w kalendarzu miesięcznym.
@@ -7531,6 +7536,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja:
Wskazuje, które dni miesiąca mają zostać pogrubione.
+
+
+ Next
+
+
Występuje, gdy zakres dat zmieni się w wyniku zaznaczenia przez użytkownika lub przez nawigację do następnego/poprzedniego miesiąca.
@@ -7541,6 +7551,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja:
Występuje, gdy użytkownik zaznaczy datę lub zakres dat.
+
+
+ Previous
+
+
Nie można ustawić zakresu formantu MonthCalendar od {0} do {1}.
@@ -7616,6 +7631,11 @@ Stos śledzenia, w którym wystąpiła zabroniona operacja:
Kolor używany do wyświetlania tekstu w tytule kalendarza.
+
+
+ Today: {0}
+
+
Bieżący dzień.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf
index ffc28652938..450da311f21 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf
@@ -7481,6 +7481,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu:
Indica as datas do ano que devem ser exibidas em negrito.
+
+
+ Calendar body
+
+
O número de linhas e colunas dos meses em um calendário mensal.
@@ -7531,6 +7536,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu:
Indica as datas mensais que devem ser exibidas em negrito.
+
+
+ Next
+
+
Ocorre quando o intervalo de datas é alterado devido à seleção de usuário ou através de navegação para o mês seguinte/anterior.
@@ -7541,6 +7551,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu:
Ocorre quando o usuário seleciona uma data ou um intervalo de datas.
+
+
+ Previous
+
+
Não é possível definir o intervalo de MonthCalendar de {0} a {1}.
@@ -7616,6 +7631,11 @@ Rastreamento de pilha em que a operação ilegal ocorreu:
A cor usada para exibir texto no título do calendário.
+
+
+ Today: {0}
+
+
O dia atual.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf
index ad57689dd7d..6bdc33c51b0 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf
@@ -7482,6 +7482,11 @@ Stack trace where the illegal operation occurred was:
Показывает, будут ли даты отображаться жирным шрифтом.
+
+
+ Calendar body
+
+
Число строк и столбцов для месяца в месячном календаре.
@@ -7532,6 +7537,11 @@ Stack trace where the illegal operation occurred was:
Указывает, какие числа месяца выделять жирным шрифтом.
+
+
+ Next
+
+
Происходит при изменении пользователем выбранного диапазона дат путем выделения или выбора предыдущего/следующего месяца.
@@ -7542,6 +7552,11 @@ Stack trace where the illegal operation occurred was:
Происходит при выборе пользователем даты или диапазона дат.
+
+
+ Previous
+
+
Невозможно установить диапазон MonthCalendar от {0} до {1}.
@@ -7617,6 +7632,11 @@ Stack trace where the illegal operation occurred was:
Цвет для отображения текста в заглавии календаря.
+
+
+ Today: {0}
+
+
Текущая дата.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf
index 323556ca24b..5cef44e49f3 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf
@@ -7481,6 +7481,11 @@ Geçersiz işlemin gerçekleştiği yığın izi:
Yıl içinde hangi tarihlerin kalın görüntülenmesi gerektiğini gösterir.
+
+
+ Calendar body
+
+
Aylık takvimde ayların gösterileceği satır ve sütun sayısı.
@@ -7531,6 +7536,11 @@ Geçersiz işlemin gerçekleştiği yığın izi:
Ayın hangi günlerinin kalın görüntüleneceğini gösterir.
+
+
+ Next
+
+
Kullanıcı seçimi veya takvimde önceki/sonraki aya gitme dolayısıyla tarih aralıkları değiştiğinde gerçekleşir.
@@ -7541,6 +7551,11 @@ Geçersiz işlemin gerçekleştiği yığın izi:
Kullanıcı bir tarih veya tarih aralığı seçtiğinde gerçekleşir.
+
+
+ Previous
+
+
MonthCalendar aralığı {0} değerinden {1} değerine ayarlanamıyor.
@@ -7616,6 +7631,11 @@ Geçersiz işlemin gerçekleştiği yığın izi:
Takvim başlığında metin görüntülemek için kullanılan renk.
+
+
+ Today: {0}
+
+
Geçerli gün.
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf
index a6c1e634abf..063940c042d 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf
@@ -7481,6 +7481,11 @@ Stack trace where the illegal operation occurred was:
指示一年中用粗体显示的日期。
+
+
+ Calendar body
+
+
月历中各月的行数和列数。
@@ -7531,6 +7536,11 @@ Stack trace where the illegal operation occurred was:
指示一月中要用粗体显示的日期。
+
+
+ Next
+
+
在因用户选择或通过下个月/上个月导航而导致日期范围更改时发生。
@@ -7541,6 +7551,11 @@ Stack trace where the illegal operation occurred was:
在用户选择日期或日期范围时发生。
+
+
+ Previous
+
+
无法将 MonthCalendar 的范围设置为从 {0} 到 {1}。
@@ -7616,6 +7631,11 @@ Stack trace where the illegal operation occurred was:
用于显示日历标题中文本的颜色。
+
+
+ Today: {0}
+
+
当前日期。
diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf
index d4aa77b81b0..49c1c6f74c1 100644
--- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf
+++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf
@@ -7481,6 +7481,11 @@ Stack trace where the illegal operation occurred was:
表示要以粗體表示一年之中的哪些日期。
+
+
+ Calendar body
+
+
月曆中月份欄和列的數目。
@@ -7531,6 +7536,11 @@ Stack trace where the illegal operation occurred was:
要以粗體表示一月之中的哪些日期。
+
+
+ Next
+
+
當因為使用者選取或透過下個月/上個月巡覽所造成日期範圍變更時發生。
@@ -7541,6 +7551,11 @@ Stack trace where the illegal operation occurred was:
當使用者選取日期或日期範圍時發生。
+
+
+ Previous
+
+
無法將 MonthCalendar 的範圍設為從 {0} 到 {1}。
@@ -7616,6 +7631,11 @@ Stack trace where the illegal operation occurred was:
用來顯示日曆標題內文字的色彩。
+
+
+ Today: {0}
+
+
目前的日期。
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs
index 71aaffa9867..d474ae2eaf6 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DateTimePicker.cs
@@ -221,7 +221,7 @@ public Color CalendarForeColor
if (!value.Equals(calendarForeColor))
{
calendarForeColor = value;
- SetControlColor(NativeMethods.MCSC_TEXT, value);
+ SetControlColor(ComCtl32.MCSC.TEXT, value);
}
}
}
@@ -300,7 +300,7 @@ public Color CalendarTitleBackColor
if (!value.Equals(calendarTitleBackColor))
{
calendarTitleBackColor = value;
- SetControlColor(NativeMethods.MCSC_TITLEBK, value);
+ SetControlColor(ComCtl32.MCSC.TITLEBK, value);
}
}
}
@@ -329,7 +329,7 @@ public Color CalendarTitleForeColor
if (!value.Equals(calendarTitleForeColor))
{
calendarTitleForeColor = value;
- SetControlColor(NativeMethods.MCSC_TITLETEXT, value);
+ SetControlColor(ComCtl32.MCSC.TITLETEXT, value);
}
}
}
@@ -358,7 +358,7 @@ public Color CalendarTrailingForeColor
if (!value.Equals(calendarTrailingText))
{
calendarTrailingText = value;
- SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, value);
+ SetControlColor(ComCtl32.MCSC.TRAILINGTEXT, value);
}
}
}
@@ -387,7 +387,7 @@ public Color CalendarMonthBackground
if (!value.Equals(calendarMonthBackground))
{
calendarMonthBackground = value;
- SetControlColor(NativeMethods.MCSC_MONTHBK, value);
+ SetControlColor(ComCtl32.MCSC.MONTHBK, value);
}
}
}
@@ -408,8 +408,8 @@ public bool Checked
// the information from win32 DateTimePicker is reliable only when ShowCheckBoxes is True
if (ShowCheckBox && IsHandleCreated)
{
- NativeMethods.SYSTEMTIME sys = new NativeMethods.SYSTEMTIME();
- int gdt = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_GETSYSTEMTIME, 0, sys);
+ Kernel32.SYSTEMTIME sys = new Kernel32.SYSTEMTIME();
+ int gdt = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_GETSYSTEMTIME, 0, ref sys);
return gdt == NativeMethods.GDT_VALID;
}
else
@@ -427,14 +427,13 @@ public bool Checked
if (value)
{
int gdt = NativeMethods.GDT_VALID;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, ref sys);
}
else
{
int gdt = NativeMethods.GDT_NONE;
- NativeMethods.SYSTEMTIME sys = null;
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, IntPtr.Zero);
}
}
// this.validTime is used when the DateTimePicker receives date time change notification
@@ -1054,8 +1053,8 @@ public DateTime Value
* get propagated to createHandle
*/
int gdt = NativeMethods.GDT_VALID;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, ref sys);
}
if (valueChanged)
@@ -1151,14 +1150,13 @@ protected override void CreateHandle()
* get propagated to setValue
*/
int gdt = NativeMethods.GDT_VALID;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, ref sys);
}
else if (!validTime)
{
int gdt = NativeMethods.GDT_NONE;
- NativeMethods.SYSTEMTIME sys = null;
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, IntPtr.Zero);
}
if (format == DateTimePickerFormat.Custom)
@@ -1386,8 +1384,8 @@ private void ResetValue()
if (IsHandleCreated)
{
int gdt = NativeMethods.GDT_VALID;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, ref sys);
}
// Updating Checked to false will set the control to "no date",
@@ -1401,11 +1399,11 @@ private void ResetValue()
///
/// If the handle has been created, this applies the color to the control
///
- private void SetControlColor(int colorIndex, Color value)
+ private void SetControlColor(Interop.ComCtl32.MCSC colorIndex, Color value)
{
if (IsHandleCreated)
{
- SendMessage(NativeMethods.DTM_SETMCCOLOR, colorIndex, ColorTranslator.ToWin32(value));
+ SendMessage(NativeMethods.DTM_SETMCCOLOR, (int)colorIndex, ColorTranslator.ToWin32(value));
}
}
@@ -1425,11 +1423,11 @@ private void SetControlCalendarFont()
///
private void SetAllControlColors()
{
- SetControlColor(NativeMethods.MCSC_MONTHBK, calendarMonthBackground);
- SetControlColor(NativeMethods.MCSC_TEXT, calendarForeColor);
- SetControlColor(NativeMethods.MCSC_TITLEBK, calendarTitleBackColor);
- SetControlColor(NativeMethods.MCSC_TITLETEXT, calendarTitleForeColor);
- SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, calendarTrailingText);
+ SetControlColor(ComCtl32.MCSC.MONTHBK, calendarMonthBackground);
+ SetControlColor(ComCtl32.MCSC.TEXT, calendarForeColor);
+ SetControlColor(ComCtl32.MCSC.TITLEBK, calendarTitleBackColor);
+ SetControlColor(ComCtl32.MCSC.TITLETEXT, calendarTitleForeColor);
+ SetControlColor(ComCtl32.MCSC.TRAILINGTEXT, calendarTrailingText);
}
///
@@ -1450,7 +1448,7 @@ private void SetRange(DateTime min, DateTime max)
NativeMethods.SYSTEMTIMEARRAY sa = new NativeMethods.SYSTEMTIMEARRAY();
flags |= NativeMethods.GDTR_MIN | NativeMethods.GDTR_MAX;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(min);
+ Kernel32.SYSTEMTIME sys = DateTimeToSysTime(min);
sa.wYear1 = sys.wYear;
sa.wMonth1 = sys.wMonth;
sa.wDayOfWeek1 = sys.wDayOfWeek;
@@ -1459,7 +1457,7 @@ private void SetRange(DateTime min, DateTime max)
sa.wMinute1 = sys.wMinute;
sa.wSecond1 = sys.wSecond;
sa.wMilliseconds1 = sys.wMilliseconds;
- sys = DateTimePicker.DateTimeToSysTime(max);
+ sys = DateTimeToSysTime(max);
sa.wYear2 = sys.wYear;
sa.wMonth2 = sys.wMonth;
sa.wDayOfWeek2 = sys.wDayOfWeek;
@@ -1747,9 +1745,9 @@ protected override void WndProc(ref Message m)
/// Takes a DateTime value and returns a SYSTEMTIME struct
/// Note: 1 second granularity
///
- internal static NativeMethods.SYSTEMTIME DateTimeToSysTime(DateTime time)
+ internal static Kernel32.SYSTEMTIME DateTimeToSysTime(DateTime time)
{
- NativeMethods.SYSTEMTIME sys = new NativeMethods.SYSTEMTIME
+ Kernel32.SYSTEMTIME sys = new Kernel32.SYSTEMTIME
{
wYear = (short)time.Year,
wMonth = (short)time.Month,
@@ -1767,7 +1765,7 @@ internal static NativeMethods.SYSTEMTIME DateTimeToSysTime(DateTime time)
/// Takes a SYSTEMTIME struct and returns a DateTime value
/// Note: 1 second granularity.
///
- internal static DateTime SysTimeToDateTime(NativeMethods.SYSTEMTIME s)
+ internal static DateTime SysTimeToDateTime(Kernel32.SYSTEMTIME s)
{
return new DateTime(s.wYear, s.wMonth, s.wDay, s.wHour, s.wMinute, s.wSecond);
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarBodyAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarBodyAccessibleObject.cs
new file mode 100644
index 00000000000..eee7e774721
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarBodyAccessibleObject.cs
@@ -0,0 +1,73 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ ///
+ /// Represents the calendar body accessible object.
+ ///
+ internal class CalendarBodyAccessibleObject : CalendarChildAccessibleObject
+ {
+ private const int ChildId = 4;
+
+ public CalendarBodyAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex)
+ : base(calendarAccessibleObject, calendarIndex, CalendarChildType.CalendarBody)
+ {
+ }
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, ComCtl32.MCGIP.CALENDARBODY, 0, 0, out RECT calendarPartRectangle);
+ return calendarPartRectangle;
+ }
+
+ internal override int GetChildId() => ChildId;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.NextSibling => new Func(() =>
+ {
+ MonthCalendar owner = (MonthCalendar)_calendarAccessibleObject.Owner;
+ return owner.ShowToday ? _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.TodayLink) : null;
+ })(),
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling => _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarHeader),
+ UnsafeNativeMethods.NavigateDirection.FirstChild =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, this, _calendarAccessibleObject.HasHeaderRow ? -1 : 0),
+ UnsafeNativeMethods.NavigateDirection.LastChild =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, this, _calendarAccessibleObject.RowCount - 1),
+ _ => base.FragmentNavigate(direction),
+
+ };
+
+ public CalendarChildAccessibleObject GetFromPoint(ComCtl32.MCHITTESTINFO hitTestInfo)
+ {
+ switch ((ComCtl32.MCHT)hitTestInfo.uHit)
+ {
+ case ComCtl32.MCHT.CALENDARDAY:
+ case ComCtl32.MCHT.CALENDARWEEKNUM:
+ case ComCtl32.MCHT.CALENDARDATE:
+ AccessibleObject rowAccessibleObject =
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, this, hitTestInfo.iRow);
+ return _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, rowAccessibleObject, hitTestInfo.iCol);
+ }
+
+ return this;
+ }
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_NamePropertyId => SR.MonthCalendarBodyAccessibleName,
+ NativeMethods.UIA_IsGridPatternAvailablePropertyId => true,
+ NativeMethods.UIA_IsTablePatternAvailablePropertyId => true,
+ _ => base.GetPropertyValue(propertyID)
+ };
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonAccessibleObject.cs
new file mode 100644
index 00000000000..d6da1040dfb
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonAccessibleObject.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal abstract class CalendarButtonAccessibleObject : CalendarChildAccessibleObject
+ {
+ public CalendarButtonAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, CalendarButtonType buttonType)
+ : base(calendarAccessibleObject, calendarIndex, (CalendarChildType)buttonType)
+ {
+ }
+
+ protected abstract CalendarButtonType ButtonType { get; }
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ ComCtl32.MCGIP dwPart;
+ switch (ButtonType)
+ {
+ case CalendarButtonType.Previous:
+ dwPart = ComCtl32.MCGIP.PREV;
+ break;
+
+ case CalendarButtonType.Next:
+ dwPart = ComCtl32.MCGIP.NEXT;
+ break;
+
+ default:
+ return new RECT();
+ }
+
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, dwPart, -1, -1, out RECT rectangle);
+ return rectangle;
+ }
+
+ internal override bool IsPatternSupported(int patternId) =>
+ (patternId == NativeMethods.UIA_InvokePatternId) || base.IsPatternSupported(patternId);
+
+ internal override void Invoke() => RaiseMouseClick();
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonType.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonType.cs
new file mode 100644
index 00000000000..f87c88e4633
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarButtonType.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal enum CalendarButtonType
+ {
+ Next = 1,
+ Previous = 2
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarCellAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarCellAccessibleObject.cs
new file mode 100644
index 00000000000..e59038a7032
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarCellAccessibleObject.cs
@@ -0,0 +1,111 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ ///
+ /// Represents the calendar cell accessible object.
+ ///
+ internal class CalendarCellAccessibleObject : CalendarGridChildAccessibleObject
+ {
+ private int _rowIndex;
+ private int _columnIndex;
+ private string _name;
+
+ public CalendarCellAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, AccessibleObject parentAccessibleObject, int rowIndex, int columnIndex, string name)
+ : base(calendarAccessibleObject, calendarIndex, CalendarChildType.CalendarCell, parentAccessibleObject, rowIndex * columnIndex)
+ {
+ _rowIndex = rowIndex;
+ _columnIndex = columnIndex;
+ _name = name;
+ }
+
+ public override string Name => _name;
+
+ internal override int Row => _rowIndex;
+
+ internal override int Column => _columnIndex;
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple ContainingGrid => _calendarAccessibleObject;
+
+ internal override int[] RuntimeId =>
+ new int[5]
+ {
+ RuntimeIDFirstItem,
+ _calendarAccessibleObject.Owner.Handle.ToInt32(),
+ Parent.Parent.GetChildId(),
+ Parent.GetChildId(),
+ GetChildId()
+ };
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, ComCtl32.MCGIP.CALENDARCELL, _rowIndex, _columnIndex, out RECT rectangle);
+ return rectangle;
+ }
+
+ internal override int GetChildId() => _columnIndex + 1;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.Parent => _parentAccessibleObject,
+ UnsafeNativeMethods.NavigateDirection.NextSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, _parentAccessibleObject, _columnIndex + 1),
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, _parentAccessibleObject, _columnIndex - 1),
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_ControlTypePropertyId =>
+ (_rowIndex == -1) ? NativeMethods.UIA_HeaderControlTypeId : NativeMethods.UIA_DataItemControlTypeId,
+ NativeMethods.UIA_NamePropertyId => Name,
+ var p when
+ p == NativeMethods.UIA_HasKeyboardFocusPropertyId ||
+ p == NativeMethods.UIA_IsGridItemPatternAvailablePropertyId ||
+ p == NativeMethods.UIA_IsTableItemPatternAvailablePropertyId => true,
+ _ => base.GetPropertyValue(propertyID)
+ };
+
+ internal override bool IsPatternSupported(int patternId) =>
+ patternId switch
+ {
+ var p when
+ p == NativeMethods.UIA_GridItemPatternId ||
+ p == NativeMethods.UIA_InvokePatternId ||
+ p == NativeMethods.UIA_TableItemPatternId => true,
+ _ => base.IsPatternSupported(patternId)
+ };
+
+ internal override void Invoke()
+ {
+ RaiseMouseClick();
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple[] GetRowHeaderItems() => null;
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple[] GetColumnHeaderItems()
+ {
+ if (!_calendarAccessibleObject.HasHeaderRow)
+ {
+ return null;
+ }
+
+ AccessibleObject headerRowAccessibleObject =
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, _parentAccessibleObject.Parent, -1);
+ AccessibleObject headerCellAccessibleObject =
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, headerRowAccessibleObject, _columnIndex);
+
+ return new UnsafeNativeMethods.IRawElementProviderSimple[1] { headerCellAccessibleObject };
+ }
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildAccessibleObject.cs
new file mode 100644
index 00000000000..a601d49dc10
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildAccessibleObject.cs
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Drawing;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ ///
+ /// Represents the calendar child accessible object.
+ ///
+ internal abstract class CalendarChildAccessibleObject : AccessibleObject
+ {
+ protected MonthCalendarAccessibleObject _calendarAccessibleObject;
+ protected int _calendarIndex;
+ protected CalendarChildType _itemType;
+
+ public CalendarChildAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, CalendarChildType itemType)
+ {
+ _calendarAccessibleObject = calendarAccessibleObject;
+ _calendarIndex = calendarIndex;
+ _itemType = itemType;
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragmentRoot FragmentRoot => _calendarAccessibleObject;
+
+ public override AccessibleObject Parent => _calendarAccessibleObject;
+
+ internal override Rectangle BoundingRectangle => CalculateBoundingRectangle();
+
+ protected virtual RECT CalculateBoundingRectangle() => new RECT();
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.Parent => Parent,
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_IsEnabledPropertyId => _calendarAccessibleObject.Enabled,
+ _ => base.GetPropertyValue(propertyID)
+ };
+
+ internal override int[] RuntimeId =>
+ new int[]
+ {
+ RuntimeIDFirstItem,
+ _calendarAccessibleObject.Owner.Handle.ToInt32(),
+ GetChildId()
+ };
+
+ public void RaiseMouseClick()
+ {
+ // Make sure that the control is enabled.
+ if (!SafeNativeMethods.IsWindowEnabled(new HandleRef(null, _calendarAccessibleObject.Owner.Handle)))
+ {
+ return;
+ }
+
+ var rectangle = CalculateBoundingRectangle();
+ int x = rectangle.left + ((rectangle.right - rectangle.left) / 2);
+ int y = rectangle.top + ((rectangle.bottom - rectangle.top) / 2);
+
+ _calendarAccessibleObject.RaiseMouseClick(x, y);
+ }
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildType.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildType.cs
new file mode 100644
index 00000000000..f4f26546520
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarChildType.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal enum CalendarChildType
+ {
+ Undefined = -1,
+ NextButton = 1,
+ PreviousButton = 2,
+ Footer = 3,
+ Calendar = 4,
+ CalendarHeader = 5,
+ CalendarBody = 6,
+ CalendarRow = 7,
+ CalendarCell = 8,
+ TodayLink = 9
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarGridChildAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarGridChildAccessibleObject.cs
new file mode 100644
index 00000000000..d216e2ce86d
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarGridChildAccessibleObject.cs
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ ///
+ /// Represents the calendar grid child accessible object.
+ ///
+ internal abstract class CalendarGridChildAccessibleObject : CalendarChildAccessibleObject
+ {
+ protected AccessibleObject _parentAccessibleObject;
+
+ public CalendarGridChildAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, CalendarChildType itemType,
+ AccessibleObject parentAccessibleObject, int itemIndex) : base(calendarAccessibleObject, calendarIndex, itemType)
+ {
+ _parentAccessibleObject = parentAccessibleObject;
+ }
+
+ public override AccessibleObject Parent => _parentAccessibleObject;
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarHeaderAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarHeaderAccessibleObject.cs
new file mode 100644
index 00000000000..0dc37df2732
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarHeaderAccessibleObject.cs
@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal class CalendarHeaderAccessibleObject : CalendarChildAccessibleObject
+ {
+ private const int ChildId = 3;
+
+ public CalendarHeaderAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex)
+ : base(calendarAccessibleObject, calendarIndex, CalendarChildType.CalendarHeader)
+ {
+ }
+
+ public override string Name => _calendarAccessibleObject.GetCalendarChildName(_calendarIndex, CalendarChildType.CalendarHeader);
+
+ internal override int GetChildId() => ChildId;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.NextButton),
+ UnsafeNativeMethods.NavigateDirection.NextSibling => _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarBody),
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_ControlTypePropertyId => NativeMethods.UIA_ButtonControlTypeId,
+ NativeMethods.UIA_NamePropertyId => Name,
+ _ => base.GetPropertyValue(propertyID)
+ };
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, ComCtl32.MCGIP.CALENDARHEADER, -1, -1, out RECT rectangle);
+ return rectangle;
+ }
+
+ internal override bool IsPatternSupported(int patternId) => (patternId == NativeMethods.UIA_InvokePatternId) || base.IsPatternSupported(patternId);
+
+ internal override void Invoke() => RaiseMouseClick();
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarNextButtonAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarNextButtonAccessibleObject.cs
new file mode 100644
index 00000000000..08b103cb47c
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarNextButtonAccessibleObject.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal class CalendarNextButtonAccessibleObject : CalendarButtonAccessibleObject
+ {
+ private const int ChildId = 2;
+
+ public CalendarNextButtonAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex)
+ : base(calendarAccessibleObject, calendarIndex, CalendarButtonType.Next)
+ {
+ }
+
+ protected override CalendarButtonType ButtonType => CalendarButtonType.Next;
+
+ internal override int GetChildId() => ChildId;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.PreviousButton),
+ UnsafeNativeMethods.NavigateDirection.NextSibling => _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarHeader),
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_BoundingRectanglePropertyId => BoundingRectangle,
+ NativeMethods.UIA_ControlTypePropertyId => NativeMethods.UIA_ButtonControlTypeId,
+ NativeMethods.UIA_NamePropertyId => SR.MonthCalendarNextButtonAccessibleName,
+ _ => base.GetPropertyValue(propertyID)
+ };
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarPreviousButtonAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarPreviousButtonAccessibleObject.cs
new file mode 100644
index 00000000000..9da0575b570
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarPreviousButtonAccessibleObject.cs
@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal class CalendarPreviousButtonAccessibleObject : CalendarButtonAccessibleObject
+ {
+ private const int ChildId = 1;
+
+ public CalendarPreviousButtonAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex)
+ : base(calendarAccessibleObject, calendarIndex, CalendarButtonType.Previous)
+ {
+ }
+
+ protected override CalendarButtonType ButtonType => CalendarButtonType.Previous;
+
+ internal override int GetChildId() => ChildId;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.NextSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.NextButton),
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_BoundingRectanglePropertyId => BoundingRectangle,
+ NativeMethods.UIA_ControlTypePropertyId => NativeMethods.UIA_ButtonControlTypeId,
+ NativeMethods.UIA_NamePropertyId => SR.MonthCalendarPreviousButtonAccessibleName,
+ _ => base.GetPropertyValue(propertyID)
+ };
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarRowAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarRowAccessibleObject.cs
new file mode 100644
index 00000000000..a901182ba32
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarRowAccessibleObject.cs
@@ -0,0 +1,55 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal class CalendarRowAccessibleObject : CalendarGridChildAccessibleObject
+ {
+ int _rowIndex;
+
+ public CalendarRowAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, CalendarBodyAccessibleObject parentAccessibleObject, int rowIndex)
+ : base(calendarAccessibleObject, calendarIndex, CalendarChildType.CalendarRow, parentAccessibleObject, rowIndex)
+ {
+ _rowIndex = rowIndex;
+ }
+
+ public int RowIndex => _rowIndex;
+
+ internal override int[] RuntimeId =>
+ new int[4]
+ {
+ RuntimeIDFirstItem,
+ _calendarAccessibleObject.Owner.Handle.ToInt32(),
+ Parent.GetChildId(),
+ GetChildId()
+ };
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, ComCtl32.MCGIP.CALENDARROW, _rowIndex, -1, out RECT calendarPartRectangle);
+ return calendarPartRectangle;
+ }
+
+ internal override int GetChildId() => _rowIndex + 1;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.NextSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, _parentAccessibleObject, _rowIndex + 1),
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, _parentAccessibleObject, _rowIndex - 1),
+ UnsafeNativeMethods.NavigateDirection.FirstChild =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, this, 0),
+ UnsafeNativeMethods.NavigateDirection.LastChild =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, this, _calendarAccessibleObject.ColumnCount - 1),
+ _ => base.FragmentNavigate(direction)
+ };
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarTodayLinkAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarTodayLinkAccessibleObject.cs
new file mode 100644
index 00000000000..2ae48a135c6
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.CalendarTodayLinkAccessibleObject.cs
@@ -0,0 +1,51 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ internal class CalendarTodayLinkAccessibleObject : CalendarChildAccessibleObject
+ {
+ private const int ChildId = 5;
+
+ public CalendarTodayLinkAccessibleObject(MonthCalendarAccessibleObject calendarAccessibleObject, int calendarIndex, CalendarChildType type)
+ : base(calendarAccessibleObject, calendarIndex, CalendarChildType.TodayLink)
+ {
+ }
+
+ protected override RECT CalculateBoundingRectangle()
+ {
+ _calendarAccessibleObject.GetCalendarPartRectangle(_calendarIndex, ComCtl32.MCGIP.FOOTER, -1, -1, out RECT calendarPartRectangle);
+ return calendarPartRectangle;
+ }
+
+ internal override int GetChildId() => ChildId;
+
+ internal override bool IsPatternSupported(int patternId) =>
+ (patternId == NativeMethods.UIA_InvokePatternId) || base.IsPatternSupported(patternId);
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_BoundingRectanglePropertyId => BoundingRectangle,
+ NativeMethods.UIA_ControlTypePropertyId => NativeMethods.UIA_ButtonControlTypeId,
+ NativeMethods.UIA_NamePropertyId => _calendarAccessibleObject.GetCalendarChildName(_calendarIndex, CalendarChildType.TodayLink),
+ _ => base.GetPropertyValue(propertyID)
+ };
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction) =>
+ direction switch
+ {
+ UnsafeNativeMethods.NavigateDirection.PreviousSibling =>
+ _calendarAccessibleObject.GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarBody),
+ _ => base.FragmentNavigate(direction)
+ };
+
+ internal override void Invoke() => RaiseMouseClick();
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.MonthCalendarAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.MonthCalendarAccessibleObject.cs
new file mode 100644
index 00000000000..711a616d12e
--- /dev/null
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.MonthCalendarAccessibleObject.cs
@@ -0,0 +1,748 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Drawing;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using static Interop;
+
+namespace System.Windows.Forms
+{
+ public partial class MonthCalendar
+ {
+ [ComVisible(true)]
+ internal class MonthCalendarAccessibleObject : ControlAccessibleObject
+ {
+ internal const int MAX_DAYS = 7;
+ internal const int MAX_WEEKS = 6;
+
+ private readonly MonthCalendar _owner;
+ private int _calendarIndex = 0;
+ private AccessibleObject _focused;
+
+ public MonthCalendarAccessibleObject(Control owner)
+ : base(owner)
+ {
+ _owner = owner as MonthCalendar;
+ }
+
+ public int ControlType =>
+ string.IsNullOrEmpty(base.Name) ? NativeMethods.UIA_CalendarControlTypeId : NativeMethods.UIA_TableControlTypeId;
+
+ public bool Enabled => _owner.Enabled;
+
+ public bool HasHeaderRow
+ {
+ get
+ {
+ bool result = GetCalendarGridInfoText(ComCtl32.MCGIP.CALENDARCELL, _calendarIndex, -1, 0, out string text);
+ if (!result || string.IsNullOrEmpty(text))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ public override AccessibleRole Role =>
+ (_owner?.AccessibleRole != AccessibleRole.Default) ? _owner.AccessibleRole : AccessibleRole.Table;
+
+ public override string Help
+ {
+ get
+ {
+ var help = base.Help;
+ if (help != null)
+ {
+ return help;
+ }
+ else
+ {
+ if (_owner != null)
+ {
+ return _owner.GetType().Name + "(" + _owner.GetType().BaseType.Name + ")";
+ }
+ }
+ return string.Empty;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ string name = base.Name;
+ if (name != null)
+ {
+ return name;
+ }
+
+ name = string.Empty;
+ if (_owner == null)
+ {
+ return name;
+ }
+
+ if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_MONTH)
+ {
+ if (DateTime.Equals(_owner.SelectionStart.Date, _owner.SelectionEnd.Date))
+ {
+ return string.Format(SR.MonthCalendarSingleDateSelected, _owner.SelectionStart.ToLongDateString());
+ }
+ else
+ {
+ return string.Format(SR.MonthCalendarRangeSelected, _owner.SelectionStart.ToLongDateString(), _owner.SelectionEnd.ToLongDateString());
+ }
+ }
+ else if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_YEAR)
+ {
+ if (DateTime.Equals(_owner.SelectionStart.Month, _owner.SelectionEnd.Month))
+ {
+ return string.Format(SR.MonthCalendarSingleDateSelected, _owner.SelectionStart.ToString("y"));
+ }
+ else
+ {
+ return string.Format(SR.MonthCalendarRangeSelected, _owner.SelectionStart.ToString("y"), _owner.SelectionEnd.ToString("y"));
+ }
+ }
+ else if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_DECADE)
+ {
+ if (DateTime.Equals(_owner.SelectionStart.Year, _owner.SelectionEnd.Year))
+ {
+ return string.Format(SR.MonthCalendarSingleYearSelected, _owner.SelectionStart.ToString("yyyy"));
+ }
+ else
+ {
+ return string.Format(SR.MonthCalendarYearRangeSelected, _owner.SelectionStart.ToString("yyyy"), _owner.SelectionEnd.ToString("yyyy"));
+ }
+ }
+ else if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_CENTURY)
+ {
+ return string.Format(SR.MonthCalendarSingleDecadeSelected, _owner.SelectionStart.ToString("yyyy"));
+ }
+
+ return name;
+ }
+ }
+
+ public override string Value
+ {
+ get
+ {
+ var value = string.Empty;
+ if (_owner == null)
+ {
+ return value;
+ }
+
+ try
+ {
+ if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_MONTH)
+ {
+ if (System.DateTime.Equals(_owner.SelectionStart.Date, _owner.SelectionEnd.Date))
+ {
+ value = _owner.SelectionStart.ToLongDateString();
+ }
+ else
+ {
+ value = string.Format("{0} - {1}", _owner.SelectionStart.ToLongDateString(), _owner.SelectionEnd.ToLongDateString());
+ }
+ }
+ else if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_YEAR)
+ {
+ if (System.DateTime.Equals(_owner.SelectionStart.Month, _owner.SelectionEnd.Month))
+ {
+ value = _owner.SelectionStart.ToString("y");
+ }
+ else
+ {
+ value = string.Format("{0} - {1}", _owner.SelectionStart.ToString("y"), _owner.SelectionEnd.ToString("y"));
+ }
+ }
+ else
+ {
+ value = string.Format("{0} - {1}", _owner.SelectionRange.Start.ToString(), _owner.SelectionRange.End.ToString());
+ }
+ }
+ catch
+ {
+ value = base.Value;
+ }
+
+ return value;
+ }
+ set
+ {
+ base.Value = value;
+ }
+ }
+
+ internal override int ColumnCount
+ {
+ get
+ {
+ GetCalendarGridInfo(
+ ComCtl32.MCGIF.RECT,
+ ComCtl32.MCGIP.CALENDARBODY,
+ _calendarIndex,
+ -1,
+ -1,
+ out RECT calendarBodyRectangle,
+ out Kernel32.SYSTEMTIME endDate,
+ out Kernel32.SYSTEMTIME startDate);
+
+ int columnCount = 0;
+ bool success = true;
+ while (success)
+ {
+ success = GetCalendarGridInfo(
+ ComCtl32.MCGIF.RECT,
+ ComCtl32.MCGIP.CALENDARCELL,
+ _calendarIndex,
+ 0,
+ columnCount,
+ out RECT calendarPartRectangle,
+ out endDate,
+ out startDate);
+
+ // Out of the body, so this is out of the grid column.
+ if (calendarPartRectangle.right > calendarBodyRectangle.right)
+ {
+ break;
+ }
+
+ columnCount++;
+ }
+
+ return columnCount;
+ }
+ }
+
+ internal override int RowCount
+ {
+ get
+ {
+ GetCalendarGridInfo(
+ ComCtl32.MCGIF.RECT,
+ ComCtl32.MCGIP.CALENDARBODY,
+ _calendarIndex,
+ -1,
+ -1,
+ out RECT calendarBodyRectangle,
+ out Kernel32.SYSTEMTIME endDate,
+ out Kernel32.SYSTEMTIME startDate);
+
+ int rowCount = 0;
+ bool success = true;
+ while (success)
+ {
+ success = GetCalendarGridInfo(
+ ComCtl32.MCGIF.RECT,
+ ComCtl32.MCGIP.CALENDARCELL,
+ _calendarIndex,
+ rowCount,
+ 0,
+ out RECT calendarPartRectangle,
+ out endDate,
+ out startDate);
+
+ // Out of the body, so this is out of the grid row.
+ if (calendarPartRectangle.bottom > calendarBodyRectangle.bottom)
+ {
+ break;
+ }
+
+ rowCount++;
+ }
+
+ return rowCount;
+ }
+ }
+
+ internal override UnsafeNativeMethods.RowOrColumnMajor RowOrColumnMajor => UnsafeNativeMethods.RowOrColumnMajor.RowOrColumnMajor_RowMajor;
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple[] GetRowHeaderItems() => null;
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment ElementProviderFromPoint(double x, double y)
+ {
+ int innerX = (int)x;
+ int innerY = (int)y;
+
+ ComCtl32.MCHITTESTINFO hitTestInfo = GetHitTestInfo(innerX, innerY);
+ switch ((ComCtl32.MCHT)hitTestInfo.uHit)
+ {
+ case ComCtl32.MCHT.TITLEBTNPREV:
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.PreviousButton);
+
+ case ComCtl32.MCHT.TITLEBTNNEXT:
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.NextButton);
+
+ case ComCtl32.MCHT.TITLE:
+ case ComCtl32.MCHT.TITLEMONTH:
+ case ComCtl32.MCHT.TITLEYEAR:
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarHeader);
+
+ case ComCtl32.MCHT.CALENDARDAY:
+ case ComCtl32.MCHT.CALENDARWEEKNUM:
+ case ComCtl32.MCHT.CALENDARDATE:
+ // Get calendar body's child.
+ CalendarBodyAccessibleObject calendarBodyAccessibleObject = (CalendarBodyAccessibleObject)GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarBody);
+ return calendarBodyAccessibleObject.GetFromPoint(hitTestInfo);
+
+ case ComCtl32.MCHT.TODAYLINK:
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.TodayLink);
+ }
+
+ return base.ElementProviderFromPoint(x, y);
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment FragmentNavigate(UnsafeNativeMethods.NavigateDirection direction)
+ {
+ switch (direction)
+ {
+ case UnsafeNativeMethods.NavigateDirection.FirstChild:
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.PreviousButton);
+ case UnsafeNativeMethods.NavigateDirection.LastChild:
+ return _owner.ShowTodayCircle
+ ? GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.TodayLink)
+ : GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarBody);
+ }
+
+ return base.FragmentNavigate(direction);
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderFragment GetFocus() => _focused;
+
+ public override AccessibleObject GetFocused() => _focused;
+
+ public ComCtl32.MCHITTESTINFO GetHitTestInfo(int xScreen, int yScreen)
+ {
+ ComCtl32.MCHITTESTINFO hitTestInfo = new ComCtl32.MCHITTESTINFO();
+ hitTestInfo.cbSize = (int)Marshal.SizeOf(hitTestInfo);
+ hitTestInfo.pt = new POINT();
+ hitTestInfo.st = new Kernel32.SYSTEMTIME();
+
+ // NativeMethods.GetCursorPos(out Point pt);
+ Point point = new Point(xScreen, yScreen);
+ NativeMethods.MapWindowPoints(IntPtr.Zero, Handle, ref point, 1);
+ hitTestInfo.pt.x = point.X;
+ hitTestInfo.pt.y = point.Y;
+
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.HITTEST, 0, ref hitTestInfo);
+
+ return hitTestInfo;
+ }
+
+ public CalendarChildAccessibleObject GetCalendarChildAccessibleObject(int calendarIndex, CalendarChildType calendarChildType, AccessibleObject parentAccessibleObject = null, int index = -1) =>
+ calendarChildType switch
+ {
+ CalendarChildType.PreviousButton => new CalendarPreviousButtonAccessibleObject(this, _calendarIndex),
+ CalendarChildType.NextButton => new CalendarNextButtonAccessibleObject(this, _calendarIndex),
+ CalendarChildType.CalendarHeader => new CalendarHeaderAccessibleObject(this, _calendarIndex),
+ CalendarChildType.CalendarBody => new CalendarBodyAccessibleObject(this, _calendarIndex),
+ CalendarChildType.CalendarRow => GetCalendarRow(calendarIndex, parentAccessibleObject, index),
+ CalendarChildType.CalendarCell => GetCalendarCell(calendarIndex, parentAccessibleObject, index),
+ CalendarChildType.TodayLink => new CalendarTodayLinkAccessibleObject(this, (int)CalendarChildType.TodayLink, calendarChildType),
+ _ => null
+ };
+
+ public string GetCalendarChildName(int calendarIndex, CalendarChildType calendarChildType, AccessibleObject parentAccessibleObject = null, int index = -1)
+ {
+ switch (calendarChildType)
+ {
+ case CalendarChildType.CalendarHeader:
+ GetCalendarGridInfoText(ComCtl32.MCGIP.CALENDARHEADER, calendarIndex, 0, 0, out string text);
+ return text;
+ case CalendarChildType.TodayLink:
+ return string.Format(SR.MonthCalendarTodayButtonAccessibleName, _owner.TodayDate.ToShortDateString());
+ };
+
+ return string.Empty;
+ }
+
+ private CalendarCellAccessibleObject GetCalendarCell(int calendarIndex, AccessibleObject parentAccessibleObject, int columnIndex)
+ {
+ if (columnIndex < 0 ||
+ columnIndex >= MAX_DAYS ||
+ columnIndex >= ColumnCount)
+ {
+ return null;
+ }
+
+ CalendarRowAccessibleObject parentRowAccessibleObject = (CalendarRowAccessibleObject)parentAccessibleObject;
+ int rowIndex = parentRowAccessibleObject.RowIndex;
+ bool getNameResult = GetCalendarGridInfoText(ComCtl32.MCGIP.CALENDARCELL, calendarIndex, rowIndex, columnIndex, out string text);
+ bool getDateResult = GetCalendarGridInfo(ComCtl32.MCGIF.DATE, ComCtl32.MCGIP.CALENDARCELL,
+ calendarIndex,
+ rowIndex,
+ columnIndex,
+ out RECT rectangle,
+ out Kernel32.SYSTEMTIME systemEndDate,
+ out Kernel32.SYSTEMTIME systemStartDate);
+
+ DateTime endDate = DateTimePicker.SysTimeToDateTime(systemEndDate).Date;
+ DateTime startDate = DateTimePicker.SysTimeToDateTime(systemStartDate).Date;
+
+ if (getNameResult && !string.IsNullOrEmpty(text))
+ {
+ string cellName = GetCalendarCellName(endDate, startDate, text, rowIndex == -1);
+
+ // The cell is present on the calendar, so create accessible object for it.
+ return new CalendarCellAccessibleObject(this, calendarIndex, parentAccessibleObject, rowIndex, columnIndex, cellName);
+ }
+
+ return null;
+ }
+
+ private string GetCalendarCellName(DateTime endDate, DateTime startDate, string defaultName, bool headerCell)
+ {
+ if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_MONTH)
+ {
+ if (headerCell)
+ {
+ return startDate.ToString("dddd");
+ }
+
+ return startDate.ToString("dddd, MMMM dd, yyyy");
+ }
+ else if (_owner.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_YEAR)
+ {
+ return startDate.ToString("MMMM yyyy");
+ }
+
+ return defaultName;
+ }
+
+ private CalendarRowAccessibleObject GetCalendarRow(int calendarIndex, AccessibleObject parentAccessibleObject, int rowIndex)
+ {
+ if ((HasHeaderRow ? rowIndex < -1 : rowIndex < 0) ||
+ rowIndex >= RowCount)
+ {
+ return null;
+ }
+
+ // Search name for the first cell in the row.
+ bool success = GetCalendarGridInfo(
+ ComCtl32.MCGIF.DATE,
+ ComCtl32.MCGIP.CALENDARCELL,
+ calendarIndex,
+ rowIndex,
+ 0,
+ out RECT calendarPartRectangle,
+ out Kernel32.SYSTEMTIME endDate,
+ out Kernel32.SYSTEMTIME startDate);
+
+ if (!success)
+ {
+ // Not able to get cell date for the row.
+ return null;
+ }
+
+ SelectionRange cellsRange = _owner.GetDisplayRange(false);
+
+ if (cellsRange.Start > DateTimePicker.SysTimeToDateTime(endDate) || cellsRange.End < DateTimePicker.SysTimeToDateTime(startDate))
+ {
+ // Do not create row if the row's first cell is out of the current calendar's view range.
+ return null;
+ }
+
+ return new CalendarRowAccessibleObject(this, calendarIndex, (CalendarBodyAccessibleObject)parentAccessibleObject, rowIndex);
+ }
+
+ private bool GetCalendarGridInfo(
+ ComCtl32.MCGIF dwFlags,
+ ComCtl32.MCGIP dwPart,
+ int calendarIndex,
+ int row,
+ int column,
+ out RECT rectangle,
+ out Kernel32.SYSTEMTIME endDate,
+ out Kernel32.SYSTEMTIME startDate)
+ {
+ Debug.Assert(
+ (dwFlags & ~(ComCtl32.MCGIF.DATE | ComCtl32.MCGIF.RECT)) == 0,
+ "GetCalendarGridInfo() should be used only to obtain Date and Rect,"
+ + "dwFlags has flag bits other that MCGIF_DATE and MCGIF_RECT");
+
+ ComCtl32.MCGRIDINFO gridInfo = new ComCtl32.MCGRIDINFO();
+ gridInfo.dwFlags = dwFlags;
+ gridInfo.cbSize = (uint)Marshal.SizeOf(gridInfo);
+ gridInfo.dwPart = dwPart;
+ gridInfo.iCalendar = calendarIndex;
+ gridInfo.iCol = column;
+ gridInfo.iRow = row;
+ bool result;
+
+ try
+ {
+ result = GetCalendarGridInfo(ref gridInfo);
+ rectangle = gridInfo.rc;
+ endDate = gridInfo.stEnd;
+ startDate = gridInfo.stStart;
+ }
+ catch
+ {
+ rectangle = new RECT();
+ endDate = new Kernel32.SYSTEMTIME();
+ startDate = new Kernel32.SYSTEMTIME();
+ result = false;
+ }
+
+ return result;
+ }
+
+ private bool GetCalendarGridInfo(ref ComCtl32.MCGRIDINFO gridInfo)
+ {
+ // Do not use this if gridInfo.dwFlags contains MCGIF_NAME;
+ // use GetCalendarGridInfoText() instead.
+ Debug.Assert(
+ (gridInfo.dwFlags & ComCtl32.MCGIF.NAME) == 0,
+ "Param dwFlags contains MCGIF_NAME, use GetCalendarGridInfoText() to retrieve the text of a calendar part.");
+
+ gridInfo.dwFlags &= ~ComCtl32.MCGIF.NAME;
+
+ return _owner.SendMessage((int)ComCtl32.MCM.GETCALENDARGRIDINFO, 0, ref gridInfo) != IntPtr.Zero;
+ }
+
+ private bool GetCalendarGridInfoText(ComCtl32.MCGIP dwPart, int calendarIndex, int row, int column, out string text)
+ {
+ const int nameLength = 128;
+
+ ComCtl32.MCGRIDINFO gridInfo = new ComCtl32.MCGRIDINFO();
+ gridInfo.cbSize = (uint)Marshal.SizeOf(gridInfo);
+ gridInfo.dwPart = dwPart;
+ gridInfo.iCalendar = calendarIndex;
+ gridInfo.iCol = column;
+ gridInfo.iRow = row;
+ gridInfo.pszName = new string('\0', nameLength + 2);
+ gridInfo.cchName = (uint)gridInfo.pszName.Length - 1;
+
+ bool result = GetCalendarGridInfoText(ref gridInfo);
+ text = gridInfo.pszName;
+
+ return result;
+ }
+
+ // Use to retrieve MCGIF_NAME only.
+ private bool GetCalendarGridInfoText(ref ComCtl32.MCGRIDINFO gridInfo)
+ {
+ Debug.Assert(
+ gridInfo.dwFlags == 0,
+ "gridInfo.dwFlags should be 0 when calling GetCalendarGridInfoText");
+
+ gridInfo.dwFlags = ComCtl32.MCGIF.NAME;
+
+ return _owner.SendMessage((int)ComCtl32.MCM.GETCALENDARGRIDINFO, 0, ref gridInfo) != IntPtr.Zero;
+ }
+
+ public bool GetCalendarPartRectangle(int calendarIndex, ComCtl32.MCGIP dwPart, int row, int column, out RECT calendarPartRectangle)
+ {
+ bool success = GetCalendarGridInfo(
+ ComCtl32.MCGIF.RECT,
+ dwPart,
+ calendarIndex,
+ row,
+ column,
+ out calendarPartRectangle,
+ out Kernel32.SYSTEMTIME endDate, out Kernel32.SYSTEMTIME startDate);
+
+ if (success)
+ {
+ success = UnsafeNativeMethods.MapWindowPoints(new HandleRef(this, Owner.Handle), new HandleRef(null, IntPtr.Zero), ref calendarPartRectangle, 2) != 0;
+ }
+
+ if (!success)
+ {
+ calendarPartRectangle = new RECT();
+ }
+
+ return success;
+ }
+
+ internal override object GetPropertyValue(int propertyID) =>
+ propertyID switch
+ {
+ NativeMethods.UIA_ControlTypePropertyId => ControlType,
+ NativeMethods.UIA_NamePropertyId => Name,
+ NativeMethods.UIA_IsGridPatternAvailablePropertyId => true,
+ NativeMethods.UIA_IsTablePatternAvailablePropertyId => true,
+ NativeMethods.UIA_IsLegacyIAccessiblePatternAvailablePropertyId => true,
+ _ => base.GetPropertyValue(propertyID)
+ };
+
+ internal override bool IsPatternSupported(int patternId) =>
+ patternId switch
+ {
+ var p when
+ p == NativeMethods.UIA_ValuePatternId ||
+ p == NativeMethods.UIA_GridPatternId ||
+ p == NativeMethods.UIA_TablePatternId ||
+ p == NativeMethods.UIA_LegacyIAccessiblePatternId => true,
+ _ => base.IsPatternSupported(patternId)
+ };
+
+ public void RaiseMouseClick(int x, int y)
+ {
+ POINT previousPosition = new POINT();
+ bool setOldCursorPos = UnsafeNativeMethods.GetPhysicalCursorPos(ref previousPosition);
+
+ bool mouseSwapped = User32.GetSystemMetrics(User32.SystemMetric.SM_SWAPBUTTON) != 0;
+
+ SendMouseInput(x, y, User32.MOUSEEVENTF.MOVE | User32.MOUSEEVENTF.ABSOLUTE);
+ SendMouseInput(0, 0, mouseSwapped ? User32.MOUSEEVENTF.RIGHTDOWN : User32.MOUSEEVENTF.LEFTDOWN);
+ SendMouseInput(0, 0, mouseSwapped ? User32.MOUSEEVENTF.RIGHTUP : User32.MOUSEEVENTF.LEFTUP);
+
+ Threading.Thread.Sleep(50);
+
+ // Set back the mouse position where it was.
+ if (setOldCursorPos)
+ {
+ SendMouseInput(previousPosition.x, previousPosition.y, User32.MOUSEEVENTF.MOVE | User32.MOUSEEVENTF.ABSOLUTE);
+ }
+ }
+
+ private void SendMouseInput(int x, int y, User32.MOUSEEVENTF flags)
+ {
+ if ((flags & User32.MOUSEEVENTF.ABSOLUTE) != 0)
+ {
+ int vscreenWidth = User32.GetSystemMetrics(User32.SystemMetric.SM_CXVIRTUALSCREEN);
+ int vscreenHeight = User32.GetSystemMetrics(User32.SystemMetric.SM_CYVIRTUALSCREEN);
+ int vscreenLeft = User32.GetSystemMetrics(User32.SystemMetric.SM_XVIRTUALSCREEN);
+ int vscreenTop = User32.GetSystemMetrics(User32.SystemMetric.SM_YVIRTUALSCREEN);
+
+ const int DesktopNormilizedMax = 65536;
+
+ // Absolute input requires that input is in 'normalized' coords - with the entire
+ // desktop being (0,0)...(65535,65536). Need to convert input x,y coords to this
+ // first.
+ //
+ // In this normalized world, any pixel on the screen corresponds to a block of values
+ // of normalized coords - eg. on a 1024x768 screen,
+ // y pixel 0 corresponds to range 0 to 85.333,
+ // y pixel 1 corresponds to range 85.333 to 170.666,
+ // y pixel 2 correpsonds to range 170.666 to 256 - and so on.
+ // Doing basic scaling math - (x-top)*65536/Width - gets us the start of the range.
+ // However, because int math is used, this can end up being rounded into the wrong
+ // pixel. For example, if we wanted pixel 1, we'd get 85.333, but that comes out as
+ // 85 as an int, which falls into pixel 0's range - and that's where the pointer goes.
+ // To avoid this, we add on half-a-"screen pixel"'s worth of normalized coords - to
+ // push us into the middle of any given pixel's range - that's the 65536/(Width*2)
+ // part of the formula. So now pixel 1 maps to 85+42 = 127 - which is comfortably
+ // in the middle of that pixel's block.
+ // The key ting here is that unlike points in coordinate geometry, pixels take up
+ // space, so are often better treated like rectangles - and if you want to target
+ // a particular pixel, target its rectangle's midpoint, not its edge.
+ x = ((x - vscreenLeft) * DesktopNormilizedMax) / vscreenWidth + DesktopNormilizedMax / (vscreenWidth * 2);
+ y = ((y - vscreenTop) * DesktopNormilizedMax) / vscreenHeight + DesktopNormilizedMax / (vscreenHeight * 2);
+
+ flags |= User32.MOUSEEVENTF.VIRTUALDESK;
+ }
+
+ NativeMethods.INPUT mouseInput = new NativeMethods.INPUT();
+ mouseInput.type = NativeMethods.INPUT_MOUSE;
+ mouseInput.inputUnion.mi.dx = x;
+ mouseInput.inputUnion.mi.dy = y;
+ mouseInput.inputUnion.mi.mouseData = 0;
+ mouseInput.inputUnion.mi.dwFlags = (int)flags;
+ mouseInput.inputUnion.mi.time = 0;
+ mouseInput.inputUnion.mi.dwExtraInfo = new IntPtr(0);
+
+ UnsafeNativeMethods.SendInput(1, ref mouseInput, Marshal.SizeOf(mouseInput));
+ }
+
+ public void RaiseAutomationEventForChild(int automationEventId, DateTime selectionStart, DateTime selectionEnd)
+ {
+ AccessibleObject calendarChildAccessibleObject = GetCalendarChildAccessibleObject(selectionStart, selectionEnd);
+ if (calendarChildAccessibleObject != null)
+ {
+ calendarChildAccessibleObject.RaiseAutomationEvent(automationEventId);
+
+ if (automationEventId == NativeMethods.UIA_AutomationFocusChangedEventId)
+ {
+ _focused = calendarChildAccessibleObject;
+ }
+ }
+ }
+
+ private AccessibleObject GetCalendarChildAccessibleObject(DateTime selectionStart, DateTime selectionEnd)
+ {
+ int columnCount = ColumnCount;
+
+ AccessibleObject bodyAccessibleObject = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarBody);
+ for (int row = 0; row < RowCount; row++)
+ {
+ AccessibleObject rowAccessibleObject = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, bodyAccessibleObject, row);
+ for (int column = 0; column < columnCount; column++)
+ {
+ bool success = GetCalendarGridInfo(
+ ComCtl32.MCGIF.DATE,
+ ComCtl32.MCGIP.CALENDARCELL,
+ _calendarIndex,
+ row,
+ column,
+ out RECT calendarPartRectangle,
+ out Kernel32.SYSTEMTIME systemEndDate,
+ out Kernel32.SYSTEMTIME systemStartDate);
+
+ if (!success)
+ {
+ continue;
+ }
+
+ AccessibleObject cellAccessibleObject = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, rowAccessibleObject, column);
+ if (cellAccessibleObject == null)
+ {
+ continue;
+ }
+
+ DateTime endDate = DateTimePicker.SysTimeToDateTime(systemEndDate);
+ DateTime startDate = DateTimePicker.SysTimeToDateTime(systemStartDate);
+
+ if (DateTime.Compare(selectionEnd, endDate) <= 0 &&
+ DateTime.Compare(selectionStart, startDate) >= 0)
+ {
+ return cellAccessibleObject;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple[] GetRowHeaders() => null;
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple[] GetColumnHeaderItems()
+ {
+ if (!HasHeaderRow)
+ {
+ return null;
+ }
+
+ UnsafeNativeMethods.IRawElementProviderSimple[] headers =
+ new UnsafeNativeMethods.IRawElementProviderSimple[MonthCalendarAccessibleObject.MAX_DAYS];
+ AccessibleObject headerRowAccessibleObject = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, this, -1);
+ for (int columnIndex = 0; columnIndex < MonthCalendarAccessibleObject.MAX_DAYS; columnIndex++)
+ {
+ headers[columnIndex] = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, headerRowAccessibleObject, columnIndex);
+ }
+
+ return headers;
+ }
+
+ internal override UnsafeNativeMethods.IRawElementProviderSimple GetItem(int row, int column)
+ {
+ AccessibleObject rowAccessibleObject = GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarRow, this, row);
+
+ if (rowAccessibleObject == null)
+ {
+ return null;
+ }
+
+ return GetCalendarChildAccessibleObject(_calendarIndex, CalendarChildType.CalendarCell, rowAccessibleObject, column);
+ }
+ }
+ }
+}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs
index 21e332d9b0c..0e0db38f6c3 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MonthCalendar.cs
@@ -10,8 +10,9 @@
using System.Windows.Forms.Internal;
using System.Windows.Forms.Layout;
using Microsoft.Win32;
-using ArrayList = System.Collections.ArrayList;
+
using static Interop;
+using ArrayList = System.Collections.ArrayList;
namespace System.Windows.Forms
{
@@ -62,7 +63,7 @@ namespace System.Windows.Forms
Designer("System.Windows.Forms.Design.MonthCalendarDesigner, " + AssemblyRef.SystemDesign),
SRDescription(nameof(SR.DescriptionMonthCalendar))
]
- public class MonthCalendar : Control
+ public partial class MonthCalendar : Control
{
const long DAYS_TO_1601 = 548229;
const long DAYS_TO_10000 = 3615900;
@@ -365,20 +366,20 @@ protected override CreateParams CreateParams
{
CreateParams cp = base.CreateParams;
cp.ClassName = NativeMethods.WC_MONTHCAL;
- cp.Style |= NativeMethods.MCS_MULTISELECT | NativeMethods.MCS_DAYSTATE;
+ cp.Style |= (int)ComCtl32.MCS.MULTISELECT | (int)ComCtl32.MCS.DAYSTATE;
if (!showToday)
{
- cp.Style |= NativeMethods.MCS_NOTODAY;
+ cp.Style |= (int)ComCtl32.MCS.NOTODAY;
}
if (!showTodayCircle)
{
- cp.Style |= NativeMethods.MCS_NOTODAYCIRCLE;
+ cp.Style |= (int)ComCtl32.MCS.NOTODAYCIRCLE;
}
if (showWeekNumbers)
{
- cp.Style |= NativeMethods.MCS_WEEKNUMBERS;
+ cp.Style |= (int)ComCtl32.MCS.WEEKNUMBERS;
}
if (RightToLeft == RightToLeft.Yes && RightToLeftLayout == true)
@@ -466,7 +467,7 @@ public Day FirstDayOfWeek
}
else
{
- SendMessage(NativeMethods.MCM_SETFIRSTDAYOFWEEK, 0, (int)value);
+ SendMessage((int)ComCtl32.MCM.SETFIRSTDAYOFWEEK, 0, (int)value);
}
}
}
@@ -569,7 +570,7 @@ public int MaxSelectionCount
{
if (IsHandleCreated)
{
- if (unchecked((int)(long)SendMessage(NativeMethods.MCM_SETMAXSELCOUNT, value, 0)) == 0)
+ if (unchecked((int)(long)SendMessage((int)ComCtl32.MCM.SETMAXSELCOUNT, value, 0)) == 0)
{
throw new ArgumentException(string.Format(SR.MonthCalendarMaxSelCount, value.ToString("D")), nameof(value));
}
@@ -757,7 +758,7 @@ public int ScrollChange
if (IsHandleCreated)
{
- SendMessage(NativeMethods.MCM_SETMONTHDELTA, value, 0);
+ SendMessage((int)ComCtl32.MCM.SETMONTHDELTA, value, 0);
}
scrollChange = value;
}
@@ -982,7 +983,7 @@ public Size SingleMonthSize
if (IsHandleCreated)
{
- if (unchecked((int)(long)SendMessage(NativeMethods.MCM_GETMINREQRECT, 0, ref rect)) == 0)
+ if (unchecked((int)(long)SendMessage((int)ComCtl32.MCM.GETMINREQRECT, 0, ref rect)) == 0)
{
throw new InvalidOperationException(SR.InvalidSingleMonthSize);
}
@@ -1015,6 +1016,8 @@ public Size SingleMonthSize
}
}
+ internal override bool SupportsUiaProviders => true;
+
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Bindable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text
{
@@ -1055,8 +1058,8 @@ public DateTime TodayDate
if (IsHandleCreated)
{
- NativeMethods.SYSTEMTIME st = new NativeMethods.SYSTEMTIME();
- int res = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_GETTODAY, 0, st);
+ Kernel32.SYSTEMTIME st = new Kernel32.SYSTEMTIME();
+ int res = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.GETTODAY, 0, ref st);
Debug.Assert(res != 0, "MCM_GETTODAY failed");
return DateTimePicker.SysTimeToDateTime(st).Date;
}
@@ -1131,7 +1134,7 @@ public Color TitleBackColor
"value"));
}
titleBackColor = value;
- SetControlColor(NativeMethods.MCSC_TITLEBK, value);
+ SetControlColor(ComCtl32.MCSC.TITLEBK, value);
}
}
@@ -1157,7 +1160,7 @@ public Color TitleForeColor
"value"));
}
titleForeColor = value;
- SetControlColor(NativeMethods.MCSC_TITLETEXT, value);
+ SetControlColor(ComCtl32.MCSC.TITLETEXT, value);
}
}
@@ -1183,7 +1186,7 @@ public Color TrailingForeColor
"value"));
}
trailingForeColor = value;
- SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, value);
+ SetControlColor(ComCtl32.MCSC.TRAILINGTEXT, value);
}
}
@@ -1398,31 +1401,31 @@ public SelectionRange GetDisplayRange(bool visible)
///
private HitArea GetHitArea(int hit)
{
- switch (hit)
+ switch ((ComCtl32.MCHT)hit)
{
- case NativeMethods.MCHT_TITLEBK:
+ case ComCtl32.MCHT.TITLEBK:
return HitArea.TitleBackground;
- case NativeMethods.MCHT_TITLEMONTH:
+ case ComCtl32.MCHT.TITLEMONTH:
return HitArea.TitleMonth;
- case NativeMethods.MCHT_TITLEYEAR:
+ case ComCtl32.MCHT.TITLEYEAR:
return HitArea.TitleYear;
- case NativeMethods.MCHT_TITLEBTNNEXT:
+ case ComCtl32.MCHT.TITLEBTNNEXT:
return HitArea.NextMonthButton;
- case NativeMethods.MCHT_TITLEBTNPREV:
+ case ComCtl32.MCHT.TITLEBTNPREV:
return HitArea.PrevMonthButton;
- case NativeMethods.MCHT_CALENDARBK:
+ case ComCtl32.MCHT.CALENDARBK:
return HitArea.CalendarBackground;
- case NativeMethods.MCHT_CALENDARDATE:
+ case ComCtl32.MCHT.CALENDARDATE:
return HitArea.Date;
- case NativeMethods.MCHT_CALENDARDATENEXT:
+ case ComCtl32.MCHT.CALENDARDATENEXT:
return HitArea.NextMonthDate;
- case NativeMethods.MCHT_CALENDARDATEPREV:
+ case ComCtl32.MCHT.CALENDARDATEPREV:
return HitArea.PrevMonthDate;
- case NativeMethods.MCHT_CALENDARDAY:
+ case ComCtl32.MCHT.CALENDARDAY:
return HitArea.DayOfWeek;
- case NativeMethods.MCHT_CALENDARWEEKNUM:
+ case ComCtl32.MCHT.CALENDARWEEKNUM:
return HitArea.WeekNumbers;
- case NativeMethods.MCHT_TODAYLINK:
+ case ComCtl32.MCHT.TODAYLINK:
return HitArea.TodayLink;
default:
return HitArea.Nowhere;
@@ -1439,9 +1442,10 @@ private Size GetMinReqRect()
///
/// Used internally to get the minimum size needed to display the
- /// MonthCalendar. This is needed because
- /// NativeMethods.MCM_GETMINREQRECT returns an incorrect value if showToday
- /// is set to false. If updateRows is true, then the
+ /// MonthCalendar. This is needed because
+ /// ComCtl32.MCM.GETMINREQRECT
+ /// returns an incorrect value if showToday
+ /// is set to false. If updateRows is true, then the
/// number of rows will be updated according to height.
///
private Size GetMinReqRect(int newDimensionLength, bool updateRows, bool updateCols)
@@ -1487,7 +1491,7 @@ private Size GetMinReqRect(int newDimensionLength, bool updateRows, bool updateC
//
if (IsHandleCreated)
{
- int maxTodayWidth = unchecked((int)(long)SendMessage(NativeMethods.MCM_GETMAXTODAYWIDTH, 0, 0));
+ int maxTodayWidth = unchecked((int)(long)SendMessage((int)ComCtl32.MCM.GETMAXTODAYWIDTH, 0, 0));
if (maxTodayWidth > minSize.Width)
{
minSize.Width = maxTodayWidth;
@@ -1505,9 +1509,9 @@ private SelectionRange GetMonthRange(int flag)
{
NativeMethods.SYSTEMTIMEARRAY sa = new NativeMethods.SYSTEMTIMEARRAY();
SelectionRange range = new SelectionRange();
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_GETMONTHRANGE, flag, sa);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.GETMONTHRANGE, flag, sa);
- NativeMethods.SYSTEMTIME st = new NativeMethods.SYSTEMTIME
+ Kernel32.SYSTEMTIME st = new Kernel32.SYSTEMTIME
{
wYear = sa.wYear1,
wMonth = sa.wMonth1,
@@ -1551,35 +1555,39 @@ private int GetPreferredWidth(int width, bool updateCols)
///
public HitTestInfo HitTest(int x, int y)
{
- NativeMethods.MCHITTESTINFO mchi = new NativeMethods.MCHITTESTINFO
+ ComCtl32.MCHITTESTINFO mchi = new ComCtl32.MCHITTESTINFO
{
- pt_x = x,
- pt_y = y,
- cbSize = Marshal.SizeOf()
+ pt = new POINT
+ {
+ x = x,
+ y = y
+ },
+ st = new Kernel32.SYSTEMTIME(),
+ cbSize = Marshal.SizeOf()
};
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_HITTEST, 0, mchi);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.HITTEST, 0, ref mchi);
// If the hit area has an associated valid date, get it
//
HitArea hitArea = GetHitArea(mchi.uHit);
if (HitTestInfo.HitAreaHasValidDateTime(hitArea))
{
- NativeMethods.SYSTEMTIME sys = new NativeMethods.SYSTEMTIME
+ Kernel32.SYSTEMTIME sys = new Kernel32.SYSTEMTIME
{
- wYear = mchi.st_wYear,
- wMonth = mchi.st_wMonth,
- wDayOfWeek = mchi.st_wDayOfWeek,
- wDay = mchi.st_wDay,
- wHour = mchi.st_wHour,
- wMinute = mchi.st_wMinute,
- wSecond = mchi.st_wSecond,
- wMilliseconds = mchi.st_wMilliseconds
+ wYear = mchi.st.wYear,
+ wMonth = mchi.st.wMonth,
+ wDayOfWeek = mchi.st.wDayOfWeek,
+ wDay = mchi.st.wDay,
+ wHour = mchi.st.wHour,
+ wMinute = mchi.st.wMinute,
+ wSecond = mchi.st.wSecond,
+ wMilliseconds = mchi.st.wMilliseconds
};
- return new HitTestInfo(new Point(mchi.pt_x, mchi.pt_y), hitArea, DateTimePicker.SysTimeToDateTime(sys));
+ return new HitTestInfo(new Point(mchi.pt.x, mchi.pt.y), hitArea, DateTimePicker.SysTimeToDateTime(sys));
}
else
{
- return new HitTestInfo(new Point(mchi.pt_x, mchi.pt_y), hitArea);
+ return new HitTestInfo(new Point(mchi.pt.x, mchi.pt.y), hitArea);
}
}
@@ -1622,21 +1630,21 @@ protected override void OnHandleCreated(EventArgs e)
SetSelRange(selectionStart, selectionEnd);
if (maxSelectionCount != DEFAULT_MAX_SELECTION_COUNT)
{
- SendMessage(NativeMethods.MCM_SETMAXSELCOUNT, maxSelectionCount, 0);
+ SendMessage((int)ComCtl32.MCM.SETMAXSELCOUNT, maxSelectionCount, 0);
}
AdjustSize();
if (todayDateSet)
{
- NativeMethods.SYSTEMTIME st = DateTimePicker.DateTimeToSysTime(todayDate);
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_SETTODAY, 0, st);
+ Kernel32.SYSTEMTIME st = DateTimePicker.DateTimeToSysTime(todayDate);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.SETTODAY, 0, ref st);
}
- SetControlColor(NativeMethods.MCSC_TEXT, ForeColor);
- SetControlColor(NativeMethods.MCSC_MONTHBK, BackColor);
- SetControlColor(NativeMethods.MCSC_TITLEBK, titleBackColor);
- SetControlColor(NativeMethods.MCSC_TITLETEXT, titleForeColor);
- SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, trailingForeColor);
+ SetControlColor(ComCtl32.MCSC.TEXT, ForeColor);
+ SetControlColor(ComCtl32.MCSC.MONTHBK, BackColor);
+ SetControlColor(ComCtl32.MCSC.TITLEBK, titleBackColor);
+ SetControlColor(ComCtl32.MCSC.TITLETEXT, titleForeColor);
+ SetControlColor(ComCtl32.MCSC.TRAILINGTEXT, trailingForeColor);
int firstDay;
if (firstDayOfWeek == Day.Default)
@@ -1647,12 +1655,12 @@ protected override void OnHandleCreated(EventArgs e)
{
firstDay = (int)firstDayOfWeek;
}
- SendMessage(NativeMethods.MCM_SETFIRSTDAYOFWEEK, 0, firstDay);
+ SendMessage((int)ComCtl32.MCM.SETFIRSTDAYOFWEEK, 0, firstDay);
SetRange();
if (scrollChange != DEFAULT_SCROLL_CHANGE)
{
- SendMessage(NativeMethods.MCM_SETMONTHDELTA, scrollChange, 0);
+ SendMessage((int)ComCtl32.MCM.SETMONTHDELTA, scrollChange, 0);
}
SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(MarshaledUserPreferenceChanged);
@@ -1684,6 +1692,13 @@ protected virtual void OnDateSelected(DateRangeEventArgs drevent)
onDateSelected?.Invoke(this, drevent);
}
+ protected override void OnGotFocus(EventArgs e)
+ {
+ base.OnGotFocus(e);
+
+ AccessibilityObject.RaiseAutomationEvent(NativeMethods.UIA_AutomationFocusChangedEventId);
+ }
+
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
@@ -1693,13 +1708,13 @@ protected override void OnFontChanged(EventArgs e)
protected override void OnForeColorChanged(EventArgs e)
{
base.OnForeColorChanged(e);
- SetControlColor(NativeMethods.MCSC_TEXT, ForeColor);
+ SetControlColor(ComCtl32.MCSC.TEXT, ForeColor);
}
protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);
- SetControlColor(NativeMethods.MCSC_MONTHBK, BackColor);
+ SetControlColor(ComCtl32.MCSC.MONTHBK, BackColor);
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -1938,6 +1953,13 @@ private IntPtr RequestBuffer(int reqSize)
return mdsBuffer;
}
+ ///
+ /// Sends a Win32 message to this control. If the control does not yet
+ /// have a handle, it will be created.
+ ///
+ private IntPtr SendMessage(int msg, int wparam, ref ComCtl32.MCGRIDINFO lparam) =>
+ ComCtl32.SendMessage(new HandleRef(this, Handle), msg, wparam, ref lparam);
+
///
/// Overrides Control.SetBoundsCore to enforce auto-sizing.
///
@@ -1974,11 +1996,11 @@ protected override void SetBoundsCore(int x, int y, int width, int height, Bound
///
/// If the handle has been created, this applies the color to the control
///
- private void SetControlColor(int colorIndex, Color value)
+ private void SetControlColor(ComCtl32.MCSC colorIndex, Color value)
{
if (IsHandleCreated)
{
- SendMessage(NativeMethods.MCM_SETCOLOR, colorIndex, ColorTranslator.ToWin32(value));
+ SendMessage((int)ComCtl32.MCM.SETCOLOR, (int)colorIndex, ColorTranslator.ToWin32(value));
}
}
@@ -2020,7 +2042,7 @@ private void SetRange(DateTime minDate, DateTime maxDate)
NativeMethods.SYSTEMTIMEARRAY sa = new NativeMethods.SYSTEMTIMEARRAY();
flag |= NativeMethods.GDTR_MIN | NativeMethods.GDTR_MAX;
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(minDate);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(minDate);
sa.wYear1 = sys.wYear;
sa.wMonth1 = sys.wMonth;
sa.wDayOfWeek1 = sys.wDayOfWeek;
@@ -2031,7 +2053,7 @@ private void SetRange(DateTime minDate, DateTime maxDate)
sa.wDayOfWeek2 = sys.wDayOfWeek;
sa.wDay2 = sys.wDay;
- if ((int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_SETRANGE, flag, sa) == 0)
+ if ((int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.SETRANGE, flag, sa) == 0)
{
throw new InvalidOperationException(string.Format(SR.MonthCalendarRange, minDate.ToShortDateString(), maxDate.ToShortDateString()));
}
@@ -2173,7 +2195,7 @@ private void SetSelRange(DateTime lower, DateTime upper)
{
NativeMethods.SYSTEMTIMEARRAY sa = new NativeMethods.SYSTEMTIMEARRAY();
- NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(lower);
+ Kernel32.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(lower);
sa.wYear1 = sys.wYear;
sa.wMonth1 = sys.wMonth;
sa.wDayOfWeek1 = sys.wDayOfWeek;
@@ -2183,7 +2205,7 @@ private void SetSelRange(DateTime lower, DateTime upper)
sa.wMonth2 = sys.wMonth;
sa.wDayOfWeek2 = sys.wDayOfWeek;
sa.wDay2 = sys.wDay;
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_SETSELRANGE, 0, sa);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.SETSELRANGE, 0, sa);
}
if (changed)
@@ -2286,12 +2308,16 @@ private void UpdateTodayDate()
{
if (IsHandleCreated)
{
- NativeMethods.SYSTEMTIME st = null;
+
if (todayDateSet)
{
- st = DateTimePicker.DateTimeToSysTime(todayDate);
+ Kernel32.SYSTEMTIME st = DateTimePicker.DateTimeToSysTime(todayDate);
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.SETTODAY, 0, ref st);
+ }
+ else
+ {
+ UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), (int)ComCtl32.MCM.SETTODAY, 0, IntPtr.Zero);
}
- UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.MCM_SETTODAY, 0, st);
}
}
@@ -2328,6 +2354,9 @@ private void WmDateChanged(ref Message m)
AccessibilityNotifyClients(AccessibleEvents.NameChange, -1);
AccessibilityNotifyClients(AccessibleEvents.ValueChange, -1);
+ MonthCalendarAccessibleObject calendarAccessibleObject = (MonthCalendarAccessibleObject)AccessibilityObject;
+ calendarAccessibleObject.RaiseAutomationEventForChild(NativeMethods.UIA_AutomationFocusChangedEventId, selectionStart, selectionEnd);
+
//subhag
if (start.Ticks < minDate.Ticks || end.Ticks < minDate.Ticks)
{
@@ -2629,159 +2658,5 @@ public enum HitArea
///
TodayLink = 12,
}
-
- [ComVisible(true)]
- internal class MonthCalendarAccessibleObject : ControlAccessibleObject
- {
- private readonly MonthCalendar calendar;
-
- public MonthCalendarAccessibleObject(Control owner)
- : base(owner)
- {
- calendar = owner as MonthCalendar;
- }
-
- public override AccessibleRole Role
- {
- get
- {
- if (calendar != null)
- {
- AccessibleRole role = calendar.AccessibleRole;
- if (role != AccessibleRole.Default)
- {
- return role;
- }
- }
- return AccessibleRole.Table;
- }
- }
-
- public override string Help
- {
- get
- {
- var help = base.Help;
- if (help != null)
- {
- return help;
- }
- else
- {
- if (calendar != null)
- {
- return calendar.GetType().Name + "(" + calendar.GetType().BaseType.Name + ")";
- }
- }
- return string.Empty;
- }
- }
-
- public override string Name
- {
- get
- {
- string name = base.Name;
- if (name != null)
- {
- return name;
- }
-
- if (calendar != null)
- {
-
- if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_MONTH)
- {
- if (System.DateTime.Equals(calendar.SelectionStart.Date, calendar.SelectionEnd.Date))
- {
- name = string.Format(SR.MonthCalendarSingleDateSelected, calendar.SelectionStart.ToLongDateString());
- }
- else
- {
- name = string.Format(SR.MonthCalendarRangeSelected, calendar.SelectionStart.ToLongDateString(), calendar.SelectionEnd.ToLongDateString());
- }
- }
- else if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_YEAR)
- {
- if (System.DateTime.Equals(calendar.SelectionStart.Month, calendar.SelectionEnd.Month))
- {
- name = string.Format(SR.MonthCalendarSingleDateSelected, calendar.SelectionStart.ToString("y"));
- }
- else
- {
- name = string.Format(SR.MonthCalendarRangeSelected, calendar.SelectionStart.ToString("y"), calendar.SelectionEnd.ToString("y"));
- }
- }
- else if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_DECADE)
- {
- if (System.DateTime.Equals(calendar.SelectionStart.Year, calendar.SelectionEnd.Year))
- {
- name = string.Format(SR.MonthCalendarSingleYearSelected, calendar.SelectionStart.ToString("yyyy"));
- }
- else
- {
- name = string.Format(SR.MonthCalendarYearRangeSelected, calendar.SelectionStart.ToString("yyyy"), calendar.SelectionEnd.ToString("yyyy"));
- }
- }
- else if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_CENTURY)
- {
- name = string.Format(SR.MonthCalendarSingleDecadeSelected, calendar.SelectionStart.ToString("yyyy"));
- }
- }
- return name;
- }
- }
-
- public override string Value
- {
- get
- {
- var value = string.Empty;
- try
- {
- if (calendar != null)
- {
- if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_MONTH)
- {
- if (System.DateTime.Equals(calendar.SelectionStart.Date, calendar.SelectionEnd.Date))
- {
- value = calendar.SelectionStart.ToLongDateString();
- }
- else
- {
- value = string.Format("{0} - {1}", calendar.SelectionStart.ToLongDateString(), calendar.SelectionEnd.ToLongDateString());
- }
- }
- else if (calendar.mcCurView == NativeMethods.MONTCALENDAR_VIEW_MODE.MCMV_YEAR)
- {
- if (System.DateTime.Equals(calendar.SelectionStart.Month, calendar.SelectionEnd.Month))
- {
- value = calendar.SelectionStart.ToString("y");
- }
- else
- {
- value = string.Format("{0} - {1}", calendar.SelectionStart.ToString("y"), calendar.SelectionEnd.ToString("y"));
- }
- }
- else
- {
- value = string.Format("{0} - {1}", calendar.SelectionRange.Start.ToString(), calendar.SelectionRange.End.ToString());
- }
- }
- }
- catch
- {
- value = base.Value;
- }
- return value;
- }
- set
- {
- base.Value = value;
- }
- }
- }
-
} // end class MonthCalendar
}
-