Serializing/DeSerializing System.Windows.Forms.Cusrsor object looses the hotspot

  • Thread starter Thread starter Sankar Nemani
  • Start date Start date
S

Sankar Nemani

Hi All,
We are trying to Serialize a System.Windows.Forms.Cursor object and
Deserialize it. Before serializing the cursor behaves correctly but when we
serialize and use a deserialized object, the hotspot (the cursor pointer) is
not where it is expected to be. We tried both binary and soap formatters.
TIA
Sankar Nemani
 
Hi Sankar,

Thanks for posting in the community.

the Cursor class implemented the ISerializable interface, which only
serialize the resource in the object and will not serialize the static
Property Location.
As a workaround, you may serialize Cursor.Position property instead, or
serialize both of them if you also need save the resource.

Hope it helps.

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
I tried the cursor position also and still it does not make a difference.
Could you please look at the code and tell me what to modify to get it
working.
Thank you
Sankar Nemani
'********Code starts here******************
Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

Friend WithEvents Label1 As System.Windows.Forms.Label

Friend WithEvents Button1 As System.Windows.Forms.Button

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.Label1 = New System.Windows.Forms.Label

Me.Button1 = New System.Windows.Forms.Button

Me.SuspendLayout()

'

'Label1

'

Me.Label1.BackColor = System.Drawing.Color.White

Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!,
System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0,
Byte))

Me.Label1.ForeColor = System.Drawing.Color.Goldenrod

Me.Label1.Location = New System.Drawing.Point(248, 112)

Me.Label1.Name = "Label1"

Me.Label1.TabIndex = 0

Me.Label1.Text = "Label1"

'

'Button1

'

Me.Button1.Location = New System.Drawing.Point(456, 120)

Me.Button1.Name = "Button1"

Me.Button1.TabIndex = 1

Me.Button1.Text = "Button1"

'

'Form1

'

Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

Me.BackColor = System.Drawing.Color.RosyBrown

Me.ClientSize = New System.Drawing.Size(816, 381)

Me.Controls.Add(Me.Button1)

Me.Controls.Add(Me.Label1)

Me.Name = "Form1"

Me.Text = "Form1"

Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim x As New Cursor("c:\WINDOWS\Cursors\pen_r.cur")

Dim f As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter

Dim str As IO.Stream

str = New IO.FileStream("test.ser", IO.FileMode.Create)

f.Serialize(str, x)

str.Close()

Dim m As Cursor

str = New IO.FileStream("test.ser", IO.FileMode.Open)

m = f.Deserialize(str)

str.Close()

Me.Button1.Cursor = m

Me.Label1.Cursor = x

End Sub

End Class

'********Code Ends here******************

"Ying-Shen Yu[MSFT]" said:
Hi Sankar,

Thanks for posting in the community.

the Cursor class implemented the ISerializable interface, which only
serialize the resource in the object and will not serialize the static
Property Location.
As a workaround, you may serialize Cursor.Position property instead, or
serialize both of them if you also need save the resource.

Hope it helps.

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Hi Sankar,
What I mean is you need serialize Cursor.Position on your own, I modified
the code as below,
Is this the effect your would like to have?
Let me know if you still have problem on it.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim x As New Cursor("c:\WINDOWS\Cursors\pen_r.cur")

Dim f As New
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter

Dim str As IO.Stream

str = New IO.FileStream("test.ser", IO.FileMode.Create)

f.Serialize(str, x)
f.Serialize(str, Cursor.Position)

str.Close()

Cursor.Position = New Point(0, 0) 'change to (0,0) of screen
coordinate

Dim m As Cursor

str = New IO.FileStream("test.ser", IO.FileMode.Open)

m = f.Deserialize(str)

Cursor.Position = f.Deserialize(str) ' restore

str.Close()

Me.Button1.Cursor = m

Me.Label1.Cursor = x

End Sub

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
It still has not fixed my problem. Can you run the modified code and when
the form comes up click on the button. The button click code we have
serializes the position and the cursor and deserializes it.
Now move the mouse over the label and the button in the top left hand corner
area.
The cursor turns from pen to an arrow as soon as you leave the label's top
left are which is how it is expected to behave.
But on the button, even after you leave the top left corner, the cursor
won't change for a few pixels. After that it changes to the pointer.
 
Hi sankar,

I apologize for misunderstanding your problem.
Thanks for the detail description, I had never noticed this behavior before.
After some research, it seems this is a known issue in Cursor class.

To workaround this issue, we need save a copy of the .Cur file. serialize
the content of this file instead . We may write a CursorWrapper class to
help us do this.
I found a sample code for you, you need change it to fit your needs.
You need load .cur file into CursorWrapper class instead then access the
Cursor property instead.
If the workaround does not solve your problem, you may contact Phone
service for further help.

Thanks!

<code>
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using System.Globalization;
using System.Runtime.Serialization;

namespace MyCursor
{
[Serializable]
[TypeConverterAttribute(typeof(CursorWrapperConverter))]
public class CursorWrapper : ISerializable
{
Cursor _cursor;
byte[] _originalFile;

internal CursorWrapper(SerializationInfo info, StreamingContext context)
{
SerializationInfoEnumerator sie = info.GetEnumerator();
if (sie == null)
{
return;
}
for (; sie.MoveNext();)
{
if (String.Compare(sie.Name, "CursorData", true,
CultureInfo.InvariantCulture) == 0)
{
byte[] dat = (byte[])sie.Value;
try
{
if (dat != null)
{
_originalFile = dat;
CursorConverter cc = new CursorConverter();
_cursor = (Cursor)cc.ConvertFrom(OriginalFile);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
}
}

public CursorWrapper(Stream stream)
{
_originalFile = new byte[stream.Length];
stream.Read(_originalFile, 0, _originalFile.Length);
CursorConverter cc = new CursorConverter();
_cursor = (Cursor) cc.ConvertFrom(_originalFile);
}

public Cursor Cursor
{
get { return _cursor; }
}

internal byte[] OriginalFile
{
get { return _originalFile; }
}

void ISerializable.GetObjectData(SerializationInfo si, StreamingContext
context)
{
si.AddValue("CursorData", OriginalFile, typeof(byte[]));
}
}

public class CursorWrapperConverter : TypeConverter {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type
sourceType)
{
if (sourceType == typeof(byte[]))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type
destinationType)
{
if (destinationType == typeof(byte[]))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}

public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is byte[])
{
MemoryStream ms = new MemoryStream((byte[])value);
return new Cursor(ms);
}
return base.ConvertFrom(context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(byte[]))
{
if (value != null)
{
return ((CursorWrapper)value).OriginalFile;
}
else
return new byte[0];
}

return base.ConvertTo(context, culture, value, destinationType);
}
}
}

</code>



Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Back
Top