using System; using System.Windows.Forms; using CityOfHeroes; namespace ExtendScannerWinForms_CS { /// <summary> /// Demo class for using the scanner in your own application. /// /// Note that this project has a post-build event that copies ChatMessageregexs.dat /// into the run directory. That file needs to be in the same directory as the /// executable in order to get the regular expressions that the ChatMessage class /// uses to parse the messages that come in from the CoH client. /// </summary> public class MainForm : System.Windows.Forms.Form { private System.Windows.Forms.MainMenu mainMenu1; private System.Windows.Forms.MenuItem miFile; private System.Windows.Forms.MenuItem miFileExit; private System.Windows.Forms.MenuItem miScanner; private System.Windows.Forms.MenuItem miScannerStart; private System.Windows.Forms.MenuItem miScannerStop; private System.Windows.Forms.Panel pnlLeft; private System.Windows.Forms.Splitter splitter1; private System.Windows.Forms.Panel pnlRight; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.MenuItem menuItem6; private System.Windows.Forms.MenuItem miScannerPause; private System.Windows.Forms.MenuItem miScannerResume; private System.Windows.Forms.ListBox lbStatus; private System.Windows.Forms.ListBox lbMessages; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; // our scanner object private CityOfHeroes.Scanner.CohScanner scanner; public MainForm() { InitializeComponent(); // first, instantiate the scanner object scanner = new CityOfHeroes.Scanner.CohScanner(); // now initialize the chat message subsystem. Note that these last two // items don't have to be done in this order // // Also note that, strictly speaking, this doesn't have to be called. If // you fail to do so, the chat message subsystem will initialize the first // time it's needed. Unfortunately, that can take some time (up to 10 seconds // or so), so it's better to initialize it up front when you're doing the rest // of your application setup so as to not have an ugly pause in the processing // of your first chat message CityOfHeroes.ChatMessage.Initialize(); // by default, the scanner will scan the chat channels that contain the // information it needs. You can add additional channels as desired // // e.g., Broadcast is not selected by default, but let's get its messages too. scanner.BroadcastChannel = true; // now let's register for some events scanner.OnHeroLogin += new CityOfHeroes.Scanner.HeroLoginHandler(scanner_OnHeroLogin); scanner.OnHeroLogout += new CityOfHeroes.Scanner.HeroLogoutHandler(scanner_OnHeroLogout); scanner.OnScanningError += new CityOfHeroes.Scanner.ScanningErrorHandler(scanner_OnScanningError); scanner.OnScanningPaused += new CityOfHeroes.Scanner.ScanningInactiveHandler(scanner_OnScanningPaused); scanner.OnScanningResumed += new CityOfHeroes.Scanner.ScanningActiveHandler(scanner_OnScanningResumed); scanner.OnScanningStart += new CityOfHeroes.Scanner.ScanningStartHandler(scanner_OnScanningStart); scanner.OnScanningStop += new CityOfHeroes.Scanner.ScanningStopHandler(scanner_OnScanningStop); scanner.OnChatMessage += new CityOfHeroes.Scanner.ChatMessageEventHandler(scanner_OnChatMessage); // and we're ready to start the scanner. Note that this is a user action in this // application, under the 'Scanner' submenu } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.mainMenu1 = new System.Windows.Forms.MainMenu(); this.miFile = new System.Windows.Forms.MenuItem(); this.miFileExit = new System.Windows.Forms.MenuItem(); this.miScanner = new System.Windows.Forms.MenuItem(); this.miScannerStart = new System.Windows.Forms.MenuItem(); this.miScannerStop = new System.Windows.Forms.MenuItem(); this.pnlLeft = new System.Windows.Forms.Panel(); this.splitter1 = new System.Windows.Forms.Splitter(); this.pnlRight = new System.Windows.Forms.Panel(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.lbStatus = new System.Windows.Forms.ListBox(); this.lbMessages = new System.Windows.Forms.ListBox(); this.menuItem6 = new System.Windows.Forms.MenuItem(); this.miScannerPause = new System.Windows.Forms.MenuItem(); this.miScannerResume = new System.Windows.Forms.MenuItem(); this.pnlLeft.SuspendLayout(); this.pnlRight.SuspendLayout(); this.SuspendLayout(); // // mainMenu1 // this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miFile, this.miScanner}); // // miFile // this.miFile.Index = 0; this.miFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miFileExit}); this.miFile.Text = "&File"; // // miFileExit // this.miFileExit.Index = 0; this.miFileExit.Text = "E&xit"; this.miFileExit.Click += new System.EventHandler(this.miFileExit_Click); // // miScanner // this.miScanner.Index = 1; this.miScanner.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miScannerStart, this.miScannerStop, this.menuItem6, this.miScannerPause, this.miScannerResume}); this.miScanner.Text = "&Scanner"; this.miScanner.Popup += new System.EventHandler(this.miScanner_Popup); // // miScannerStart // this.miScannerStart.Index = 0; this.miScannerStart.Text = "Star&t"; this.miScannerStart.Click += new System.EventHandler(this.miScannerStart_Click); // // miScannerStop // this.miScannerStop.Enabled = false; this.miScannerStop.Index = 1; this.miScannerStop.Text = "Sto&p"; this.miScannerStop.Click += new System.EventHandler(this.miScannerStop_Click); // // pnlLeft // this.pnlLeft.Controls.Add(this.lbStatus); this.pnlLeft.Controls.Add(this.label1); this.pnlLeft.Dock = System.Windows.Forms.DockStyle.Left; this.pnlLeft.Location = new System.Drawing.Point(0, 0); this.pnlLeft.Name = "pnlLeft"; this.pnlLeft.Size = new System.Drawing.Size(240, 350); this.pnlLeft.TabIndex = 0; // // splitter1 // this.splitter1.Location = new System.Drawing.Point(240, 0); this.splitter1.Name = "splitter1"; this.splitter1.Size = new System.Drawing.Size(6, 350); this.splitter1.TabIndex = 1; this.splitter1.TabStop = false; // // pnlRight // this.pnlRight.Controls.Add(this.lbMessages); this.pnlRight.Controls.Add(this.label2); this.pnlRight.Dock = System.Windows.Forms.DockStyle.Fill; this.pnlRight.Location = new System.Drawing.Point(246, 0); this.pnlRight.Name = "pnlRight"; this.pnlRight.Size = new System.Drawing.Size(258, 350); this.pnlRight.TabIndex = 2; // // label1 // this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.label1.Dock = System.Windows.Forms.DockStyle.Top; this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(240, 23); this.label1.TabIndex = 0; this.label1.Text = "Status"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // label2 // this.label2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.label2.Dock = System.Windows.Forms.DockStyle.Top; this.label2.Location = new System.Drawing.Point(0, 0); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(258, 23); this.label2.TabIndex = 0; this.label2.Text = "Chat Messages"; this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // lbStatus // this.lbStatus.Dock = System.Windows.Forms.DockStyle.Fill; this.lbStatus.IntegralHeight = false; this.lbStatus.Location = new System.Drawing.Point(0, 23); this.lbStatus.Name = "lbStatus"; this.lbStatus.ScrollAlwaysVisible = true; this.lbStatus.Size = new System.Drawing.Size(240, 327); this.lbStatus.TabIndex = 1; // // lbMessages // this.lbMessages.Dock = System.Windows.Forms.DockStyle.Fill; this.lbMessages.IntegralHeight = false; this.lbMessages.Location = new System.Drawing.Point(0, 23); this.lbMessages.Name = "lbMessages"; this.lbMessages.ScrollAlwaysVisible = true; this.lbMessages.Size = new System.Drawing.Size(258, 327); this.lbMessages.TabIndex = 1; // // menuItem6 // this.menuItem6.Index = 2; this.menuItem6.Text = "-"; // // miScannerPause // this.miScannerPause.Enabled = false; this.miScannerPause.Index = 3; this.miScannerPause.Text = "&Pause"; this.miScannerPause.Click += new System.EventHandler(this.miScannerPause_Click); // // miScannerResume // this.miScannerResume.Enabled = false; this.miScannerResume.Index = 4; this.miScannerResume.Text = "&Resume"; this.miScannerResume.Click += new System.EventHandler(this.miScannerResume_Click); // // MainForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(504, 350); this.Controls.Add(this.pnlRight); this.Controls.Add(this.splitter1); this.Controls.Add(this.pnlLeft); this.Menu = this.mainMenu1; this.Name = "MainForm"; this.Text = "HeroStats Scanner Extension"; this.pnlLeft.ResumeLayout(false); this.pnlRight.ResumeLayout(false); this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new MainForm()); } #region Form Event Handlers private void miFileExit_Click(object sender, System.EventArgs e) { Close(); } private void miScannerStart_Click(object sender, System.EventArgs e) { scanner.Start(); } private void miScannerStop_Click(object sender, System.EventArgs e) { scanner.Stop(); } private void miScannerPause_Click(object sender, System.EventArgs e) { scanner.Pause(); } private void miScannerResume_Click(object sender, System.EventArgs e) { scanner.Resume(); } private void miScanner_Popup(object sender, System.EventArgs e) { miScannerStart.Enabled = !scanner.Scanning; miScannerStop.Enabled = scanner.Scanning; miScannerPause.Enabled = scanner.Scanning && !scanner.Paused; miScannerResume.Enabled = scanner.Scanning && scanner.Paused; } #endregion #region Scanner Event Handlers /*********************************************************** * Below are the event handlers for the scanner. * * Note that these will always be called on a thread that is * different from the UI's thread. Due to the way .NET event * handling works for UI elements, if you're handling a message * on a thread that's not the UI thread, you must call Invoke * on the control in order to switch to the UI thread prior to * doing any action with the UI. * * That's why you'll see a check for InvokeRequired and the * call to Invoke in each one of these. The good news is that, * since they're already event handlers, there's delegates set up * for them, so you don't have to create new delegates to pass off * to Invoke() ***********************************************************/ /// <summary> /// Handles an event that gets fired when a new hero logs into CoH /// </summary> /// <param name="hero">Information about the hero logging in</param> private void scanner_OnHeroLogin(CityOfHeroes.HeroData hero) { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.HeroLoginHandler(scanner_OnHeroLogin)); else { lbStatus.Items.Add(string.Format("Hero '{0}' just logged in", hero.Name)); } } /// <summary> /// Handles an event that gets fired when a new hero logs out of CoH /// </summary> /// <param name="hero">Information about the hero logging out</param> private void scanner_OnHeroLogout(CityOfHeroes.HeroData hero) { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.HeroLogoutHandler(scanner_OnHeroLogout)); else { lbStatus.Items.Add(string.Format("Hero '{0}' just logged out", hero.Name)); } } /// <summary> /// Handles an event that gets fired when an error occurs in the scanner /// </summary> /// <param name="msg">Details of the error. Also stored in CohScanner.Error</param> private void scanner_OnScanningError(string msg) { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ScanningErrorHandler(scanner_OnScanningError)); else { lbStatus.Items.Add(string.Format("A scanning error occurred. {0}", msg)); } } /// <summary> /// Handles an event that gets fired when the scanner is programmatically paused /// </summary> private void scanner_OnScanningPaused() { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ScanningInactiveHandler(scanner_OnScanningPaused)); else { lbStatus.Items.Add("The scanner has been paused"); } } /// <summary> /// Handles an event that gets fired when the scanner is programmatically resumed /// after a pause /// </summary> private void scanner_OnScanningResumed() { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ScanningActiveHandler(scanner_OnScanningResumed)); else { lbStatus.Items.Add("Scanning is resumed"); } } /// <summary> /// Handles an event that gets fired when the scanner has started. Its first action /// is to try to find the CoH client. Once it finds it, it switches to reading the /// chat messages. Note that both of these activities are termed "scanning" /// </summary> private void scanner_OnScanningStart() { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ScanningStartHandler(scanner_OnScanningStart)); else { lbStatus.Items.Add("The scanner has been started"); } } /// <summary> /// Handles an event that gets fired when the scanner has been told to stop scanning. /// </summary> private void scanner_OnScanningStop() { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ScanningStopHandler(scanner_OnScanningStop)); else { lbStatus.Items.Add("The scanner has been stopped"); } } /// <summary> /// Handles an event that gets fired when a chat message has been detected. /// </summary> /// <param name="message">The incoming message</param> private void scanner_OnChatMessage(CityOfHeroes.ChatMessage message) { if (InvokeRequired) Invoke(new CityOfHeroes.Scanner.ChatMessageEventHandler(scanner_OnChatMessage)); else { lbMessages.Items.Add(string.Format("ChatMessage from {0} at {1}: {2}", message.Channel, message.Timestamp, message.Message)); lbMessages.Items.Add(string.Format(" Category: {0}", message.Category)); } } #endregion } }