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