Connecting Tech Pros Worldwide Help | Site Map

howto emulate events?

EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#1: Oct 6 '09
I'm writing A.I. for logic game, and I need to know how do I call methods like this:
Expand|Select|Wrap|Line Numbers
  1. public void MyButton_Click(object sender, System.EventArgs e) {} 
...and what arguments do I pass to them?

One more: I need event handler for a MessageBox appearance, so I could close it progammably.
That means, somehow to determine if messagebox has popped up, and close it programmably.

P.S. I running out of time and I need your's help very bad. I have deadlines, and I guess, I miscalculated my work plan time.
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,148
#2: Oct 6 '09

re: howto emulate events?


Its just a function, call it like any other function.

If you have:
Expand|Select|Wrap|Line Numbers
  1. void mybutton_Click(object sender, EventArgs e)
  2. {
  3. //your code here
  4. }
  5.  
You can call that function manually with
Expand|Select|Wrap|Line Numbers
  1. mybutton_Click(mybutton,new EventArgs());
  2.  
From a coding perspective I like to do things something like this:
Expand|Select|Wrap|Line Numbers
  1. void mybutton_Click(object sender, EventArgs e)
  2. {
  3.    MyButtonClick();
  4. }
  5.  
  6. void MyButtonClick()
  7. {
  8. //code here
  9. }
  10.  
Then I can just call MyButtonClick()
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 211
#3: Oct 6 '09

re: howto emulate events?


For the message box thing, I'd recommend making your own class to handle showing a message box. Something like...

Expand|Select|Wrap|Line Numbers
  1. public class MyMessageBox
  2. {
  3.   public static void ShowMessage( ... ) // whatever params you want
  4.   {
  5.     MessageBox.Show(...); // whatever you want here
  6.     // Fire your event here
  7.   }
  8. }
A google search should turn up a good amount of information on how to create custom events. Here's one hit that seemed reasonably helpful, but there are many others :)

http://www.devarticles.com/c/a/C-Sha...ts-in-C-sharp/
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#4: Oct 6 '09

re: howto emulate events?


Quote:
That means, somehow to determine if messagebox has popped up, and close it programmably.
What do you mean by 'determine *if* a messagebox has opened"? It's your code. It opens if you tell it to open. There isn't a lot of "determine if" about it. Or are you trying to close a messagebox from another program not your own?

Gary is right about making your own MessageBox class. I would add to his suggestion with this... Include a timer as well as a .Close() method. That way you can give it an external Close() command, as well has have it close itself if nobody responds in 10 seconds.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#5: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by tlhintoq View Post

What do you mean by 'determine *if* a messagebox has opened"? It's your code. It opens if you tell it to open. There isn't a lot of "determine if" about it. Or are you trying to close a messagebox from another program not your own?

Gary is right about making your own MessageBox class. I would add to his suggestion with this... Include a timer as well as a .Close() method. That way you can give it an external Close() command, as well has have it close itself if nobody responds in 10 seconds.

Well, my code consists of 7 classes and around 1630 lines of code.
Lets say, it a kinda difficult to trace all the call and arguments... doesn't matter, I've already did it, and got myself method ShowMessage().

Now, there's another issue: I was trying to handle messagebox closing by adding following code to my ShowMessage method - it didn't work:
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.     MessageBox.Show(msg); 
  4.         if(ps.PlayerName=="CPU") {
  5.             gui.Wait(500); // custom delay method
  6.             SendKeys.Send("{ESC}"); // doesn't close messagebox, ENTER key too
  7.         }
  8. }
Now, I'm planning to choose another object to the role of message box. The only requirement to that object is - existing close routine or window handler.
I was thinking about creating Form object each time and close it after, but maybe someone can suggest less heavyweight object? Something like tooltiptext?
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,148
#6: Oct 6 '09

re: howto emulate events?


MessageBox.Show() is a blocking call
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#7: Oct 6 '09

re: howto emulate events?


Quote:
I was thinking about creating Form object each time and close it after, but maybe someone can suggest less heavyweight object? Something like tooltiptext?
That's pretty much what we were suggesting. Make a class that inherits from Form. Put a text box on it for the text of the message. Put an [OK] and [Cancel] button on it. Put a timer in it if you want to to close on it's own. Give it a public method for "public void ExternalClose()" that will close the form and be a method you can call from all your other classes.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#8: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by tlhintoq View Post

That's pretty much what we were suggesting. Make a class that inherits from Form. Put a text box on it for the text of the message. Put an [OK] and [Cancel] button on it. Put a timer in it if you want to to close on it's own. Give it a public method for "public void ExternalClose()" that will close the form and be a method you can call from all your other classes.

ok, did it. thanks. Now trying to block somehow mainform while MessageBoxForm active...
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 211
#9: Oct 6 '09

re: howto emulate events?


Use the ShowDialog method instead of the Show method when you make it appear.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#10: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by GaryTexmo View Post

Use the ShowDialog method instead of the Show method when you make it appear.

Ok, it's almost perfect. Is there any way to force this kind of form close?
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.     MyMessageBox CustomMsgBox = new MyMessageBox(msg); 
  4.  
  5.     CustomMsgBox.ShowDialog(); 
  6.     if(ps.PlayerName=="CPU") {
  7.         gui.Wait(2000); 
  8.  
  9.         CustomMsgBox.DialogResult = DialogResult.Cancel; 
  10.         // cannot close CustomMsgBox form... what's wrong? 
  11.         CustomMsgBox.Dispose(); 
  12.     }
  13. }
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#11: Oct 6 '09

re: howto emulate events?


Internally this.close()
Externally call the method that has "this.close()"
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#12: Oct 6 '09

re: howto emulate events?


Expand|Select|Wrap|Line Numbers
  1. CustomMsgBox.DialogResult = DialogResult.Cancel; 
  2.         // cannot close CustomMsgBox form... what's wrong? 
  3.         CustomMsgBox.Dispose(); 
You aren't going to tell it from the outside what it's dialog result is.

You need a method inside the form that closes and returns a given result.

You can then call that method from the outside
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#13: Oct 6 '09

re: howto emulate events?


Quote:
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.     MyMessageBox CustomMsgBox = new MyMessageBox(msg); 
  4.  
  5.     CustomMsgBox.ShowDialog(); 
  6.     if(ps.PlayerName=="CPU") {
  7.         gui.Wait(2000); 
  8.  
  9.         CustomMsgBox.DialogResult = DialogResult.Cancel; 
  10.         // cannot close CustomMsgBox form... what's wrong? 
  11.         CustomMsgBox.Dispose(); 
  12.     }
  13. }
If you want a dialog result from this, you need to get it as part of the ShowDialog()

NOTE the additional parameter to send to your custom dialog telling it how long to wait before autoclosing

Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui, int AutoTimeOut)
  2. {
  3.     MyMessageBox CustomMsgBox = new MyMessageBox(msg); 
  4.  
  5.     DialogResult TheResult = CustomMsgBox.ShowDialog(); 
  6.     // You are stuck here.  Stopped. That's it.  Until the dialog closes
  7.     // That's why you need to send a time handled by the Dialog's own timer
  8.     // If a human doesn't close the dialog, it needs to close itself and return
  9.     // The desired result such as cancel.
  10.     }
  11. }
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#14: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by tlhintoq View Post

Expand|Select|Wrap|Line Numbers
  1. CustomMsgBox.DialogResult = DialogResult.Cancel; 
  2.         // cannot close CustomMsgBox form... what's wrong? 
  3.         CustomMsgBox.Dispose(); 
You aren't going to tell it from the outside what it's dialog result is.

You need a method inside the form that closes and returns a given result.

You can then call that method from the outside

Nope, does not work:
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.  
  4.     MyMessageBox CustomMsgBox = new MyMessageBox(msg); 
  5.  
  6.     CustomMsgBox.ShowDialog(); 
  7.     if(ps.PlayerName=="CPU") {
  8.  
  9.         gui.Wait(2000); 
  10.  
  11.         CustomMsgBox.MyClose(); 
  12.         CustomMsgBox.Dispose(); 
  13.     }
  14. }
Expand|Select|Wrap|Line Numbers
  1. public void MyClose()
  2. {
  3.     this.DialogResult = DialogResult.OK; 
  4.     this.Close(); 
  5. }
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,148
#15: Oct 6 '09

re: howto emulate events?


hehe.

Ok, if you're going to use ShowDialog() (which blocks), then your code for closing the box on a time interval has to be done either prior to opening it, or inside the class itself.

Otherwise, use the .Show() call and the program will continue to flow. Where you can use your wait() call then use the MyClose() function.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#16: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by Plater View Post

hehe.

Ok, if you're going to use ShowDialog() (which blocks), then your code for closing the box on a time interval has to be done either prior to opening it, or inside the class itself.

Otherwise, use the .Show() call and the program will continue to flow. Where you can use your wait() call then use the MyClose() function.

The problem is, that a criteria (string argument) should be passed after ShowDialog called. Otherwise, CustomForm will close before ShowDialog called -> runtime error.

Show is not a good desicion, cause it allows performing manual actions on the main form while secondary is up, carrying message...
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,148
#17: Oct 6 '09

re: howto emulate events?


Well you are stuck putting a timer event in your custom messagebox code.
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#18: Oct 6 '09

re: howto emulate events?


Quote:

Originally Posted by EntryTeam View Post

Nope, does not work:

Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.  
  4.     MyMessageBox CustomMsgBox = new MyMessageBox(msg); 
  5.  
  6.     CustomMsgBox.ShowDialog(); 
  7.     if(ps.PlayerName=="CPU") {
  8.  
  9.         gui.Wait(2000); 
  10.  
  11.         CustomMsgBox.MyClose(); 
  12.         CustomMsgBox.Dispose(); 
  13.     }
  14. }

Expand|Select|Wrap|Line Numbers
  1. public void MyClose()
  2. {
  3.     this.DialogResult = DialogResult.OK; 
  4.     this.Close(); 
  5. }

You can't say it didn't work, when you didn't do it as it was suggested.
The timer has to be inside the CustomMessageBox.
Not inside the other class that calls the CustomMessageBox.
Go back and re-read the suggestion I make paying special attention where I said "NOTE the new parameter of int for the number of seconds before the CustomMessageBox closes". You have to tell the box how long to live before auto closing. You cannot close it from the outside if you use ShowDialog and you have already stated that you HAVE to use ShowDialog so people can't play with the mainform while the dialog form is open.

Quote:
The problem is, that a criteria (string argument) should be passed after ShowDialog called.
Not an option. Accept that. As Plater has pointed out ShowDialog is a blocking call. You will need to rework your code slightly so that you pass the string criteria as part of the CustomMessageBox parameters when you make the box.

Or you can make the box
Pass the string
THEN call its ShowDialog method.


Stop.

Breathe.

Relax.

You are over thinking it. you are making it harder than it really is.
Just make the box.
Give it all the values it needs.
Then the last step is to ShowDialog.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#19: Oct 7 '09

re: howto emulate events?


Quote:

Originally Posted by Plater View Post

Well you are stuck putting a timer event in your custom messagebox code.

Quote:

Originally Posted by tlhintoq

You will need to rework your code slightly so that you pass the string criteria as part of the CustomMessageBox parameters when you make the box.

Correct me if I'm wrong:
Expand|Select|Wrap|Line Numbers
  1. public MyMessageBox(string msg, string name)
  2. {
  3.     InitializeComponent();
  4.     richTextBox1.Text = msg; 
  5.  
  6.     this.ShowDialog(); 
  7.  
  8.     if(name=="CPU") {
  9.         GUI.Wait(2000); // ms
  10.         this.Close(); 
  11.     }    
  12. }
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.     MyMessageBox CustomMsgBox = new MyMessageBox(msg, ps.PlayerName); 
  4.     CustomMsgBox.Dispose(); 
  5. }
No effect
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,148
#20: Oct 7 '09

re: howto emulate events?


Yup still wrong.
The .ShowDialog() will block regardless of its location.
Here's a way you could do it:
INSIDE your custom class's constructor, attached an event handler to its own "Activated" event (or similar event) in that handler you would start the timer with the number of seconds from your constructor interval.
This way, the timer starts when your form is shown.
Use an actual timer, not just a wait function. When the timer elapses, close the custom dialog.
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#21: Oct 8 '09

re: howto emulate events?


Quote:

Originally Posted by Plater View Post

Yup still wrong.
The .ShowDialog() will block regardless of its location.
Here's a way you could do it:
INSIDE your custom class's constructor, attached an event handler to its own "Activated" event (or similar event) in that handler you would start the timer with the number of seconds from your constructor interval.
This way, the timer starts when your form is shown.
Use an actual timer, not just a wait function. When the timer elapses, close the custom dialog.

Can I please have working code example? Here's mine, still not working properly:
(MyMessageBox class)
Expand|Select|Wrap|Line Numbers
  1. private static System.Timers.Timer aTimer;
  2. private string arg_name; 
  3.  
  4. public MyMessageBox(string msg, string name)
  5. {
  6.     InitializeComponent();
  7.     richTextBox1.Text = msg; 
  8.     arg_name = name; 
  9.  
  10.     aTimer = new System.Timers.Timer(2000);
  11.     aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
  12.     aTimer.Interval = 2000;
  13.     // aTimer.Enabled = true;
  14.  
  15.     this.ShowDialog(); 
  16. }
  17.  
  18. void Button1Click(object sender, EventArgs e)
  19. {
  20.     this.Close(); 
  21. }
  22.  
  23. private void OnTimedEvent(object source, ElapsedEventArgs e)
  24. {
  25.     this.Close();
  26. }
  27.  
  28. void MyMessageBoxActivated(object sender, EventArgs e)
  29. {
  30.     if(arg_name=="CPU") 
  31.         aTimer.Enabled = true;
  32. }
  33.  
  34. void MyMessageBoxLoad(object sender, EventArgs e)
  35. {
  36.     if(arg_name=="CPU")
  37.         aTimer.Enabled = true;
  38. }
  39.  
  40. void MyMessageBoxShown(object sender, EventArgs e)
  41. {
  42.     if(arg_name=="CPU")
  43.         aTimer.Enabled = true;
  44. }
Expand|Select|Wrap|Line Numbers
  1. public void ShowMessage(string msg, ref PlayerStatus ps, ref GUI gui)
  2. {
  3.  
  4.     MyMessageBox CustomMsgBox = new MyMessageBox(msg, ps.PlayerName); 
  5.     CustomMsgBox.Dispose(); 
  6. }
As you can see I've tryied all possible events...
tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,743
#22: Oct 9 '09

re: howto emulate events?


Quote:
// aTimer.Enabled = true;
If you don't start the timer, then its not going to autoclose

Suggestion: Always do text comparrisons to lower so you can be sure to get a match regardless of what you you send it. If by chance you were sending a player name of "cpu" or "Cpu" then your comparrison could be failing.

if(arg_name.ToLower() =="cpu")

If you run it just as you have it now but with line 13 working (not commented out) then your dialog should be closing after 2 seconds. Does it?
EntryTeam's Avatar
Member
 
Join Date: Aug 2009
Posts: 49
#23: Oct 9 '09

re: howto emulate events?


Quote:

Originally Posted by tlhintoq View Post

If you don't start the timer, then its not going to autoclose

Suggestion: Always do text comparrisons to lower so you can be sure to get a match regardless of what you you send it. If by chance you were sending a player name of "cpu" or "Cpu" then your comparrison could be failing.

if(arg_name.ToLower() =="cpu")

Nice advice.

Quote:

Originally Posted by tlhintoq View Post

If you run it just as you have it now but with line 13 working (not commented out) then your dialog should be closing after 2 seconds. Does it?

Still not working :(
Reply