【问题标题】:C# How to catch WIN32 0XFFFF exception when calling P/Invoke SendmessageC# 如何在调用 P/Invoke Sendmessage 时捕获 WIN32 0XFFFF 异常
【发布时间】:2023-04-10 15:23:01
【问题描述】:

当我尝试在 WPF 中使用非托管代码时。例如SendMessage(IntPtr hWnd, int Msg, int wParam, ref TOOLINFO toolInfo),此函数可能会直接返回TOOLINFO中lpszText的0XFFFF,应用程序直接崩溃。我参考了 MSDN,发现这是一个 ERROR_ILLEGAL_CHARACTER 错误。所以我想问一下:我如何才能在托管代码中捕捉到这种错误,或者我如何才能返回 TOOLINFO 一个好的结果。

    struct TOOLINFO
    {
        public int cbSize;
        public int uFlags;
        public IntPtr hwnd;
        public IntPtr uId;
        public RECT rect;
        public IntPtr hinst;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpszText;
        public IntPtr lParam;
    }
[DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref TOOLINFO toolInfo);

【问题讨论】:

  • 您要发送什么消息?解决方案仍然很简单:public string lpszText; 使其成为 public IntPtr lpszText;,然后用 Marshal.PtrToStringAuto() 编组字符串(在 try/catch 中)
  • 我在ToolInfo 的描述中看到您必须分配缓冲区。您可以尝试使用具有预分配长度的StringBuilder()StringBuilder lpszText;,然后在发送消息之前lpszText = new StringBuilder(200)
  • wParam 应该是 IntPtr

标签: c# error-handling memory-leaks pinvoke


【解决方案1】:

你要发送什么消息?

解决办法还是很简单的:

public string lpszText; 

改成:

public IntPtr lpszText; 

然后用Marshal.PtrToStringAuto() 编组字符串(在try/catch 内)

但我在ToolInfo 的描述中看到您必须分配缓冲区。您可以尝试使用具有预分配长度的StringBuilder()

public StringBuilder lpszText;

然后在发送消息之前

tt.lpszText = new StringBuilder(200);

【讨论】:

  • 感谢您的回答。我发送的消息是 TTM_ENUMTOOLSA,它用于枚举 tooltip ctrl 中的所有工具。以下是我的解决方案:StringBuilder builder = new StringBuilder(1024); builder.Append('\0'); builder.Append('*', builder.Capacity - 8); TOOLINFO ti = new TOOLINFO(); ti.lpszText = builder.ToString(); ti.cbSize = Marshal.SizeOf(ti); WIN32API.SendMessage(wnd, TTM_ENUMTOOLSA, i, ref ti);至于你的“Intptr lpszText”解决方案,我之前已经试过了。它将返回 0XFFFFFFFF,因此在某些情况下无法读取字符串。
  • 如果我在 TOOLINFO 中对 lpszText 使用字符串,在某些情况下应用程序会直接崩溃,因为 lpszText 的位置已损坏(0XFFFFFFFF)。 WPF 无法捕获异常,因为此异常是本机异常。我不知道如何在托管代码中捕获 WIN32 异常。
  • @Qiao 你必须使用StringBuilder,而不是string。请注意,您不能使用这些消息来获取有关其他进程的工具栏的信息(请参阅此处的 cmets:stackoverflow.com/questions/24395786/…
猜你喜欢
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2011-05-02
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多