c# - Bitmap.FromHbitmap erroring when called over RDP -
our application cursor manipulation enable "relatively" nice drag drop animation on winforms (at time wpf wasn't option). when using application on rdp session throws generic gdi+ exception.
the method throws this:
[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); }
specifically line:
bitmap bmp = bitmap.fromhbitmap(iinfo.hbmcolor);
when debugging hbmcolor
0
, means when running on rdp call geticoninfo
doesn't return required information.
i can check 0
, handle special case, there can make work on rdp normally?
edit
here's iconinfo
structure:
[structlayout(layoutkind.sequential)] struct iconinfo { public bool ficon; // specifies whether structure defines icon or cursor. value of true specifies // icon; false specifies cursor. public int32 xhotspot; // specifies x-coordinate of cursor's hot spot. if structure defines icon, hot // spot in center of icon, , member ignored. public int32 yhotspot; // specifies y-coordinate of cursor's hot spot. if structure defines icon, hot // spot in center of icon, , member ignored. public intptr hbmmask; // (hbitmap) specifies icon bitmask bitmap. if structure defines black , white icon, // bitmask formatted upper half icon , bitmask , lower half // icon xor bitmask. under condition, height should multiple of two. if // structure defines color icon, mask defines , bitmask of icon. public intptr hbmcolor; // (hbitmap) handle icon color bitmap. member can optional if // structure defines black , white icon. , bitmask of hbmmask applied srcand // flag destination; subsequently, color bitmap applied (using xor) // destination using srcinvert flag. }
from habjan's answer below i've added comments p/invoke structure above. looks hbmmask
contains bitmap reference i'm after, i'm afraid bit manipulation skills rather rusty. when p/invoke says upper half / lower half - inferring to?
is possible black , white bitmap this?
i think due rdp color depth. if cursor black , white (via rdp), not hbmcolor
value parameter optional.
msdn says:
hbmcolor type: hbitmap
description: handle icon color bitmap. member can optional if structure defines black , white icon. , bitmask of hbmmask applied srcand flag destination; subsequently, color bitmap applied (using xor) destination using srcinvert flag.
edit:
public static bitmap bitmapfromcursor(cursor cur) { iconinfo iinfo; geticoninfo(cur.handle, out iinfo); bitmap bmpcolor = null; if (iinfo.hbmcolor != intptr.zero) { bmpcolor = bitmap.fromhbitmap(iinfo.hbmcolor); } else { bmpcolor = new bitmap(w,h); // fill bmpcolor white colour } bitmap bmpmask = bitmap.fromhbitmap(iinfo.hbmmask); deleteobject(iinfo.hbmcolor); deleteobject(iinfo.hbmmask); // apply mask bitmap color bitmap: // http://stackoverflow.com/questions/3654220/alpha-masking-in-c-sharp-system-drawing 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); }
... did not test code, it's give brief info do...
Comments
Post a Comment