【发布时间】:2014-06-10 10:07:17
【问题描述】:
我们的应用程序进行了一些光标操作,以在 WinForms 上启用“相对”漂亮的拖放动画(当时 WPF 不是一个选项)。但是,当通过 RDP 会话使用应用程序时,它会引发通用 GDI+ 异常。
抛出这个的方法是这样的:
[DllImport("user32")]
private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO pIconInfo);
[DllImport("user32.dll")]
private static extern IntPtr LoadCursorFromFile(string lpFileName);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
public static Bitmap BitmapFromCursor(Cursor cur)
{
ICONINFO iInfo;
GetIconInfo(cur.Handle, out iInfo);
Bitmap bmp = Bitmap.FromHbitmap(iInfo.hbmColor);
DeleteObject(iInfo.hbmColor);
DeleteObject(iInfo.hbmMask);
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
Bitmap dstBitmap = new Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0);
bmp.UnlockBits(bmData);
return new Bitmap(dstBitmap);
}
具体是一行:
Bitmap bmp = Bitmap.FromHbitmap(iInfo.hbmColor);
当调试 hbmColor 时为 0,这意味着当通过 RDP 运行时,对 GetIconInfo 的调用不会返回所需的信息。
我可以检查0 并处理特殊情况,但是我可以做些什么来像往常一样通过 RDP 进行这项工作?
编辑
这是ICONINFO 结构:
[StructLayout(LayoutKind.Sequential)]
struct ICONINFO
{
public bool fIcon; // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies
// an icon; FALSE specifies a cursor.
public Int32 xHotspot; // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot
// spot is always in the center of the icon, and this member is ignored.
public Int32 yHotspot; // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot
// spot is always in the center of the icon, and this member is ignored.
public IntPtr hbmMask; // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon,
// this bitmask is formatted so that the upper half is the icon AND bitmask and the lower half is
// the icon XOR bitmask. Under this condition, the height should be an even multiple of two. If
// this structure defines a color icon, this mask only defines the AND bitmask of the icon.
public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this
// structure defines a black and white icon. The AND bitmask of hbmMask is applied with the SRCAND
// flag to the destination; subsequently, the color bitmap is applied (using XOR) to the
// destination by using the SRCINVERT flag.
}
根据下面 HABJAN 的回答,我已将 p/Invoke 中的 cmets 添加到上面的结构中。看起来hbmMask 包含我所追求的位图参考,但我担心我的位操作技能相当生疏。当 p/Invoke 说上半部分/下半部分时 - 它在推断什么?
是否可以从中获取黑白位图?
【问题讨论】:
-
你能展示你的'ICONINFO'结构定义吗?
-
忽略 winapi 函数的返回值是一个标准错误。它不是可选的,您没有友好的 .NET 异常来避免麻烦。当 GetIconInfo() 返回 false 时抛出 Win32Exception 以便您知道失败的原因。并修复声明以添加 SetLastError = true。
-
干杯汉斯,这是我需要更熟悉的东西,而不仅仅是从 p/Invoke 复制和粘贴。下次我会记住这一点..