Embedded Color Cursors

H

H. Williams

I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've been
trying to get theLoadCursor API to work with embedded resources and I am not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 
G

Guest

This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}
 
H

H. Williams

thanks for your reply, but the Cursor class doesn't work with COLOR cursors.
In your code, the line 'return new Cursor(stream)' causes the color cursor
to be converted to black and white. Also the line
'using(Bitmap bm = new Bitmap(stream))' throws a 'System.ArgumentException,
Invalid Parameter Used'
I think the only way to get the cursors in color is to load the cursor and
use reflection to point the current cursor handle to the handle of the color
cursor. This is easy with the LoadCursorFromFile API method because the
cursor files return a handle. However, I don't want to distribute cursors
with my program so I need help on how to get a handle to an embedded
resource.


AndrewEames said:
This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}


H. Williams said:
I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've been
trying to get theLoadCursor API to work with embedded resources and I am
not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long
hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 
J

James Park

Assuming no one comes up with anything better, you could embed the cursor,
write it to a temp file, and then use LoadCursorFromFile on that.

H. Williams said:
thanks for your reply, but the Cursor class doesn't work with COLOR
cursors. In your code, the line 'return new Cursor(stream)' causes the
color cursor to be converted to black and white. Also the line
'using(Bitmap bm = new Bitmap(stream))' throws a
'System.ArgumentException, Invalid Parameter Used'
I think the only way to get the cursors in color is to load the cursor and
use reflection to point the current cursor handle to the handle of the
color cursor. This is easy with the LoadCursorFromFile API method because
the cursor files return a handle. However, I don't want to distribute
cursors with my program so I need help on how to get a handle to an
embedded resource.


AndrewEames said:
This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point
hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't
work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}


H. Williams said:
I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr
LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've been
trying to get theLoadCursor API to work with embedded resources and I am
not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long
hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 
H

H. Williams

That appears to be the only solution.
I found this note:
'The only thing that can't be done as things stand is to instantiate a color
cursor from a .NET resource file without writing it to an intermediate
temporary file on disk. This is because LoadImage (or LoadCursor)
unfortunately does not provide a stream or byte array based overload.'


James Park said:
Assuming no one comes up with anything better, you could embed the cursor,
write it to a temp file, and then use LoadCursorFromFile on that.

H. Williams said:
thanks for your reply, but the Cursor class doesn't work with COLOR
cursors. In your code, the line 'return new Cursor(stream)' causes the
color cursor to be converted to black and white. Also the line
'using(Bitmap bm = new Bitmap(stream))' throws a
'System.ArgumentException, Invalid Parameter Used'
I think the only way to get the cursors in color is to load the cursor
and use reflection to point the current cursor handle to the handle of
the color cursor. This is easy with the LoadCursorFromFile API method
because the cursor files return a handle. However, I don't want to
distribute cursors with my program so I need help on how to get a handle
to an embedded resource.


AndrewEames said:
This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point
hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't
work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}


:

I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr
LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've
been
trying to get theLoadCursor API to work with embedded resources and I
am not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long
hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 
J

James Park

I just tried out another solution, but it's a bit of a pain. Create a
resource file (.rc) that includes the cursor using VC++, create a win32
resource file (.res) from it with Resource Compiler (rc.exe), use the
compiler option /win32res to attach it, and then use LoadCursor in normal
fashion. I used IntPtr instead of string for lpCursorName argument though.

H. Williams said:
That appears to be the only solution.
I found this note:
'The only thing that can't be done as things stand is to instantiate a
color cursor from a .NET resource file without writing it to an
intermediate temporary file on disk. This is because LoadImage (or
LoadCursor) unfortunately does not provide a stream or byte array based
overload.'


James Park said:
Assuming no one comes up with anything better, you could embed the
cursor, write it to a temp file, and then use LoadCursorFromFile on that.

H. Williams said:
thanks for your reply, but the Cursor class doesn't work with COLOR
cursors. In your code, the line 'return new Cursor(stream)' causes the
color cursor to be converted to black and white. Also the line
'using(Bitmap bm = new Bitmap(stream))' throws a
'System.ArgumentException, Invalid Parameter Used'
I think the only way to get the cursors in color is to load the cursor
and use reflection to point the current cursor handle to the handle of
the color cursor. This is easy with the LoadCursorFromFile API method
because the cursor files return a handle. However, I don't want to
distribute cursors with my program so I need help on how to get a handle
to an embedded resource.


This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point
hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't
work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref
ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}


:

I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set
color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr
LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've
been
trying to get theLoadCursor API to work with embedded resources and I
am not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long
hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 
H

H. Williams

Here's my somewhat long solution using the temp file. It's fast, there are
no additional files to include with the program, and it works.

private static IntPtr GetCursorHandle(string sResource)
{
//Load cursor from Manifest Resource to Stream
Stream streamFrom =
Assembly.GetExecutingAssembly().GetManifestResourceStream(sResource);
Stream streamTo =
File.Create(Environment.GetEnvironmentVariable("TEMP")+@"\~cur.tmp");
BinaryReader br = new BinaryReader(streamFrom);
BinaryWriter bw = new BinaryWriter(streamTo);
//Write cursor to temporary file
bw.Write(br.ReadBytes((int)streamFrom.Length));
bw.Flush();
bw.Close();
br.Close();
bw=null;
br=null;
streamFrom.Close();
streamTo.Close();
streamFrom=null;
streamTo=null;
//Load handle of temporary cursor file
IntPtr hwdCursor = LoadCursorFromFile(
Environment.GetEnvironmentVariable("TEMP")+@"\~cur.tmp" );
//Delete temporary cursor file
File.Delete(Environment.GetEnvironmentVariable("TEMP")+@"\~cur.tmp");
return hwdCursor;
}
 
G

Guest

Did you actually try this? The Cursor class does actually work with color
cursors in some circumstances.

The line 'return new Cursor(stream)' is only executed under Windows 2000 on
16 bit displays and as the comment indicates, I dont why this trick works in
that case
Andrew

H. Williams said:
thanks for your reply, but the Cursor class doesn't work with COLOR cursors.
In your code, the line 'return new Cursor(stream)' causes the color cursor
to be converted to black and white. Also the line
'using(Bitmap bm = new Bitmap(stream))' throws a 'System.ArgumentException,
Invalid Parameter Used'
I think the only way to get the cursors in color is to load the cursor and
use reflection to point the current cursor handle to the handle of the color
cursor. This is easy with the LoadCursorFromFile API method because the
cursor files return a handle. However, I don't want to distribute cursors
with my program so I need help on how to get a handle to an embedded
resource.


AndrewEames said:
This works for me
Andrew

public static Cursor LoadColorCursor(string resourceName,Point hotspot)
{
Assembly ass = Assembly.GetCallingAssembly();
Stream stream = ass.GetManifestResourceStream(resourceName);
// In Windows 2000 in 16 bit color mode, the cursor mask doesn't work
properly
// I have no idea why but the simple loading the cursor from the
resource stream
// works in this case - again, I've no idea why!!!
if((Environment.OSVersion.Version.Major < 5 ||
(Environment.OSVersion.Version.Major == 5 &&
Environment.OSVersion.Version.Minor == 0)) &&
GetColorDepth() == 16)

return new Cursor(stream);
else
{
using(Bitmap bm = new Bitmap(stream))
{
NativeMethods.ICONINFO ii = new NativeMethods.ICONINFO();
ii.IsIcon = false;
ii.xHotspot = hotspot.X;
ii.yHotspot = hotspot.Y;
IntPtr imgHandle = bm.GetHbitmap();
try
{
ii.MaskBitmap = imgHandle;
ii.ColorBitmap = imgHandle;
IntPtr handle = SafeNativeMethods.CreateIconIndirect(ref ii);
return new Cursor(handle);
}
finally
{
SafeNativeMethods.DeleteObject(imgHandle);
}
}
}
}


H. Williams said:
I know the .Net Cursor class doesn't work with color cursors. So I'm
currently using the LoadCursorFromFile API with reflection to set color
cursors:

here is my code:

[DllImport("user32.dll")] public static extern IntPtr LoadCursorFromFile(
string fileName );
IntPtr hwdCursor= LoadCursorFromFile( "color.cur" );
myCursor.GetType().InvokeMember("handle",BindingFlags.Public |
BindingFlags.NonPublic |BindingFlags.Instance |
System.Reflection.BindingFlags.SetField,null,myCursor,new object [] {
hwdCursor} );

It works great, but I'd like to be able to embed the cursors. I've been
trying to get theLoadCursor API to work with embedded resources and I am
not
having any luck.

here is the code that doesn't work:

[DllImport("user32.dll")] public static extern IntPtr LoadCursor( long
hwd,
string fileName );
private static IntPtr hInstance =
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
private static IntPtr hwdRedCursor=
LoadCursor((long)hInstance,"color.cur" );

Any suggestions?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top