该声明是错误的,wParam和lParam参数是IntPtr,不长。
由于您尝试发送字符串,因此会出现复杂情况。如果目标窗口是Unicode启用或不启用,那么重要。有两个版本的SendMessage,SendMessageA()和SendMessageW()。如果程序过期并使用8位字符串而不是UTF-16编码字符串,则需要使用前者。
你可以通过使用Spy ++找到。使用取景器工具选择应用程序的窗口。在General属性选项卡中,您会看到“Window proc”。它会说(Unicode)该窗口是否启用了Unicode。如果你没有看到它,那么字符串必须被转换为8位字符。
要生成需要传递的字符串指针,可以使用Marshal.StringToHGlobalAnsi或StringToHGlobalUni(分别为8位和Unicode)。然而,您可以玩一些技巧让P/Invoke编组人员为您翻译字符串。在通话结束后,您不必麻烦地取出字符串,这让您省却麻烦。对于ANSI版本,你可以宣布这样的API函数:
[DllImport("user32.dll", CharSet = CharSet.Ansi, EntryPoint = "SendMessageA", ExactSpelling = true)]
private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);
和Unicode版本是这样的:
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW", ExactSpelling = true)]
private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);
最后一点:这是行不通的,是如果该窗口属于另一个应用程序,你会崩溃它。你传递的指针值只在你自己的进程中有效,而不在C++进程中。要解决该问题,您必须在目标进程中分配内存,以便指针有效。这需要OpenProcess获得进程的句柄,VirtualAllocEx()在目标进程中分配内存,足以存储字符串WriteProcessMemory以写入字符串。现在,您可以调用SendMessage(),使用用IntPtr声明的版本作为wParam和lParam参数,传递从VirtualAllocEx获得的值。接下来使用VirtualFreeEx()释放内存和CloseHandle进行清理。或者如果你经常这样做,下次保持记忆。
很多P/Invoke在那里出错。更不用说安全问题了,WriteProcessMemory需要管理员权限,UAC提升是必需的。
我相信'MarshalAs'属性是有序的。 – ChaosPandion 2010-06-22 15:13:03