As per Sam's request the program is on the free section.
This's been quite an effort since it's been only coded at nights. I still have Visual Basic code snippets which I must adapt to C# to add to this; just haven't done enough in "Zombie mode", yet each day from now up to March 1st an addition is gong to be made to this :nod:
I can only offer my sincere apologies to Sam, as well as big thank you in the name of the community for giving the program to a general audience.
Download: [attachmini=1]
Screenshot:
[attachimg=2]
Kindly don't report bugs until it moves to final version. I'm adding functionality and addressing many on each iteration :nod:
Hi Sam, this is development.
So each day additions and bugfixes are delivered on a continuous basis.
I'm addressing the handling of the triple-wheel clicker right now. Each nite a little gets added -in GMT -4:30 (VE time).
Source code checkout for 2013-02-17:
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using Microsoft.VisualBasic;
namespace GUT_TC_0_1
{
public partial class Form1 : Form
{
/// <summary>
/// Constructor
/// </summary>
public Form1()
{
InitializeComponent();
// Set icon
this.Icon = Properties.Resources.roulette_icon_256to16;
}
// intPtr holding Last Window
public IntPtr LastWindow = IntPtr.Zero;
// History implemented as stack
Stack<int> history = new Stack<int>();
// Redo implemented as stack too
Stack<int> redo = new Stack<int>();
// Instantiate history form
Form fHistory = new FormHistory();
// Instantiate counter form
Form fCount = new FormCount();
// Instantiate advisor form
Form fAdvisor = new FormAdvisor();
// XML settings Filename
string xmlFile = Path.GetDirectoryName(Application.ExecutablePath) + "\\GUT-TC.xml";
// Reference to DataGridView in FormCount
DataGridView dgvCount;
// Reference to DataGridView in FormAdvisor
DataGridView dgvAdvisor;
// Reference to History ListBox
ListBox lbHistory;
// Counter as BindingList of NumberCount (bound to DataGridView in FormCount)
BindingList<NumberCount> Counter = new BindingList<NumberCount>();
// Counter as BindingList of AdvisorRow (bound to DataGridView in FormAdvisor)
BindingList<AdvisorRow> Advisor = new BindingList<AdvisorRow>();
/// <summary>
/// Program's entrypoint
/// </summary>
private void Form1_Load(object sender, EventArgs e)
{
// Declare control array
PictureBox[] pbCtrl = { pb0, pb37, pb1, pb2, pb3, pb4, pb5, pb6, pb7, pb8, pb9, pb10, pb11, pb12, pb13, pb14, pb15, pb16, pb17, pb18, pb19, pb20, pb21, pb22, pb23, pb24, pb25, pb26, pb27, pb28, pb29, pb30, pb31, pb32, pb33, pb34, pb35, pb36 };
// Attach events to each control
foreach (PictureBox ctrl in pbCtrl)
{
// MouseLeave
ctrl.MouseLeave += new EventHandler(PictureBox_MouseLeave);
// MouseEnter
ctrl.MouseEnter += new EventHandler(PictureBox_MouseEnter);
// MouseDown
ctrl.MouseDown += new MouseEventHandler(PictureBox_MouseDown);
// MouseUp
ctrl.MouseUp += new MouseEventHandler(PictureBox_MouseUp);
// MouseClick
ctrl.MouseClick += new MouseEventHandler(PictureBox_MouseClick);
}
// Set lbHistory
lbHistory = (ListBox)fHistory.Controls["lbHistory"];
// Show history form
fHistory.Show();
// Set dgvCount
dgvCount = (DataGridView)fCount.Controls["dgvCount"];
// Alternating background
dgvCount.RowsDefaultCellStyle.BackColor = Color.White;
dgvCount.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;
// Prevent automatic generation of columns
dgvCount.AutoGenerateColumns = false;
// Prevent resize
dgvCount.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dgvCount.AllowUserToResizeRows = false;
// Add shows column
DataGridViewTextBoxColumn showsColumn = new DataGridViewTextBoxColumn();
showsColumn.DataPropertyName = "Shows";
showsColumn.HeaderText = "Shows";
showsColumn.Width = 50;
showsColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
showsColumn.DefaultCellStyle.Font = new Font(fileToolStripMenuItem.Font, fileToolStripMenuItem.Font.Style ^ FontStyle.Italic);
dgvCount.Columns.Add(showsColumn);
// Add count column
DataGridViewTextBoxColumn countColumn = new DataGridViewTextBoxColumn();
countColumn.DataPropertyName = "Count";
countColumn.HeaderText = "Count";
countColumn.Width = 50;
countColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
countColumn.DefaultCellStyle.Font = new Font(fileToolStripMenuItem.Font, fileToolStripMenuItem.Font.Style ^ FontStyle.Italic);
dgvCount.Columns.Add(countColumn);
// Add numbers column
DataGridViewTextBoxColumn numbersColumn = new DataGridViewTextBoxColumn();
numbersColumn.DataPropertyName = "Numbers";
numbersColumn.HeaderText = "Numbers";
showsColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
numbersColumn.DefaultCellStyle.Font = new Font(fileToolStripMenuItem.Font, fileToolStripMenuItem.Font.Style ^ FontStyle.Italic);
numbersColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dgvCount.Columns.Add(numbersColumn);
// Set dgvCount DataSource
dgvCount.DataSource = Counter;
// Show counters form
fCount.Show();
/********** Advisor **********/
// Set dgvAdvisor
dgvAdvisor = (DataGridView)fAdvisor.Controls["dgvAdvisor"];
// Alternating background
dgvAdvisor.RowsDefaultCellStyle.BackColor = Color.White;
dgvAdvisor.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;
// Prevent automatic generation of columns
dgvAdvisor.AutoGenerateColumns = false;
// Prevent resize
dgvAdvisor.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dgvAdvisor.AllowUserToResizeRows = false;
// Add Crossing column
DataGridViewTextBoxColumn crossingColumn = new DataGridViewTextBoxColumn();
crossingColumn.DataPropertyName = "Crossing";
crossingColumn.HeaderText = "Crossing";
crossingColumn.Width = 55;
crossingColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
crossingColumn.DefaultCellStyle.Font = new Font(fileToolStripMenuItem.Font, fileToolStripMenuItem.Font.Style ^ FontStyle.Italic);
dgvAdvisor.Columns.Add(crossingColumn);
// Add Registry column
DataGridViewTextBoxColumn registryColumn = new DataGridViewTextBoxColumn();
registryColumn.DataPropertyName = "Registry";
registryColumn.HeaderText = "Registry";
registryColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
registryColumn.DefaultCellStyle.Font = new Font(fileToolStripMenuItem.Font, fileToolStripMenuItem.Font.Style ^ FontStyle.Italic);
registryColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dgvAdvisor.Columns.Add(registryColumn);
// Set dgvCount DataSource
dgvAdvisor.DataSource = Advisor;
// Clear pesky first selection
if (dgvAdvisor.Rows.Count > 1 && dgvAdvisor.Rows[0].Selected)
{
dgvAdvisor.Rows[0].Selected = false;
}
// Show advisor form
fAdvisor.Show();
// File Size
FileInfo xmlInfo = new FileInfo(xmlFile);
// Check for XML file's existence and length
if (File.Exists(xmlFile) && xmlInfo.Length > 0)
{
// Set XPath Document
XPathDocument document = new XPathDocument(xmlFile);
// Create XPath Navigator
XPathNavigator navigator = document.CreateNavigator();
// Process Options
foreach (XPathNavigator section in navigator.Select("/GUT-TC/Options"))
{
foreach (XPathNavigator node in section.SelectChildren(XPathNodeType.All))
{
// Toggle options
foreach (ToolStripMenuItem tsmi in optionsToolStripMenuItem.DropDownItems)
{
// Set CheckState
if (tsmi.Name == node.Name + "ToolStripMenuItem")
{
// Load from file
tsmi.CheckState = (node.InnerXml == "Checked" ? CheckState.Checked : CheckState.Unchecked);
}
}
}
}
// Process Layout
foreach (XPathNavigator section in navigator.Select("/GUT-TC/Layout"))
{
foreach (XPathNavigator node in section.SelectChildren(XPathNodeType.All))
{
// Toggle Layout
foreach (ToolStripMenuItem tsmi in layoutToolStripMenuItem.DropDownItems)
{
// Set CheckState
if (tsmi.Name == node.Name + "ToolStripMenuItem")
{
// Load from file
tsmi.CheckState = (node.InnerXml == "Checked" ? CheckState.Checked : CheckState.Unchecked);
// Set Layout
if (tsmi.Checked)
{
// Click
tsmi.PerformClick();
}
}
}
}
}
// Coordinates
if (saveCoordinatesToolStripMenuItem.Checked)
{
// Process
foreach (XPathNavigator section in navigator.Select("/GUT-TC/Coordinates"))
{
foreach (XPathNavigator subsection in section.SelectChildren(XPathNodeType.All))
{
// Process forms
foreach (Form frm in Application.OpenForms)
{
// Match
if (frm.Name == subsection.Name)
{
// Set X,Y
foreach (XPathNavigator node in subsection.SelectChildren(XPathNodeType.All))
{
// X
if (node.Name == "x")
{
frm.Left = Convert.ToInt32(node.InnerXml);
}
// Y
if (node.Name == "y")
{
frm.Top = Convert.ToInt32(node.InnerXml);
}
}
}
}
}
}
}
// Process NumericUpDowns
foreach (XPathNavigator section in navigator.Select("/GUT-TC/NUDs"))
{
foreach (XPathNavigator node in section.SelectChildren(XPathNodeType.All))
{
// Set value
foreach (Control c in this.Controls)
{
// Set if matches
if (c is NumericUpDown && c.Name == node.Name)
{
// Set values
((NumericUpDown)c).Value = Convert.ToDecimal(node.InnerXml);
}
}
}
}
}
else
{
// Default options check state
topmostToolStripMenuItem.Checked = true;
saveCoordinatesToolStripMenuItem.Checked = true;
europeanToolStripMenuItem.Checked = true;
// Set Layout to Euro
europeanToolStripMenuItem.PerformClick();
// Jump back
nudJB.Value = 20;
// Unit size
nudUS.Value = 1;
// Max show
nudMS.Value = 10;
}
}
/// <summary>
/// MouseEnter handler
/// </summary>
private void PictureBox_MouseEnter(object sender, System.EventArgs e)
{
// Show alpha-blended image
((PictureBox)sender).BackgroundImage = Properties.Resources.yellow_highlight_alpha_38x47;
}
/// <summary>
/// MouseLeave handler
/// </summary>
private void PictureBox_MouseLeave(object sender, System.EventArgs e)
{
// Remove image
((PictureBox)sender).BackgroundImage = null;
}
/// <summary>
/// MouseDown Handler
/// </summary>
private void PictureBox_MouseDown(object sender, MouseEventArgs e)
{
// Check for left button
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
// Change cursor to hand
((PictureBox)sender).Cursor = Cursors.Hand;
// Show blue alpha-blended image
((PictureBox)sender).BackgroundImage = Properties.Resources.blue_highlight_alpha_38x47;
}
}
/// <summary>
/// MouseUp Handler
/// </summary>
private void PictureBox_MouseUp(object sender, MouseEventArgs e)
{
// Show yellow alpha-blended image
((PictureBox)sender).BackgroundImage = Properties.Resources.yellow_highlight_alpha_38x47;
// Change cursor back
((PictureBox)sender).Cursor = Cursors.Default;
}
/// <summary>
/// MouseClick handler
/// </summary>
private void PictureBox_MouseClick(object sender, MouseEventArgs e)
{
/* Right click = UNDO */
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
// Check there's history
if (history.Count > 0)
{
// Pop last one
history.Pop();
// Remove from history ListBox
lbHistory.Items.RemoveAt(0);
}
// Disable if no history
if (history.Count == 0)
{
// Disable
//disable();
}
// Take one from window
if (nudW.Value > 0)
{
nudW.Value = nudW.Value - 1;
}
// Update
update();
// Halt flow
return;
}
// Check sender
if (!(sender is PictureBox))
{
// Halt flow too
return;
}
/* Left click = add to history */
// Snip number as string
string sNumber = ((PictureBox)sender).Name.ToString().Substring(2);
// Handle double zero
int number = (sNumber == "00" ? 37 : Convert.ToInt32(sNumber));
// Push onto history stack
history.Push(number);
// Add to history ListBox
lbHistory.Items.Insert(0, number);
// Enable on first item
if (history.Count == 1)
{
// enable();
}
// Disable redo if manual input
if (redo.Count > 0 && e.Delta != 1)
{
// Reset stack
redo.Clear();
// Disable
redoToolStripMenuItem.Enabled = false;
}
// Rise 1 to window
nudW.Value = nudW.Value + 1;
// Update
update();
}
/// <summary>
/// Change to No Zero felt
/// </summary>
private void noZeroToolStripMenuItem_Click(object sender, EventArgs e)
{
// Hide 0,00
pb0.Visible = false;
pb37.Visible = false;
// Change background
this.BackgroundImage = Properties.Resources.felt_no_zero_numbers_only_trimmed3;
// Reset CasinoInfo
CasinoInfo.Reset();
// Set wheel type
wheel.NoZero();
// Proper checked
noZeroToolStripMenuItem.Checked = true;
europeanToolStripMenuItem.Checked = false;
americanToolStripMenuItem.Checked = false;
}
/// <summary>
/// Change to European felt
/// </summary>
private void europeanToolStripMenuItem_Click(object sender, EventArgs e)
{
// Hide 00
pb37.Visible = false;
// Change 0/00 location
pb0.Location = new Point(23, 76);
pb37.Location = new Point(23, 23);
// Show 0
pb0.Visible = true;
// Change background
this.BackgroundImage = Properties.Resources.felt_numbers_only_trimmed3;
// Reset CasinoInfo
CasinoInfo.Reset();
// Set wheel type
wheel.European();
// Proper checked
noZeroToolStripMenuItem.Checked = false;
europeanToolStripMenuItem.Checked = true;
americanToolStripMenuItem.Checked = false;
}
/// <summary>
/// Change to American felt
/// </summary>
private void americanToolStripMenuItem_Click(object sender, EventArgs e)
{
// Change 0/00 location
pb0.Location = new Point(29, 110);
pb37.Location = new Point(28, 47);
// Show 0,00
pb0.Visible = true;
pb37.Visible = true;
// Change background
this.BackgroundImage = Properties.Resources.felt_american_numbers_only_trimmed3;
// Reset CasinoInfo
CasinoInfo.Reset();
// Set wheel type
wheel.American();
// Proper checked
noZeroToolStripMenuItem.Checked = false;
europeanToolStripMenuItem.Checked = false;
americanToolStripMenuItem.Checked = true;
}
/// <summary>
/// Update procedure
/// </summary>
private void update()
{
// Window counter array
int[] wCount = new int[wheel.count];
// List of int for numbers (in)
List<int> numbers = new List<int>();
// List of int for "greater than" numbers
List<int> gtNumbers = new List<int>();
// Clear counter
Counter.Clear();
// Recount numbers
for (int i = 0; i < nudW.Value; ++i)
{
// Cast to int
int number = Convert.ToInt32(lbHistory.Items[(lbHistory.Items.Count - 1) - i].ToString());
// Rise number
wCount[number]++;
}
// Add to Counter (so it updates DataGridView)
for (int i = Convert.ToInt32(nudMS.Value); i >= 0; --i)
{
// Clear number list
numbers.Clear();
// Browse wCount for current show
for (int n = 0; n < wheel.count; ++n)
{
// Check for a match
if (wCount[n] == i)
{
// Add to numbers
numbers.Add(n);
}
}
// Check point for addition
if (numbers.Count == 0)
{
// Skip iteration
continue;
}
// Add regular
Counter.Insert(0, new NumberCount(i.ToString(), numbers.Count, numbers));
// Check for addition Limits
if (i == 0)
{
// Skip iteration
continue;
}
// Add greater than column
if (gtNumbers.Count > 0)
{
Counter.Insert(1, new NumberCount(">" + i.ToString(), gtNumbers.Count, gtNumbers));
}
// Set "greater than" numbers (for next iteration)
gtNumbers.AddRange(numbers);
}
/* Scan dgvCount for crossings */
// Clear Advisor bindinglist
Advisor.Clear();
// Declare diff
int diff;
// Scan for 0 vs 1
diff = (Convert.ToInt32(dgvCount.Rows[0].Cells[1].Value) - Convert.ToInt32(dgvCount.Rows[1].Cells[1].Value));
if (diff == 1 || diff == 0) // TODO: Refactor ranges
{
// add to advisor
Advisor.Insert(0, new AdvisorRow("0 vs 1", new List<string> { "c", "h", "e", "c", "k" }));
}
// Iterate the rest
for (int i = 1; i < dgvCount.Rows.Count - 2; ++i)
{
// Scan for same number match
if (dgvCount.Rows[i].Cells[0].Value.ToString() == dgvCount.Rows[i + 1].Cells[0].Value.ToString().Replace(">", ""))
{
// Set diff
diff = (Convert.ToInt32(dgvCount.Rows[i].Cells[1].Value) - Convert.ToInt32(dgvCount.Rows[i + 1].Cells[1].Value));
if (diff == 1 || diff == 0) // TODO: Refactor ranges
{
// Matched, add to advisor
Advisor.Insert(0, new AdvisorRow(dgvCount.Rows[i].Cells[0].Value.ToString() + " vs >" + dgvCount.Rows[i].Cells[0].Value.ToString(), new List<string> { "c", "h", "e", "c", "k" }));
}
}
}
// Change "0" BackColor
if (dgvCount.Rows.Count > 0 && Convert.ToInt32(dgvCount.Rows[0].Cells[0].Value) == 0)
{
// Change it
dgvCount.Rows[0].DefaultCellStyle.BackColor = Color.LightGray;
}
// Update status strip count
tsslHistory.Text = history.Count.ToString();
}
/// <summary>
/// NumberCount Class
/// </summary>
public class NumberCount
{
// Shows
public string _shows;
// Count
public int _count;
// Numbers
public string _numbers;
/// <summary>
/// Overloaded constructor
/// </summary>
/// <param name="shows">int for shows</param>
/// <param name="splits">List of int for numbers</param>
public NumberCount(string shows, int count, List<int> numbers)
{
// Set shows
_shows = shows;
// Set count
_count = count;
// Intermediate list
List<string> sNum = new List<string>();
// Populate list
foreach (int n in numbers)
{
// Add current one
sNum.Add((n == 37 ? "00" : n.ToString()));
}
// Set _numbers field
_numbers = String.Join(",", sNum.ToArray());
}
/// <summary>
/// Shows property
/// </summary>
public string Shows
{
get { return _shows; }
set { _shows = value; }
}
/// <summary>
/// Count property
/// </summary>
public int Count
{
get { return _count; }
set { _count = value; }
}
/// <summary>
/// Splits property
/// </summary>
public string Numbers
{
get
{
return _numbers;
}
}
}
/// <summary>
/// NumberCount Class
/// </summary>
public class AdvisorRow
{
// Crossing
public string _crossing;
// Registry
public string _registry;
/// <summary>
/// Overloaded constructor
/// </summary>
public AdvisorRow(string crossing, List<string> registry)
{
// Set crossing
_crossing = crossing;
// Set registry
_registry = String.Join(",", registry.ToArray());
}
/// <summary>
/// Crossing property
/// </summary>
public string Crossing
{
get { return _crossing; }
set { _crossing = value; }
}
/// <summary>
/// Registry property
/// </summary>
public string Registry
{
get
{
return _registry;
}
}
}
/// <summary>
/// Set window to
/// </summary>
private void bJump_Click(object sender, EventArgs e)
{
// Check if can jump
if (nudJB.Value < nudW.Value)
{
// Jump!
nudW.Value = nudJB.Value;
// Update
update();
}
}
/// <summary>
/// Max. Shows changed
/// </summary>
private void nudMS_ValueChanged(object sender, EventArgs e)
{
// Refresh if there's something in History
if (history.Count > 0)
{
// Trigger update
update();
}
}
/// <summary>
/// Spin Window change
/// </summary>
private void nudW_ValueChanged(object sender, EventArgs e)
{
// Prevent it from gong beyond history
if (nudW.Value > history.Count)
{
// Set it back
nudW.Value = history.Count;
}
// Refresh if there's something in History
if (history.Count > 0 && nudW.Value > 0)
{
// Trigger update
update();
}
}
/// <summary>
/// Cursor enters Jump Back button
/// </summary>
private void bJump_MouseEnter(object sender, EventArgs e)
{
// Change background image
bJump.BackgroundImage = Properties.Resources.yellow_highlight_alpha_38x47;
}
/// <summary>
/// Cursor exits Jump Back button
/// </summary>
private void bJump_MouseLeave(object sender, EventArgs e)
{
// Change background image back
bJump.BackgroundImage = null;
}
/// <summary>
/// Save XMl file right before closing
/// </summary>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// Check for confirmation
if (confirmOnExitToolStripMenuItem.Checked)
{
// Prompt user
if (MessageBox.Show("Exit the program now?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
{
// Cancel form close
e.Cancel = true;
// Exit procedure
return;
}
}
// Instantiate XmlTextWriter
XmlTextWriter writer = new XmlTextWriter(xmlFile, null);
// Set formatting
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
// Document start
writer.WriteStartDocument();
// Root start
writer.WriteStartElement("GUT-TC");
// Options start
writer.WriteStartElement("Options");
// Write options
foreach (ToolStripMenuItem tsmi in optionsToolStripMenuItem.DropDownItems)
{
// Save checked status
writer.WriteElementString(tsmi.Name.Replace("ToolStripMenuItem", ""), tsmi.CheckState.ToString());
}
// Options end
writer.WriteEndElement();
/* Layout */
// Layout start
writer.WriteStartElement("Layout");
// Write Layout
foreach (ToolStripMenuItem tsmi in layoutToolStripMenuItem.DropDownItems)
{
// Save checked status
writer.WriteElementString(tsmi.Name.Replace("ToolStripMenuItem", ""), tsmi.CheckState.ToString());
}
// Layout end
writer.WriteEndElement();
/* NumericUpDown */
// NumericUpDown start
writer.WriteStartElement("NUDs");
// Write NumericUpDowns
foreach (Control c in this.Controls)
{
if (c is NumericUpDown)
{
// Save name/value
writer.WriteElementString(((NumericUpDown)c).Name, ((NumericUpDown)c).Value.ToString());
}
}
// NumericUpDown end
writer.WriteEndElement();
/* Coordinates */
// Coordinates start
writer.WriteStartElement("Coordinates");
// Iterate through forms
foreach (Form frm in Application.OpenForms)
{
// Current form start
writer.WriteStartElement(frm.Name);
// Save coordinates
writer.WriteElementString("x", frm.Left.ToString());
writer.WriteElementString("y", frm.Top.ToString());
// Current form end
writer.WriteEndElement();
}
// Coordinates end
writer.WriteEndElement();
//// LastX start
//writer.WriteStartElement("LastX");
//// X value
//writer.WriteElementString("X", nudX.Value.ToString());
//// LastX end
//writer.WriteEndElement();
// Root start
writer.WriteEndElement();
// Document end
writer.WriteEndDocument();
// Close writer
writer.Close();
}
/// <summary>
/// Handle MouseDown on Bullseye
/// </summary>
private void pbCursor_MouseDown(object sender, MouseEventArgs e)
{
// Set cursor
Cursor = new Cursor(new System.IO.MemoryStream(Properties.Resources.searchw));
// Change image to blank background one
pbCursor.Image = Properties.Resources.findere;
}
/// <summary>
/// Handle MouseUp on Bullseye
/// </summary>
private void pbCursor_MouseMove(object sender, MouseEventArgs e)
{
if (Cursor != Cursors.Default)
{
// We are, determine found window
IntPtr FoundWindow = cWin32.ChildWindowFromPoint(Cursor.Position);
// Not this application
if (Control.FromHandle(FoundWindow) == null)
{
// Not an already-processed window
if (FoundWindow != LastWindow)
{
// clear old window
cWin32.ShowInvertRectTracker(LastWindow);
// Set new window
LastWindow = FoundWindow;
// Paint inverted rectangle on new window
cWin32.ShowInvertRectTracker(LastWindow);
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pbCursor_MouseUp(object sender, MouseEventArgs e)
{
// Check if it's done
if (Cursor != Cursors.Default)
{
// Invert last window back
cWin32.ShowInvertRectTracker(LastWindow);
// Change image back
pbCursor.Image = Properties.Resources.finderf;
// Change cursor back
Cursor = Cursors.Default;
// Check if the casino is already loaded
if (cCasino.LoadCasino(LastWindow))
{
// Casino is loaded, nothing else to do
goto ResetLast;
}
/* Casino is not loaded, start the process of saving casino */
// Set all forms invisible
Program.allVisible(false);
// Reset all dictionaries and variables
// Ask for chips
string chipAmount = "";
while (chipAmount.Length == 0)
{
chipAmount = Interaction.InputBox("Please enter the number of chips on this roulette table:", "Chip amount");
// Check length
if (chipAmount.Length == 0)
{
// Ask for a halt
if (MessageBox.Show("Do you want to halt coordinates capturing process?", "No chip amount entered", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
// Set all visible
Program.allVisible(true);
// Halt process without saving
goto ResetLast;
}
else
{
// Set chipAmount to empty
chipAmount = string.Empty;
// Go to next iteration
continue;
}
}
// Set casino chip
int chipsInt;
if (!Int32.TryParse(chipAmount, out chipsInt))
{
// Ask for a halt
if (MessageBox.Show("Do you want to halt coordinates capturing process?", "No valid number entered", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
// Set all visible
Program.allVisible(true);
// Halt process without saving
goto ResetLast;
}
else
{
// Set chipAmount to empty
chipAmount = string.Empty;
// Go to next iteration
continue;
}
}
// Set casino name, as everything is good
CasinoInfo.chips = chipsInt;
}
// Set last window as target on cCasino
cCasino.targetWindow = LastWindow;
// Instantiate capture form
Form fCapture = new FormCapture();
// Set backgruond
fCapture.BackgroundImage = cWin32.CaptureWindow(LastWindow);
// Set width and height
fCapture.ClientSize = new Size(fCapture.BackgroundImage.Width, fCapture.BackgroundImage.Height);
// Set fCapture to visible
fCapture.Visible = true;
//Reset label
ResetLast:
// Reset last window
LastWindow = IntPtr.Zero;
}
}
}
}
FormCapture.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.Globalization;
namespace GUT_TC_0_1
{
public partial class FormCapture : Form
{
// Index for number
int index;
// Title
string title;
// List for numbers
List<string> addList = new List<string>();
/// <summary>
/// Constructor
/// </summary>
public FormCapture()
{
// Set index to zero
index = 0;
// Clear numbers dictionary
cCasino.Coords.Clear();
// Zero for euro and american
if (wheel.type == wheel.Type.European || wheel.type == wheel.Type.American)
{
addList.Add("0");
}
// Double zero for american
if (wheel.type == wheel.Type.American)
{
addList.Add("00");
}
// Add 1-36 for all
for (int i = 1; i <= 36; ++i)
{
addList.Add(i.ToString());
}
// Initialize
InitializeComponent();
// Set icon
this.Icon = Properties.Resources.roulette_icon_256to16;
}
/// <summary>
/// Entrypoint
/// </summary>
private void FormCapture_Load(object sender, EventArgs e)
{
// Set title
title = "Please click on number >" + addList[index] + "<";
// Set caption
this.Text = title;
}
/// <summary>
/// Handles number addition
/// </summary>
private void FormCapture_MouseClick(object sender, MouseEventArgs e)
{
/* Handle right click */
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
// Check if there's one to take
if (cCasino.Coords.Count > 0)
{
// Remove latest
cCasino.Coords.RemoveAt(cCasino.Coords.Count - 1);
// Decrement index by one
--index;
}
// Exit
goto finish;
}
/* Handle left click*/
// Set chip holding variables //POSSIBLE TODO: Refactor so they are only declared and used after index > 36
string chipValue = "";
float chipVal = (float)0.0;
// Ask for chips
if (index >= wheel.count)
{
while (chipValue.Length == 0)
{
// Make invisible
this.Visible = false;
// As for current chip
chipValue = Interaction.InputBox("Please enter the value of last chip:" + Environment.NewLine + "(Use a point as decimal separator)", "Chip #" + (index - (wheel.count - 1)) + " value");
// Check length
if (chipValue.Length == 0)
{
// Ask for a halt
if (MessageBox.Show(this, "Do you want to halt coordinates capturing process?", "No chip value entered", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
// Halt process without saving
goto noSaveChip;
}
else
{
// Set chipAmount to empty
chipValue = string.Empty;
// Make Visible
this.Visible = true;
// Go to next iteration
continue;
}
}
// Set casino chip
if (!float.TryParse(chipValue, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out chipVal))
{
// Ask for a halt
if (MessageBox.Show(this, "Do you want to halt coordinates capturing process?", "Invalid number entered", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
// Halt process without saving
goto noSaveChip;
}
else
{
// Set chipAmount to empty
chipValue = string.Empty;
// Make Visible
this.Visible = true;
// Go to next iteration
continue;
}
}
// Break code flow here
break;
noSaveChip:
// Bring everything back to visible
Program.allVisible(true);
// Dispose the form
this.Dispose();
// Exit
return;
}
}
// Add current number's coordinates //TODO HANDLE DUPLICATE CHIPS DONE BY USER MISTAKE
cCasino.Coords.Add((index <= (wheel.count - 1) ? addList[index] : "c:" + chipVal.ToString(CultureInfo.InvariantCulture)), new Point(e.X, e.Y));
// Check if we're done
if (index == ((wheel.count - 1) + CasinoInfo.chips))
{
// Process finished, hide form
this.Visible = false;
// Show messagebox asking for casino name
string casinoName = "";
while (casinoName.Length == 0)
{
casinoName = Interaction.InputBox("Please enter casino name:", "Casino");
// Check length
if (casinoName.Length == 0)
{
// Ask for a halt
if (MessageBox.Show(this, "Do you want to halt coordinates capturing process?", "No casino name to save", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
// Halt process without saving
goto noSaveCasino;
}
}
else
{
// Set casino name
CasinoInfo.name = casinoName;
}
}
// Save casino
cCasino.SaveCasino();
// noSaveCasino label
noSaveCasino:
// Bring everything back to visible
Program.allVisible(true);
// Dispose the form
this.Dispose();
// Exit
return;
}
else
{
// We aren't done, set visible for next iteration
this.Visible = true;
}
// Rise index
++index;
finish:
// Set title
title = "Please click on " + (index <= (wheel.count - 1) ? "number" : "chip") + " >" + (index <= (wheel.count - 1) ? addList[index] : "#" + (index - (wheel.count - 1))) + "<";
// Set caption
this.Text = title;
}
/// <summary>
/// Updates title bar
/// </summary>
private void FormCapture_MouseMove(object sender, MouseEventArgs e)
{
// Append current coordinates to title
this.Text = title + " x:" + e.X + "," + "y:" + e.Y;
}
/// <summary>
/// Ask when closing
/// </summary>
private void FormCapture_FormClosing(object sender, FormClosingEventArgs e)
{
// If there's something saved and the user clicked
if (index > 0 && e.CloseReason == CloseReason.UserClosing)
{
// Ask
if (MessageBox.Show(this, "Do you want to halt coordinates capturing process?", "Halt", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.No)
{
// Cancel
e.Cancel = true;
// Exit
return;
}
}
// Bring everything back to visible
Program.allVisible(true);
}
}
}
cCasino.cs
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using System.Collections;
using System.Drawing;
using System.Xml;
using System.Xml.XPath;
using System.Windows.Forms;
namespace GUT_TC_0_1
{
// Casino info static class
public static class CasinoInfo
{
// Name
public static string name;
// Dimensions
public static int width;
public static int height;
// Class name
public static string className;
// Handle
public static IntPtr handle;
// Chips amount
public static int chips;
// Coordinates
public static Dictionary<string, Point> coords = new Dictionary<string, Point>();
// Reset
public static void Reset()
{
// Name
name = string.Empty;
// Dimensions
width = 0;
height = 0;
// Class name
className = string.Empty;
// Handle
handle = IntPtr.Zero;
// Chips
chips = 0;
// Coordinates
coords.Clear();
}
}
static class cCasino
{
// Target casino window
public static System.IntPtr targetWindow;
// xmlFile
public static string xmlFile = "";
// Casino directory
public static string casinoDir = System.AppDomain.CurrentDomain.BaseDirectory + "casinos";
// Ordered number coordinates for XML
public static OrderedDictionary Coords = new OrderedDictionary();
// Ordered chip values for XML
public static OrderedDictionary chipValues = new OrderedDictionary();
/// <summary>
/// Loads casino using passed window
/// </summary>
/// <param name="window">Target (passed)</param>
/// <returns>True if casino is already present</returns>
public static bool LoadCasino(IntPtr window)
{
// Check if casinos directory exists
if (!Directory.Exists(casinoDir))
{
// Doesn't exist
return false;
}
// Declare and populate string array for files
string[] files = Directory.GetFiles(System.AppDomain.CurrentDomain.BaseDirectory + "casinos", "*.xml");
// Check if there is at least one file to work with
if (files.Length == 0)
{
// Exit
return false;
}
/* <Parse by date> */
List<string> Filelist = new List<string>();
IComparer comp = new FileComparer(FileComparer.CompareBy.CreationTime);
Array.Sort(files, comp);
foreach (string file in files)
{
Filelist.Add(file);
}
Filelist.Reverse();
/* </Parse by date> */
//DEBUG
foreach (string current in Filelist)
{
// Show
MessageBox.Show(current);
}
// Return false
return false;
}
/// <summary>
/// Saves casino information and coordinates to XML file
/// </summary>
/// <returns>True on success</returns>
public static bool SaveCasino()
{
/* Populate casino info structure */
// Set target casino window handle
CasinoInfo.handle = targetWindow;
// Rectangle structure
Rectangle rect;
// Try to set rect
try
{
// Get a rect from targetWindow
rect = cWin32.GetWindowRect(targetWindow);
}
catch (Exception)
{
return false;
}
//' Width
CasinoInfo.width = rect.Width;
//' Height
CasinoInfo.height = rect.Height;
//' ClassName
StringBuilder sbClassName = new StringBuilder("", 256);
// Pass in the handle of the object for which to get the class name; for example, the form's handle
cWin32.GetClassName(targetWindow, sbClassName, sbClassName.Capacity);
// Assign
CasinoInfo.className = sbClassName.ToString();
// Clear Coordinates
CasinoInfo.coords.Clear();
/* Populate coordinates */
// Check if casino directory
if (!Directory.Exists(casinoDir))
{
// Create it
Directory.CreateDirectory(casinoDir);
}
// Prepare XML file: <casino dir>/<casino name>_<wheel type>_<current date>.xml
xmlFile = casinoDir + Path.DirectorySeparatorChar + CasinoInfo.name + "_" + wheel.type.ToString().ToUpper() + "_" + DateTime.Now.ToString("dd-MM-yy_HH-mm-ss") + ".xml";
// Instantiate XmlTextWriter
XmlTextWriter writer = new XmlTextWriter(xmlFile, null);
// Set formatting
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
// Document start
writer.WriteStartDocument();
// Root start
writer.WriteStartElement("CASINO");
// Info start
writer.WriteStartElement("INFO");
// Info fields
writer.WriteElementString("Name", CasinoInfo.name.ToString());
writer.WriteElementString("Width", CasinoInfo.width.ToString());
writer.WriteElementString("Height", CasinoInfo.height.ToString());
writer.WriteElementString("ClassName", CasinoInfo.className.ToString());
// INFO end
writer.WriteEndElement();
// Coordinates (WHEEL TYPE NAME) start
writer.WriteStartElement(wheel.type.ToString().ToUpper());
// Object array for keys
object[] keys = new object[cCasino.Coords.Keys.Count];
cCasino.Coords.Keys.CopyTo(keys, 0);
// Iterate elements
for (int i = 0; i < cCasino.Coords.Count; ++i)
{
// Temporary point
Point p = (Point)cCasino.Coords[i];
// Add to one CasinoInfo class
CasinoInfo.coords.Add(keys[i].ToString(), p);
/* Add to XML file */
// Numbers/Chips
if (i == 0)
{
// Numbers
writer.WriteStartElement("Numbers");
}
else if (i == wheel.count)
{
// Chips
writer.WriteStartElement("Chips");
}
// Remove c: from chips
if (i >= wheel.count)
{
keys[i] = keys[i].ToString().Split(':').GetValue(1);
}
// Write current one
writer.WriteElementString(keys[i].ToString(), p.X.ToString() + "," + p.Y.ToString());
// Close numbers/chips
if (i == (wheel.count - 1) || i == (cCasino.Coords.Count - 1))
{
writer.WriteEndElement();
}
}
// Coordinates (WHEEL TYPE NAME) end
writer.WriteEndElement();
// CASINO end
writer.WriteEndElement();
// Document end
writer.WriteEndDocument();
// Close writer
writer.Close();
// Codepaths
return false;
}
}
}
cWheel.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace GUT_TC_0_1
{
public static class wheel
{
// Enum
public enum Type
{
noZero,
European,
American
}
// First
public static int first;
// Count
public static int count;
// Type
public static Type type;
/* Methods */
// American
public static void American()
{
// Wheel type
type = Type.American;
// Set first
first = 0;
// Set count
count = 38;
}
// European
public static void European()
{
// Wheel type
type = Type.European;
// Set first
first = 0;
// Set count
count = 37;
}
// NoZero
public static void NoZero()
{
// Wheel type
type = Type.noZero;
// Set first
first = 1;
// Set count
count = 36;
}
}
}
FormHistory.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace GUT_TC_0_1
{
public partial class FormHistory : Form
{
public FormHistory()
{
InitializeComponent();
// Set icon
this.Icon = Properties.Resources.roulette_icon_256to16;
}
private void lbHistory_DrawItem(object sender, DrawItemEventArgs e)
{
try
{
// Set sender's ItemHeight
((ListBox)sender).ItemHeight = e.Font.Height + 3;
// Drawing routines
e.DrawBackground();
// Set brush
SolidBrush myBrush = new SolidBrush(getColor(Convert.ToByte(((ListBox)sender).Items[e.Index])));
// Set number string
string sNumber = ((ListBox)sender).Items[e.Index].ToString();
// Resolve 00
if (sNumber == "37")
{
// Change into 00
sNumber = "00";
}
// Draw roulette number
e.Graphics.DrawString(sNumber, e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
e.DrawFocusRectangle();
}
catch (Exception ex)
{
// Nothing
}
}
/// <summary>
/// Determines the color of a number and returns color structure for it
/// </summary>
/// <param name="num">Byte holding input number</param>
/// <returns>Color structure, corresponding to either Black, Red or Green</returns>
public Color getColor(byte num)
{
switch (num)
{
case 1:
case 3:
case 5:
case 7:
case 9:
case 12:
case 14:
case 16:
case 18:
case 19:
case 21:
case 23:
case 25:
case 27:
case 30:
case 32:
case 34:
case 36:
// Red number
return Color.Red;
case 2:
case 4:
case 6:
case 8:
case 10:
case 11:
case 13:
case 15:
case 17:
case 20:
case 22:
case 24:
case 26:
case 28:
case 29:
case 31:
case 33:
case 35:
// Black number
return Color.Black;
default:
// Anything else = green
return Color.Green;
}
}
}
}
(There are other smaller "stock" supporting classes and functions, MSDN constant and such, but all the "how to's" to learn are there)
Edit: some functions differing from "stock" MSDN code:
/// <summary>
/// Returns the window currently present below the cursor. i.e.
/// </summary>
/// <param name="point">Structure holding X, Y coordinates for current cursor location</param>
/// <returns>IntPtr.Zero if no window was found</returns>
public static IntPtr ChildWindowFromPoint(Point point)
{
IntPtr WindowPoint = WindowFromPoint(point);
if (WindowPoint == IntPtr.Zero)
{
return IntPtr.Zero;
}
if (ScreenToClient(WindowPoint, ref point) == false)
{
throw new Exception("ScreenToClient failed");
}
IntPtr Window = ChildWindowFromPointEx(WindowPoint, point, 0);
if (Window == IntPtr.Zero)
{
return WindowPoint;
}
if (ClientToScreen(WindowPoint, ref point) == false)
{
throw new Exception("ClientToScreen failed");
}
if (IsChild(GetParent(Window), Window) == false)
{
return Window;
}
// create a list to hold all childs under the point
ArrayList WindowList = new ArrayList();
while (Window != IntPtr.Zero)
{
Rectangle rect = GetWindowRect(Window);
if (rect.Contains(point))
{
WindowList.Add(Window);
}
Window = GetWindow(Window, Convert.ToUInt32(GetWindow_Cmd.GW_HWNDNEXT));
}
// search for the smallest window in the list
int MinPixel = GetSystemMetrics(SystemMetric.SM_CXFULLSCREEN) * GetSystemMetrics(SystemMetric.SM_CYFULLSCREEN);
for (int i = 0; i <= WindowList.Count - 1; i++)
{
Rectangle rect = GetWindowRect((IntPtr)WindowList[i]);
int ChildPixel = rect.Width * rect.Height;
if (ChildPixel < MinPixel)
{
MinPixel = ChildPixel;
Window = (IntPtr)WindowList[i];
}
}
return Window;
}
public static Image CaptureWindow(IntPtr handle)
{
// Check if it is a window for a start
if (IsWindow(handle) == false)
{
// Clear picturebox
//fCapture.BackgroundImage = null;
// Halt
return null;
}
// get te hDC of the target window
IntPtr hdcSrc = GetWindowDC(handle);
// get the size
RECT windowRect = new RECT();
GetWindowRect(handle, ref windowRect);
int width = windowRect.Right - windowRect.Left;
int height = windowRect.Bottom - windowRect.Top;
// create a device context we can copy to
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = SelectObject(hdcDest, hBitmap);
// bitblt over
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
// restore selection
SelectObject(hdcDest, hOld);
// clean up
DeleteDC(hdcDest);
ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
DeleteObject(hBitmap);
return img;
}
//CaptureWindow
/// <summary>
/// Paint a rect into the given window
/// </summary>
/// <param name="window">Pointer/Handle identifying window on which inverted rectangle is going to be painted</param>
///
public static void ShowInvertRectTracker(IntPtr window)
{
if (window != IntPtr.Zero)
{
// get the coordinates from the window on the screen
Rectangle WindowRect = GetWindowRect(window);
// get the window's device context
IntPtr dc = GetWindowDC(window);
// Create an inverse pen that is the size of the window border
SetROP2(dc, Convert.ToInt32(RopMode.R2_NOT));
Color cColor = Color.FromArgb(0, 255, 0);
IntPtr Pen = CreatePen(6, GetSystemMetrics(SystemMetric.SM_CXBORDER) * 3, Convert.ToUInt32(ColorTranslator.ToWin32(cColor)));
// Draw the rectangle around the window
IntPtr OldPen = SelectObject(dc, Pen);
IntPtr OldBrush = SelectObject(dc, GetStockObject(Convert.ToInt32(StockObjects.NULL_BRUSH)));
Rectangle(dc, 0, 0, WindowRect.Width, WindowRect.Height);
SelectObject(dc, OldBrush);
SelectObject(dc, OldPen);
//release the device context, and destroy the pen
ReleaseDC(window, dc);
DeleteObject(Pen);
}
}
Well, that's ton of work and I can see where it would take some time. Here's a thought: Send the guy a simple email or pm
"Hey, Bro, haven't forgotten you! Working on it daily. Am I OK?"
No friggin' wonder there is war.
Sam
No harm dear Sam, I wish I could deliver you more daytime hours right now but I'm locked until Tuesday with my current inventory contract. With the money I get, I'll be halting local work to deliver this baby to you and the friends.
In a good day I can advance it tenfold :nod:
Kindly stay tuned to this thread.
Vic
DO NOT take away from your work to do this.
I have said, March 1st will be fine. Hey, March 15 would be fine.
As long as I KNOW it's coming.
Quote from: TwoCatSam on February 18, 2013, 12:29:51 AM
DO NOT take away from your work to do this.
I have said, March 1st will be fine. Hey, March 15 would be fine.
As long as I KNOW it's coming.
Thanks Sam, but truth be told this last gig has drained me so much. Data entry/inventory is truly the "manual labor" level of the IT jobs.
I could really use some days of staying at home. Working from home is better and -must I say- quite stress-free.
It'd do good to me :)
Hey! You'll know the exact progress by following the thread.
Thanks again.
Hi Sam I'm home.
The next goal for is to enable the clicker... click.
I was studying how to solve the issue about the overlapping windows negating the click events, but... since we're in a rush we do it the old-fashioned way by faking mouse clicks instead of injection :nod:
Hi TwoCatSam
Good to see you are still busy with the GUT.( are you still in the plus ? )
Winkel is not any more around these forms ,I hope he is still well.
Regards
Max
(Look like an excellent tracker)
No, Max, I'm not in the plus on anything!
That statement will be fodder for the mill!
I'm onto other things.
Sam