【问题标题】:Getting unexpected CA1901 warning for ChildWindowFromPointEx function收到 ChildWindowFromPointEx 函数的意外 CA1901 警告
【发布时间】:2019-02-24 17:06:03
【问题描述】:

当我在我的 Visual Studio 项目中使用代码分析功能时,我在 ChildWindowFromPointExRealChildWindowFromPoint 的参数类型为 POINT 时收到了意外的 CA1901 警告。

我刚刚定义了一个名为 NativePoint 的结构,其中 XY 字段为 Int32 类型,我'm 用作那些 POINT 参数的等价物。

我了解在 x86 或 x64 下运行时可移植性在值大小方面的含义,但是,在这种情况下,我不确定如何解决此警告,因为我使用的是相同的 NativePoint 其他函数的 POINT 参数的结构,例如:ChildWindowFromPointClientToScreenGetCursorPos 和许多其他函数,并且代码分析不会警告它们,并且它们在运行时可以工作x86 和 x64 进程。

事实上,ChildWindowFromPointChildWindowFromPointEx 似乎只有一个附加参数不同,两者都采用相同的 POINT 结构作为参数,所以我不'不明白为什么 ChildWindowFromPointEx 会警告可移植性问题,而对于 ChildWindowFromPoint 来说一切正常。

我的问题是:在 C# 或 VB.NET 中,如何正确修复(而不是抑制)ChildWindowFromPointExRealChildWindowFromPoint 函数的此警告?也许我需要用不同的字段类型定义另一个不同的 NativePoint 结构,仅用于这两个函数?但是,为什么这两个函数会抛出警告,而 ChildWindowFromPoint 如果两者采用相同的 POINT(我的 NativePoint)结构却不会?

请注意,如果我使用 System.Drawing.Point 结构,这两个函数会收到相同的警告,但仅限于这两个。


[DllImport("user32.dll", EntryPoint="ChildWindowFromPointEx", SetLastError=false)]
public extern static IntPtr ChildWindowFromPointEx(IntPtr hwndParent,
                                              NativePoint point, 
                                                     uint flags);

[DllImport("user32.dll", EntryPoint="RealChildWindowFromPoint", SetLastError=false)]
public extern static IntPtr RealChildWindowFromPoint(IntPtr hwndParent, 
                                                NativePoint point);

[StructLayout(LayoutKind.Sequential)]
public struct NativePoint {
    public int X;
    public int Y;
}

【问题讨论】:

  • 似乎是一个非常虚假的警告(您是否尝试过 HandleRef 而不是 IntPtr?)。微软本身压制了很多论文,你可以在这里看到:referencesource.microsoft.com/#System.Windows.Forms/winforms/…
  • 你应该使用System.Windows.Point而不是定义你自己的结构。
  • @Remy Lebeau 但在评论的最后,我指定使用 System.Drawing.Point 会产生相同的警告。
  • @Simon Mourier 你的意思是 HWND 类型的 hwndParent 参数?是的,它会产生相同的警告。
  • 也许在你的声明中使用internal而不是public(或者private,如果你不打算在别处直接使用这些函数)。在任何情况下你都不应该使用public。如果您导出某些内容,请导出函数的包装器。

标签: c# .net vb.net winapi pinvoke


【解决方案1】:

在负责的分析程序集中四处寻找后,Windows API 文档与分析插件使用的数据集不匹配。

规则认为RealChildWindowFromPoint应该有3个参数,每4字节,ChildWindowFromPointEx在x86上应该有4个参数,每4字节。另一方面,ChildWindowFromPoint 被列为具有预期的一个 4 字节参数和一个 8 字节参数。

确实,以这种方式声明RealChildWindowFromPoint 似乎可以满足代码分析,但我对Windows API 调用约定的了解还不够,无法说明这是否实际上是调用该方法的有效方式:

[DllImport("user32.dll", EntryPoint = "RealChildWindowFromPoint", SetLastError = false)]
public static extern IntPtr RealChildWindowFromPoint(IntPtr hwndParent, int x, int y);

考虑到RealChildWindowFromPointChildWindowFromPointEx 的规则缺少返回值大小以及x64 声明的数据,而ChildWindowFromPoint 的数据是完整的,我认为这只是数据中的错误而不是故意推荐。

【讨论】:

  • 感谢您的回答。也许有人应该向微软团队报告这一切。
猜你喜欢
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
相关资源
最近更新 更多