我正试图将MCM_GETSELRANGE窗口消息发送到标准的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似乎没有任何关于如何命名的建议。
谢谢
显然,您正在将此发送到属于另一个进程的窗口。这不能像这样工作,SYSTEMTIME数组只在您的进程中有效,而在其他进程中无效。这会使代码相当复杂,您必须在目标进程中分配内存。
我将简要描述所需的pinvoke,您应该可以毫不费力地从api函数名称中搜索示例代码。首先,您需要GetWindowThreadProcessId()来获取拥有窗口的进程的ID。OpenProcess()打开它的句柄。VirtualAllocEx()用于分配内存。SendMessage()像之前一样发送消息,传递从VirtualAllocEx()获得的指针。ReadProcessMemory()从进程中读取数组内容。使用VirtualFreeEx()和CloseHandle()进行清理。你不太可能会遇到安全问题,顺便说一句,这些都是特权功能。