C# VS.Net 2003, .Net CF, MessageWindow + Dataset error

Hi all,
My device is running under Windows CE .Net 4.2 with a built in barcode scanner. I found a problem over my .Net CF application which developed in C#. I do create a message window in a class like below to getting the value my barcode scanner get when scan key press.

public class myMessageWndMain : MessageWindow
{
frmMain app;
public const int WM_USER = 0x400;
public const int WM_SCAN_DATA = WM_USER+100;
public const int WM_DATA_SCANINIT_START=WM_USER+101;
public const int WM_DATA_SCANINIT_END=WM_USER+102;
public myMessageWndMain(frmMain app)
{
this.app=app;
}

protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case WM_SCAN_DATA:
app.GetScanData();
break;
}
base.WndProc (ref m);

}
}


In my frmMain_Load, include this
myMessageWndMain msgWnd = new myMessageWndMain(this);
At the first few times when the particular key press, and my scanner get the value, my application still able to step into/proceed into
protected override void WndProc(ref Message m).Butafter a few times i press my insert button(UI) which perform a dataset and also dataset.writexml, my application fail to step into/proceed into protected override void WndProc(ref Message m)when i pressed my scan button. No matter how i tried. My scanner able to get the value, just because my code cant step into protected override void WndProc(ref Message m). If i indent all my dataset and write xml code, it able to step into protected override void WndProc(ref Message m)and call myGetScanData()to capture the scan value, even ten hundred times. I had tried my best to do everything i can, but i cant solve. Is any expert here can help me on this? A thousand thanks for every single reply.
Is it related to any resourcesof object/GC(garbage collector) problem?

[2730 byte] By [Pony] at [2007-12-16]
# 1

Hello Pony, sorry for the delay in getting back to you. I've been trying to reproduce your issue with a recent v2 build according to your problem description where MessageWindow -> application -> add to dataset -> dataset.WriteXML. After 10000 iterations, my MessageWindow is still calling back into my application. I've pasted in the code, please let me know if this is accurately representing what your code is doing (if not, how it needs to change). Note code below only performs 10 iterations each time you click the "starttest" menu item.

mike



using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.WindowsCE.Forms;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Xml;

public class Test : System.Windows.Forms.Form
{
int pass, fail;
private bool autoStart = false;
public int ReturnCode = 0x00010001;
Timer autoStartTimer;
MenuItem menuRun, menuExit;
Label status;

myMessageWindow mw;
DataSet myData;
XmlTextWriter xmlTextWriter;

public Test(string[] args)
{
for(int n = 0; n < args.Length; n++)
{
if(args//emoticons/emotion-45.gif" alt="No" />.Equals("/auto"))
{
this.autoStart = true;
break;
}
}
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.MinimizeBox = false;
this.Text = "MessageWindow+dataset";

this.Menu = new MainMenu();
this.menuRun = AddMenuItem(this.Menu, "Run Test");
this.menuExit = AddMenuItem(this.Menu, "Exit");

this.status = new Label();
this.status.Parent = this;
this.status.Dock = DockStyle.Top;
this.status.Text = "test not running";

this.mw = new myMessageWindow(this);
this.myData = this.CreateDataSet();
FileStream fs = new FileStream("myXMLdoc.xml", FileMode.Create);
this.xmlTextWriter = new XmlTextWriter(fs, System.Text.Encoding.ASCII);


if(this.autoStart)
{
Console.WriteLine("/auto switch detected, running test automatically...");
this.autoStartTimer = new Timer();
this.autoStartTimer.Interval = 200;
this.autoStartTimer.Tick += new EventHandler(this._Tick);
this.autoStartTimer.Enabled = true;
}
}

MenuItem AddMenuItem(Menu parent, string text)
{
MenuItem menu = new MenuItem();

menu.Text = text;
menu.Click += new EventHandler(this.menu_Click);
parent.MenuItems.Add(menu);

return menu;
}

protected void menu_Click(object o, EventArgs e)
{
MenuItem menu = (MenuItem)o;

if(menu == this.menuRun)
StartTest();
else if(menu == this.menuExit)
this.Close();
}

void _Tick(object o, EventArgs e)
{
this.autoStartTimer.Enabled = false;
StartTest();
}

const int MSGCOUNT = 10;
private void StartTest()
{
this.postCount = 0;
for(int n = 0; n < MSGCOUNT; n++)
{
Message msg = Message.Create(this.mw.Hwnd,
myMessageWindow.WM_POST,
(IntPtr)myMessageWindow.WM_POST,
(IntPtr)(myMessageWindow.WM_POST + 1));

MessageWindow.PostMessage(ref msg);

pass++;
Application.DoEvents();
}

if(this.autoStart)
this.Close();
}


int postCount = 0;
/// <summary>
/// this called from MessageWindow...
/// </summary>
public void PostEvent(int data)
{
Console.WriteLine("--PostEvent");
this.postCount++;

// add scan data to dataset, writeXML
DataRow row = this.myData.Tables[0].NewRow();
row[0] = string.Format("code #{0}", postCount);
row[1] = postCount;
this.myData.Tables[0].Rows.Add(row);

this.myData.WriteXml(this.xmlTextWriter);
}

int percentPass()
{
if(this.pass + this.fail == 0)
return 0;

return this.pass * 100 / (this.pass + this.fail);
}

protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
this.xmlTextWriter.Close();

if(this.autoStart)
{
int scenarios = (this.pass + this.fail) << 16;
Console.WriteLine(string.Format("\nExpected return code if all pass = {0} or 0x{1:X}",
scenarios,
scenarios));

this.ReturnCode = scenarios + this.fail;

Console.WriteLine(string.Format(" {0} results: #fail={1}, %pass={2}%; returnCode={3} or 0x{4:X}\n",
this.Text,
this.fail,
percentPass(),
this.ReturnCode,
this.ReturnCode));
}
}

DataSet CreateDataSet()
{
DataSet myDataSet;
myDataSet = new DataSet("ScanCodes");

// Create two DataTable objects using a function.
DataTable table1 = MakeTable("codes", "desc", "code");
myDataSet.Tables.Add(table1);

Console.WriteLine(myDataSet.DataSetName, myDataSet.Tables.Count);
return myDataSet;
}


DataTable MakeTable(string tableName, string c1Name, string c2Name)
{
DataTable myTable = new DataTable(tableName);
DataColumn myColumn;

// Add two DataColumns
myColumn = new DataColumn();
myColumn.DataType = typeof(string);
myColumn.ColumnName = c1Name;
myTable.Columns.Add(myColumn);

myColumn = new DataColumn();
myColumn.DataType = typeof(int);
myColumn.ColumnName = c2Name;
myTable.Columns.Add(myColumn);

return myTable;
}


static int Main(string[] args)
{
Test x = new Test(args);
try
{
Application.Run(x);
return x.ReturnCode;
}
catch(Exception e)
{
Console.WriteLine("\n unhandled exception: " + e.Message + "\n" + e.StackTrace);
return 0x00010001;
}
}
}


public class myMessageWindow : MessageWindow, IDisposable
{
public const int WM_USER = 0x0400;
// public const int WM_SEND = WM_USER + 1;
public const int WM_POST = WM_USER + 2;
public const int PASS = 0xABC;
public const int FAIL = 0xDEF;

int count = 0;

Test test;

public myMessageWindow(Test test)
{
this.test = test;
}

protected override void WndProc(ref Message msg)
{
switch(msg.Msg)
{
// case WM_SEND:
// if(msg.WParam != (IntPtr)WM_SEND)
// Console.WriteLine("wparam=" + msg.WParam + ", expected=" + WM_SEND);
// else if(msg.LParam != (IntPtr)(WM_SEND + 1))
// Console.WriteLine("wparam=" + msg.WParam + ", expected=" + WM_SEND);
// else
// msg.Result = (IntPtr)PASS;
//
// this.test.SendEvent();
// break;

case WM_POST:
msg.Result = (IntPtr)FAIL;

if(msg.WParam != (IntPtr)WM_POST)
Console.WriteLine("wparam=" + msg.WParam + ", expected=" + WM_POST);
else if(msg.LParam != (IntPtr)(WM_POST + 1))
Console.WriteLine("wparam=" + msg.WParam + ", expected=" + WM_POST);
else
msg.Result = (IntPtr)PASS;

this.test.PostEvent(count++);
break;
}

Console.WriteLine(" WndProc messageID=" + msg.Msg);

base.WndProc(ref msg);
}
}

MichaelLippMSFT at 2007-9-9 > top of Msdn Tech,Smart Device Development,Smart Devices General...