- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在处理 What's wrong with this unmanaged code in C#? 中描述的问题时我偶然发现了参数 wParam 及其类型 IntPtr for SendMessage 功能。
原始函数的代码是这样的
var length = (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
var buff = new char[length + 1];
var iptr = Marshal.AllocHGlobal(buff.Length * sizeof(char));
SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)(length + 1), iptr);
Marshal.Copy(iptr, buff, 0, length + 1);
Marshal.FreeHGlobal(iptr);
我不喜欢 allocation 和 Copy 部分,所以我尝试用
var length = 1 + (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
var buffer = new char[length];
var bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
var lengthHandle = GCHandle.Alloc(length, GCHandleType.Pinned);
SendMessage(hWnd, WindowMessage.WM_GETTEXT, lengthHandle.AddrOfPinnedObject(), bufferHandle.AddrOfPinnedObject());
bufferHandle.Free();
lengthHandle.Free();
事实证明,这是行不通的,因为参数 wParam 不是指针(可以从它的 IntPtr 类型得出结论)。
关于WM_GETTEXT消息的具体描述可以在MSDN上找到(感谢 SO 社区指出这一点)这导致我们遵循以下代码
var length = 1 + (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
var buffer = new char[length];
var bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)length, bufferHandle.AddrOfPinnedObject());
bufferHandle.Free();
是否有针对特定消息专门化或缩小范围的 SendMessage 函数的库或签名集合?
不要误会我的意思,PInvoke 已经通过将此功能提供给托管世界做了很多工作,我很欣赏这一点,但是单一方法的多用途性质使其更难使用。
最佳答案
您可以从 PInvoke page 复制它们, 但请注意,我经常必须修改 PInvoke 定义(它们通常是面向 32 位的,因此他们经常假设 sizeof(IntPtr) == sizeof(int)
,这是非常错误的!,或者他们使用“过时的”ANSI API,但现在应该始终使用 Unicode API...举个例子,在链接页面中,SendMessage
和 [MarshalAs(UnmanagedType.LPStr) ] string lParam
使用的是 ANSI API,而带有 Int32 wParam
的将在 64 位上中断)
您的代码可以更改为:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);
var length = (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
var sb = new StringBuilder(length + 1);
SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)sb.Capacity, sb);
string str = sb.ToString();
利用 pinvoke 子系统“支持”StringBuilder
来编码字符串这一事实。
关于c# - SendMessage 中的误导参数类型 (... IntPtr wParam ...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43778985/
在 Delphi 6 中 WPARAM 被声明为已签名: WPARAM = Longint; 在 Delphi 2010 中,WPARAM 被声明为已签名: WPARAM = INT_PTR; 但在
我正在寻找一种将对象(在我的例子中为 vector)作为 WPARAM 传递的方法采用 C++11 风格。 我发现的教程使用了 C 风格的转换或 reinterpret_cast传递一个指向对象的指针
我正在尝试获取由消息的 wParam 属性中返回的整数表示的实际系统消息。有没有办法做到这一点或可以实现这一目标的功能? 最佳答案 这是关于 WndProc 的问题吗?你说的是哪条消息? LRESUL
下面是整体代码: LRESULT WmPointerAPI::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HRES
如果我使用计算机鼠标滚动窗口,我会得到以下 Spy++ 结果: fwKeys: 0, zDelta: -120 我需要通过代码模拟鼠标滚轮事件,所以我像这样使用 PostMessage: Public
出于不相关的原因,我在 C# 应用程序的 WinForm 中捕获 WM_SYSCOMMAND 消息。有时,我的处理程序会收到带有 wParam 0xF063 的 WM_SYSCOMMAND 消息。 文
我目前正在尝试实现 http://www.codeproject.com/KB/threads/winspy.aspx 中的一些代码(子类化部分)到我的项目中,但遇到一些问题,我调试了 dll,似乎当
我有一个来自 WM_KEYDOWN 消息的 pMsg->wParam,我想将它转换成一个 CString。我该怎么做? 我试过下面的代码: TCHAR ch[2]; ch[0] = pMsg->wPa
在处理 What's wrong with this unmanaged code in C#? 中描述的问题时我偶然发现了参数 wParam 及其类型 IntPtr for SendMessage
在查看 RAWINPUT 结构的 MSDN 文档时,它有以下声明: typedef struct tagRAWINPUT { RAWINPUTHEADER header; union {
尝试这样做: 代码: WPARAM wParam = MAKEWPARAM(MK_LBUTTON, MK_RBUTTON, MK_SHIFT, MK_CONTROL, MK_MBUTTON); Pos
我知道 wParam 和 lParam 是(我相信是 32 位)特定于当时正在传递的消息的信息位,但是有什么方法可以分辨每条消息放入这两个消息中的内容吗? 我在某处读到 wParam 是 16 位而
一个标准的窗口过程函数采用这个原型(prototype): LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM l
将值传递给同时接受 WPARAM 和 LPARAM 参数的函数时,我传递其中的哪一个参数是否重要?有人告诉我,如果我使用 Windows x64,我应该使用 WPARAM;这是真的? 最佳答案 发送消
我知道我在这里很懒,我应该自己搜索头文件,但是 LPARAM 和 WPARAM 参数的实际类型是什么?它们是指针,还是四字节整数?我正在编写一些 C# 互操作代码,并希望确保它能够在 x64 系统上运
我需要填充结构的成员: typedef struct SPEVENT { SPEVENTENUM eEventId : 16; SPEVENTLPARAMTYPE el
我有点困惑。当一个文件被拖到一个带有 WS_EX_ACCEPTFILES 标记的窗口上时,它会将一个 PostMessage 放入 WndProc 函数中,该函数将 UINT 消息设置为 WM_DRO
我正在尝试调用 win32api.SendMessage()通过我的 Python 应用程序(即发送应用程序)。 接收应用程序的 API 声明消息的格式为:::SendMessage(, , (WPA
我在 C# 中导入 WinApi 函数、编写回调等 ( example ) 并且总是想知道: 它们是什么意思? LRESULT 作为最后的结果? W参数? L-参数 ? 如何安全地“包裹”它们 WPA
这个问题在这里已经有了答案: How should I pass negative values to SendMessage and Perform when they expect a Nativ
我是一名优秀的程序员,十分优秀!