Just a quick and dirty example of using stock Windows forms in a plugin that doesn't require Visual Studio. It basically subscribes to stock API notifications for inbound chat messages, show's how to use the data view grid and delegates for managing multiple threads where forms are concerned.
Note: This doesn't diminish the benefits of using Visual Studio; it's easier to maintain a separation of concerns yet in a single shared source file, may not be evident to the casual bot developer.
Note: This doesn't diminish the benefits of using Visual Studio; it's easier to maintain a separation of concerns yet in a single shared source file, may not be evident to the casual bot developer.
Code:
#region Using Directives
using ArcheBuddy.Bot.Classes;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
#endregion
namespace Experiment
{
public class WindowsFormExample
: Core
{
#region Private Fields
private bool _isOpen = true;
private Form _form;
private Thread _formThread;
private DataGridView messageGrid;
private DataGridViewTextBoxColumn timeStamp;
private DataGridViewTextBoxColumn from;
private DataGridViewTextBoxColumn message;
private DataGridViewTextBoxColumn type;
#endregion
#region Private Methods
private void InitializeForm()
{
_form = new Form();
_form.Width = 500;
_form.Height = 500;
_form.Text = GetPluginDescription();
_form.FormBorderStyle = FormBorderStyle.Sizable;
_form.MaximizeBox = false;
_form.MinimizeBox = true;
_form.TopMost = true;
messageGrid = new DataGridView();
timeStamp = new DataGridViewTextBoxColumn();
from = new DataGridViewTextBoxColumn();
message = new DataGridViewTextBoxColumn();
type = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(messageGrid)).BeginInit();
_form.SuspendLayout();
_form.Controls.Add(messageGrid);
// Grid
messageGrid.AllowUserToAddRows = false;
messageGrid.AllowUserToDeleteRows = false;
messageGrid.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom)
| AnchorStyles.Left)
| AnchorStyles.Right)));
messageGrid.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
messageGrid.Columns.AddRange(new DataGridViewColumn[] {
timeStamp,
from,
message,
type});
messageGrid.Location = new System.Drawing.Point(0, 0);
messageGrid.Name = "Messages";
messageGrid.ReadOnly = true;
messageGrid.Size = new System.Drawing.Size(445, 300);
messageGrid.TabIndex = 0;
messageGrid.Dock = DockStyle.Top;
// Grid Columns
// Message Timestamp
timeStamp.HeaderText = "Received";
timeStamp.Name = "TimeStamp";
timeStamp.ReadOnly = true;
timeStamp.Width = 125;
// Message From
from.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
from.HeaderText = "From";
from.Name = "From";
from.ReadOnly = true;
from.Width = 55;
// Message Body
message.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
message.HeaderText = "Message";
message.Name = "Message";
message.ReadOnly = true;
// Message Type
type.HeaderText = "Type";
type.Name = "Type";
type.ReadOnly = true;
_form.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
_form.AutoScaleMode = AutoScaleMode.Font;
_form.ClientSize = new System.Drawing.Size(571, 384);
_form.Name = "ChatLog";
_form.Text = "Chat Log";
_form.ResumeLayout(false);
_form.FormClosed += new FormClosedEventHandler(message_FormClosed);
}
private void RunForm()
{
try
{
InitializeForm();
Application.Run(_form);
}
catch (Exception error)
{
Log(error.ToString());
}
}
private void message_FormClosed(object sender, FormClosedEventArgs e)
{
_isOpen = false;
}
#endregion
#region Default Archebuddy Methods
public static string GetPluginAuthor()
{
return "AUser";
}
public static string GetPluginVersion()
{
return "1.0.0.0";
}
public static string GetPluginDescription()
{
return "Form Sample";
}
//Call on plugin start
public void PluginRun()
{
ClearLogs();
Log("Starting ------------------");
_formThread = new Thread(RunForm);
_formThread.SetApartmentState(ApartmentState.STA);
_formThread.Start();
onChatMessage += ChatMessage;
while (_isOpen)
Thread.Sleep(100);
}
//Call on plugin stop
public void PluginStop()
{
onChatMessage -= ChatMessage;
try
{
if (_form != null)
{
_form.Invoke(new Action(() => _form.Close()));
_form.Invoke(new Action(() => _form.Dispose()));
}
if (_formThread.ThreadState == System.Threading.ThreadState.Running)
{
_formThread.Abort();
_formThread.Join();
}
}
catch
{
Log("Stopping ------------------");
}
}
#endregion
#region Public Methods
public void ChatMessage(ChatType chatType, string text, string sender)
{
if (!_form.IsHandleCreated)
_form.CreateControl();
// Parse linked item's from chat messages and replace with actual item names
if (text.Contains("|i"))
{
// String.format because strings are immutable in C#
string value = string.Empty;
var matches = Regex.Matches(text, @"\|i([^\|i.]*)\;").OfType<Match>().Select(x => x.Groups[1].Value).ToList();
foreach (var item in matches)
{
value = sqlCore.sqlItems.Where(i => i.Key == Convert.ToInt32(item.Split(',')[0])).Select(i => i.Value).FirstOrDefault().name;
text = text.Replace(string.Format("|i{0};", item.ToString()), string.Format("[{0}]", value));
}
}
_form.Invoke((MethodInvoker)delegate
{
messageGrid.Rows.Add(new string[] { DateTime.Now.ToString(), sender, text, chatType.ToString() });
messageGrid.FirstDisplayedScrollingRowIndex = messageGrid.RowCount - 1;
});
}
#endregion
}
}