Can I mimic a btn_Click() ?

  • Thread starter Thread starter Rick
  • Start date Start date
R

Rick

Hi,

I have an application at work that I've inherited from a former employee.
This app runs on a Windows CE .NET environment on an LCD screen.
The app has several buttons on the screen that
are clickable and have event handlers. These work fine. What I did was set
up a UDP link from a PC to the CE device and I want to send commands from my
PC instead of clicking the button on the device. This doesn't work very
well. It works if the action does not affect the display such as testing
LEDs on the device. If I have operations that remove buttons from the screen
and make others appear, the buttons appear to be dead. For example my form
gave me this event hander for the button which works well.

this.m_oCalibrateLCDBtn.Click += new
System.EventHandler(this.CalibrateLCD_Click);

When I receive the remote command from my PC I try to do a similar thing
which isn't working.

CalibrateLCD_Click(this.m_oCalibrateLCDBtn, dummyEventArgs);

I must be missing something from the form that the event handler has but I
don't know what it is. Some other points are: Other remote UDP command are
OK as long as the display is not affected. Once I'm in the
CalibrateLCD_Click() event handler my sender and "this" look OK in my
"Autos" window in both cases. My EventArgs is empty which is why I was able
to create a dummy. However once I start some operations that affect the
display (removing buttons such as setting enabled and visible to false) my
sender and my "this" get clobbered in my "Autos" window. It says "undefined
value". If I try to debug this with breakpoints things get even more messed
up. I had better luck with MessageBox(es) to debug but still am not having
any luck. I was told to try the PerformClick() method but this is not
available on
the CE.

If anyone has any ideas on this I would appreciate advice.
Rick
 
See if this helps:
http://www.opennetcf.org/PermaLink.aspx?guid=4cf118ee-5668-452e-af2c-f3a0c6d43a7f

In particular you want to read the part "Emulating event firing"
In the sample code instead of searching an event with type of
ListChangedEventHandler, you will need to search for an event with f.Name =
"Click"

private void SimulateClick(Button button1)
{
// TO simulate the delegate invocation we obtain it's invocation list
// and walk it, invoking each item in the list
Type t = typeof(Control);
FieldInfo fi = t.GetField("Click",
BindingFlags.NonPublic|BindingFlags.Instance);
MulticastDelegate d = fi.GetValue(button1) as MulticastDelegate;
Delegate[] list = d.GetInvocationList();
// It is important to cast each member to an appropriate delegate type
// For example for the KeyDown event we would replace EventHandler
// with KeyEvenHandler and new EventArgs() with new KeyHandlerEventArgs()
foreach(EventHandler del in list)
{
del.Invoke(button1, new EventArgs());
}
}
 
Hi Rick,

If you want to trigger a button click with another event than a manual click
you can do it this way:
myButton_Click(sender, new EventArgs());

private void MyFunction_SomeEvent(object sender, SomeEventArgs e)
{
myButton_Click(sender,new EventArgs());
}

HTH,
Sitar.
___
 
Hello all,



I’m following up my original post since I think this info could be helpful
to some people. Maybe this has all been covered in the past but here goes
anyway. I would like to thank Alex Feinman for being very helpful and
patient with me. Thanks also to Daniel Moth who has an excellent web site as
well as open source code that I used for my solution at
www.danielmoth.com/Blog/2004/12/backgroundworker-for-cf-10.html.



My problem was I was trying to simulate a click on my CF app from a remote
PC over a UDP link. I need to send commands from the PC that mean the same
thing as a button click on the app. The UDP client has to listen for
messages so it needs it’s own thread. The problem with the CF platform (and
to a lesser degree the regular .NET platform) is that you cannot update the
GUI from a background thread, only from the GUI thread itself. I found this
out after a lot of frustration a bit or heartache. Alex informed me of
Daniel’s BackgroundWorker class that is available for download. Using that
along with the Invoke() method to pass execution between background and
foreground got the job done. Daniel also provides an example of the Invoke
(in VB) at www.danielmoth.com/Blog/2004/10/invoke-cf-and-full-fx.html.



Following is pseudo code that highlights only the background / foreground
implementation.



Rick



Public class myClass

{

private BackgroundWorkder mBW;

private Queue m_queue = new Queue();

private UdpClient udpClient;





public myClass

{

this.InitBW();

}





private void InitBW()

{

mBW = new BackgroundWorkder(this);

mBW.RunWorkerCompleted += new
RunWorkerCompletedEventHander(mBW_RunWorkerCompleted);

mBW.DoWork +=
DoWorkEventHandler(mBW_DoWork);

}



private void myClassForm_Load

{



mBW.RunWorkerAsync():

}



// My BG processor. Cannot touch GUI from here.

private void mBW_DoWork(object sender, DoWorkEventArgs e)

{

udpClient = new UdpClient(PC_PORT_NUM);

IPEndPoint endPoint = new
IPEndPoint(IPAddress.Any, 0);

do

{

Byte[] receiveBytes =
udpClient.Receive(ref endPoint);

string returnData =
Encoding.ASCII.GetString( receiveBytes, 0, receiveBytes.Length );

Thread.Sleep(50);

lock ( m_queue.SyncRoot )

{

m_queue.Enqueue(
returnData );

}

Invoke ( new EventHandler(
ProcessCommands ) );

} while(true);

}





// Not really needed for my app

private void mBW_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)

{

MessageBox.Show("mBW Background worker
completed");

}



private void ProcessCommands( object sender, EventArgs e )

{

EventArgs dummyEventArgs = new EventArgs();

string[] strArray;

string cmd;



// Receives the execution from the
BackgroundWorker to the GUI

lock (m_queue.SyncRoot)

{

cmd =
(string)m_queue.Dequeue();

}

strArray = cmd.Split( ' ' );

switch( strArray[0] )

{

case "clcd":

CalibrateLCD_Click(
this.m_oCalibrateLCDBtn, dummyEventArgs );

Break;



// The rest of the commands



}
 
Back
Top