C# 向MonthCalendar发送MCM_GETSELRANGE消息的P/Invoke签名是什么?

C# 向MonthCalendar发送MCM_GETSELRANGE消息的P/Invoke签名是什么?,c#,winapi,pinvoke,comctl32,C#,Winapi,Pinvoke,Comctl32,我正在尝试将windows消息发送到标准的MonthCalendar。根据文档,我尝试了以下方法,但没有成功(日期返回为零[因为在中,日期没有设置为零以外的任何值],但是我确实得到了一个非零的返回值,这似乎表明它成功了?): pinvoke.net似乎没有任何关于如何命名的建议 谢谢很明显,您正在将此消息发送到属于另一个进程的窗口。这不能像这样工作,SYSTEMTIME数组仅在您的进程中有效,而在另一个进程中无效。这使代码变得相当复杂,您必须在目标进程中分配内存 我将简要描述所需的pinvoke

我正在尝试将windows消息发送到标准的MonthCalendar。根据文档,我尝试了以下方法,但没有成功(日期返回为零[因为在中,日期没有设置为零以外的任何值],但是我确实得到了一个非零的返回值,这似乎表明它成功了?):

pinvoke.net似乎没有任何关于如何命名的建议


谢谢

很明显,您正在将此消息发送到属于另一个进程的窗口。这不能像这样工作,SYSTEMTIME数组仅在您的进程中有效,而在另一个进程中无效。这使代码变得相当复杂,您必须在目标进程中分配内存

我将简要描述所需的pinvoke,从api函数名中搜索示例代码应该不会有问题。首先,需要GetWindowThreadProcessId()来获取拥有该窗口的进程的ID。OpenProcess()打开它的句柄。VirtualAllocEx()来分配内存


SendMessage()以像以前一样发送消息,传递从VirtualAllocEx()获得的指针。ReadProcessMemory()从进程中读取数组内容。使用VirtualFreeEx()和CloseHandle()进行清理。顺便说一句,你不大可能会遇到安全问题,这些都是特权功能

+1也要小心跨越位边界。我甚至不确定当一个进程是32位而另一个是64位时是否可以使用这种方法。即使可能,也需要一些技巧。谢谢你,汉斯!您是对的,我们这样做的窗口不属于我们的流程(我们正在开发一个自动化框架)。在与标准ListView和TreeView控件交互时,我们实际上必须做一些非常类似的事情,以便我们可以模拟这些控件。顺便问一下,您是如何确定这只在MonthCalendar存在的过程中有效的?还是个人经验?我要求将来参考其他控件。这是任何需要传递指针的消息的情况。很多LV和TV信息都是这样。看看它。
using System;
using System.Runtime.InteropServices;

namespace GetSelRange
{
    class Program
    {
        static void Main(string[] args)
        {
            IntPtr targetWindowHandle = new IntPtr(68684130);
            SYSTEMTIME[] dateRange = new SYSTEMTIME[2];
            IntPtr success = SendMessage(targetWindowHandle, MCM_GETSELRANGE, IntPtr.Zero, dateRange);
        }

        #region Win32API

        const uint MCM_FIRST = 0x1000;
        const uint MCM_GETSELRANGE = MCM_FIRST + 5;

        [StructLayout(LayoutKind.Sequential)]
        private struct SYSTEMTIME
        {
            [MarshalAs(UnmanagedType.U2)]
            public ushort Year;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Month;
            [MarshalAs(UnmanagedType.U2)]
            public ushort DayOfWeek;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Day;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Hour;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Minute;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Second;
            [MarshalAs(UnmanagedType.U2)]
            public ushort Milliseconds;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, SYSTEMTIME[] lParam);

        #endregion
    }
}