1

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

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
    }
}

pinvoke.net 似乎没有关于如何调用它的任何建议。

谢谢

4

1 回答 1

2

显然,您将其发送到属于另一个进程的窗口。这不能像这样工作,SYSTEMTIME 数组只在您的进程中有效,而不是另一个。这使代码相当复杂,您必须在目标进程中分配内存。

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

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

于 2011-05-02T23:16:42.217 回答