Obtaining input from Joystick with C# and DirectX using Tutorial - c#

I'm using Visual Studio 2019 my question is closely aligned with the use of this Tutorial. I've done all the steps such as:
Creation of a Window Form in C#
Adding existing file Joystick.cs
Adding Reference item
Added Application Configuration File and pasted the code provided
Pasted example code into Form1.cs
My question: What am I missing? I can't access the library for joystick Screenshot of Error
Here is the whole Form1.cs code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RunJoyStickOnLocalMachine{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void joystickTimer_Tick_1(object sender, EventArgs e)
{
try
{
joystick.UpdateStatus();
joystickButtons = joystick.buttons;
if (joystick.Xaxis == 0)
output.Text += "Left\n";
if (joystick.Xaxis == 65535)
output.Text += "Right\n";
if (joystick.Yaxis == 0)
output.Text += "Up\n";
if (joystick.Yaxis == 65535)
output.Text += "Down\n";
for (int i = 0; i < joystickButtons.Length; i++)
{
if (joystickButtons[i] == true)
output.Text += "Button " + i + " Pressed\n";
}
}
catch
{
joystickTimer.Enabled = false;
connectToJoystick(joystick);
}
}
}
}
If there is anything else that I need to provide please notify me.
Thank You!
Edit: I've solved this problem by comparing both the tutorial file and the step by step tutorial file that the blog has.

You can download the project from the article you mentioned to check the code.
Based on my test, you can use the following code in the form1.cs code after you add theJoystick.cs to your project.
public partial class Form1 : Form
{
private Joystick joystick; // define the type Joystick
private bool[] joystickButtons; // here define the bool array
public Form1()
{
InitializeComponent();
joystick = new Joystick(this.Handle);
connectToJoystick(joystick);
}
private void joystickTimer_Tick(object sender, EventArgs e)
{
try
{
joystick.UpdateStatus();
joystickButtons = joystick.buttons;
if (joystick.Xaxis == 0)
output.Text += "Left\n"; // output is the name of richtextbox
if (joystick.Xaxis == 65535)
output.Text += "Right\n";
if (joystick.Yaxis == 0)
output.Text += "Up\n";
if (joystick.Yaxis == 65535)
output.Text += "Down\n";
for (int i = 0; i < joystickButtons.Length; i++)
{
if (joystickButtons[i] == true)
output.Text += "Button " + i + " Pressed\n";
}
}
catch
{
joystickTimer.Enabled = false;
connectToJoystick(joystick);
}
}
private void enableTimer()
{
if (this.InvokeRequired)
{
BeginInvoke(new ThreadStart(delegate ()
{
joystickTimer.Enabled = true;
}));
}
else
joystickTimer.Enabled = true;
}
private void connectToJoystick(Joystick joystick)
{
while (true)
{
string sticks = joystick.FindJoysticks();
if (sticks != null)
{
if (joystick.AcquireJoystick(sticks))
{
enableTimer();
break;
}
}
}
}
}

Related

C# removing an object Completely(no collision)

I am making a brick break game in c# windows form in which I need to remove a picture box when the ball(picture box) collide with it........
I have tried hide, dispose remove control and even making it equal to null but all of them just hide it and doesn't make it vanished completely means that there is still collision.....
here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication20
{
public partial class Form1 : Form
{
public int spx =10;
public int spy = 10;
public Form1()
{
InitializeComponent();
timer1.Enabled = true;
Cursor.Hide();
this.FormBorderStyle = FormBorderStyle.None;
this.TopMost = true;
this.Bounds = Screen.PrimaryScreen.Bounds;
paddle.Top = background.Bottom - (background.Bottom / 10);
if(paddle.Left > background.Left)
{
paddle.Left += 0;
}
}
private void Form1_ControlRemoved(object sender, ControlEventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
ball.Left += spx;
ball.Top += spy;
paddle.Left = Cursor.Position.X - (paddle.Left / Width);
if(ball.Left <= background.Left)
{
spx = -spx;
}
if (ball.Right >= background.Right)
{
spx = -spx;
}
if (ball.Top <= background.Top)
{
spy = -spy;
}
if (ball.Bottom >= background.Bottom)
{
spy = -spy;
}
if (paddle.Top <= ball.Bottom && paddle.Top >= ball.Top && ball.Left >= paddle.Left && ball.Right <= paddle.Right)
{
spy = -spy;
}
if (pictureBox.Top <= ball.Bottom && pictureBox.Bottom >= ball.Top && ball.Left <= pictureBox.Right && ball.Right >= pictureBox.Left)
{
spy = -spy;
background.Controls.Remove(pictureBox);
pictureBox = null;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
}
}
}
Your code that checks for collisions is hard-coded to look at pictureBox. Making it invisible doesn't change that.
If you want to use the Visible property of pictureBox to hide it, then you should change those if conditions to ignore it if it isn't visible:
if (pictureBox.Visible && (pictureBox.Top <= ball.Bottom && pictureBox.Bottom >= ball.Top && ball.Left <= pictureBox.Right && ball.Right >= pictureBox.Left))
{
spy = -spy;
pictureBox.Visible = false;
}

How can I delete all Panels from my calendar?

I'm programming an calendar with C# right now.
If i call my calendar, it creates as much panels as the current month has days. But if I want to increase the current month by one, the panels from the current month are stilt there.
So i have to delete all my panels as soon as I change the month.
But how can i do it in this case ?
Thanks for the help.
Code eplain:
First I call the createPanel method, to create panels for the current month.
Next if I click the MonthAdd method, I want to delete all my created panels.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Globalization;
namespace Einteilungs_Plan
{
public partial class Kalender : Form
{
public DateTime TodayDate { get; set; }
int counting = 0;
public Kalender()
{
InitializeComponent();
//Kalenderwochen initialisieren
monat(counting);
createPanel(true);
}
public string monat(int adding)
{
string monat = DateTime.Now.AddMonths(adding).ToString("MMMM");
tbMonat.Text = monat;
return monat;
}
private void btnAddMonth_Click(object sender, EventArgs e)
{
counting++;
if(counting < 12)
{
monat(counting);
switch (counting)
{
case 0:
int number = 10;
break;
case 1:
break;
default:
break;
}
}
else
{
counting--;
}
}
private void btnRemoveMonth_Click(object sender, EventArgs e)
{
counting--;
if (counting > -1)
{
monat(counting);
}
else
{
counting++;
}
}
public void createPanel(bool remove)
{
var numDays = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);
int locationX = 12;
int locationY = 74;
for (int i = 0; i <= numDays; i++)
{
//Create Panel
Panel test = new Panel();
//Fill Panel
test.Name = "panel" + i;
test.Width = 200;
test.Height = 100;
test.BackColor = Color.White;
test.Location = new System.Drawing.Point(locationX, locationY);
this.Controls.Add(test);
test.Show();
if(i == 6 || i == 13 || i == 20 || i == 28)
{
locationY += 106;
locationX = -194;
}
locationX += 206;
}
}
public void Kalender_Shown(object sender, EventArgs e)
{
}
private void Kalender_Load(object sender, EventArgs e)
{
}
private void btnNeuerEintrag_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
private void btnHinzufügen_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
}
}
...
for (int i = 0; i <= numDays; i++)
{
//Create Panel
test[i] = new Panel();
}
...
and then
this.Control.Remove(test[i]);
I'm not sure if I undestood you well but first simple solutiona that comes into my mind is that while creating panels you can keep them in some List for example and before generating new month you can call
foreach (var p in panels)
this.Controls.Remove(p);

Read Serial Port on C# allocating on an array no forgetting "00"

I'm trying to do a program that reads a serie of data from a serial port (COM3). The problem is that my code is for example (in decimal):
170 85 01 128 01 129 46 00 00 00 00 00 05 46
The way I'm reading the bytes "00" aren't been allocated on the array or variable:
I try a lot of ways like:
await port.BaseStream.ReadAsync(buffer, 0, 1);
And like shows on microsoft web site:
using System;
using System.IO.Ports;
class PortDataReceived
{
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
}
But all this methods doesn't work.
Does any one knows any way from get this data and allocate in an array?
How about something to investigate what's happening? If you start a new Winforms project with a single form, a button (buttonStart), and six text boxes, and then put this code behind it
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
int RxRead;
int n;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Open();
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (n = 0; n < 23; n++)
{
if (serialPort1.BytesToRead > 0)
{
RxRead = serialPort1.ReadByte();
if (n == 0)
{
textBox1.AppendText(RxRead.ToString());
}
if (n == 1)
{
textBox2.AppendText(RxRead.ToString());
}
if (n == 2)
{
textBox3.AppendText(RxRead.ToString());
}
if (n == 3)
{
textBox4.AppendText(RxRead.ToString());
}
if (n == 4)
{
textBox5.AppendText(RxRead.ToString());
}
if (n == 5)
{
textBox6.AppendText(RxRead.ToString());
}
if (n == 6)
{
serialPort1.Close();
}
}
}
}
}
}
Then I would hope that, when you press the start button, you will get the first six bytes displayed in the text boxes. This would let you see whether the 00 bytes are actually being read at all, or whether they are being discarded for some reason? I haven't got a serial port hooked up on my machine, so my apologies if there are any errors in the code.
Cheers,
Nick
If it's any help, here is a program that I wrote a long while back to pick up data coming in over a serial port from two sensors. It's very clunky programming, but as I recall it did (mostly!) work, so there may be something you can use.
Cheers,
Nick
[][1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace serial_port_with_events_attempt_4
{
public partial class Form1 : Form
{
string RxString;
int RxRead;
int i;
int j;
int RxDec1;
int RxDec2;
int RxDec3;
float RxFloat;
float RxFloat2;
string locnString = "Unknown";
DateTime deleteDate;
string deleteDateString;
string testString;
public Form1()
{
InitializeComponent();
deleteDate = DateTime.Today;
deleteDate = deleteDate.AddDays(-7);
deleteDateString = deleteDate.ToString();
textBox1.AppendText(deleteDateString);
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM8";
serialPort1.BaudRate = 9600;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
//textBox1.ReadOnly = false;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
//textBox1.ReadOnly = true;
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
for (j = 0; j<23 ; j++)
{
if (serialPort1.BytesToRead > 0)
{
RxRead = serialPort1.ReadByte();
this.Invoke(new EventHandler(DisplayText));
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
}
private void DisplayText(object sender, EventArgs e)
{
if (RxRead == 126)
{
//textBox1.AppendText(Environment.NewLine);
i = 0;
}
if (i< 23)
{
if (i == 13)
{
testString = RxRead.ToString();
textBox1.AppendText(testString);
if (RxRead == 82) // 82 in this position means that the temp sensor is the low range one (R1L)
{
//textBox1.AppendText("Temperature in Nick's office = ");
locnString = ("Nicks office");
}
if (RxRead == 195) // 195 in this position means that the temp sensor is the high range one (R1H)
{
//textBox1.AppendText("Temperature in Nick's office = ");
locnString = ("Sitting Room");
}
}
if (i == 17)
{
RxDec1 = RxRead - 48; // Read the tens unit
}
if (i == 18)
{
RxDec2 = RxRead - 48; // Read the units
}
if (i == 20)
{
RxDec3 = RxRead - 49; // read the decimal
}
if (i == 22)
{
RxFloat = ((RxDec1 * 10) + RxDec2);
RxFloat2 = RxDec3;
RxFloat2 = RxFloat2 / 10;
RxFloat = RxFloat + RxFloat2;
// Frig about to get the reads in the right format and added together
RxString = RxFloat.ToString();
if (RxFloat < 30 && RxFloat >10)
{
//textBox1.AppendText(RxString);
if (locnString == "Nicks office")
{
button1.Text = RxString;
}
if (locnString == "Sitting Room")
{
button2.Text = RxString;
}
// Put the value in the main text box if it is not corrupt, (checking if the range is reasonable
temperature1DataSetTableAdapters.Temp1TableAdapter temp1tableadapter = new temperature1DataSetTableAdapters.Temp1TableAdapter();
temp1tableadapter.Insert(DateTime.Now, RxFloat, locnString);
// Add a new line into the temperature database
}
deleteDate = DateTime.Today;
deleteDate = deleteDate.AddDays(-7);
deleteDateString = deleteDate.ToString();
textBox1.Clear();
textBox1.AppendText(deleteDateString);
temperature1DataSetTableAdapters.TempTableAdapter temp2tableadapter = new temperature1DataSetTableAdapters.TempTableAdapter();
temp2tableadapter.DeleteTempQuery(deleteDate);
//textBox1.AppendText("BreakpointA");
textBox1.AppendText(testString);
// Delete any old data.
// TODO Doesn't seem to be working. Don't understand why not. The code gets to here as Breakpoint A gets triggered
this.tempTableAdapter.Fill(this.temperature1DataSet.Temp);
chart1.DataBind();
// These two lines refresh the chart. Took me a long time to figure this out. Basically, you have to
// rerun the query and then run the DataBind method to update the chart control.
// Good article on table adapters http://msdn.microsoft.com/en-us/library/bz9tthwx%28VS.80%29.aspx
//** test code for second chart.
this.tempSensor2AdapterTableAdapter.tempSensor2Fill(this.temperature1DataSet.tempSensor2Adapter);
chart2.DataBind();
}
}
i=i+1;
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'temperature1DataSet.tempSensor2Adapter' table. You can move, or remove it, as needed.
this.tempSensor2AdapterTableAdapter.tempSensor2Fill(this.temperature1DataSet.tempSensor2Adapter);
// TODO: This line of code loads data into the 'temperature1DataSet.Temp' table. You can move, or remove it, as needed.
this.tempTableAdapter.Fill(this.temperature1DataSet.Temp);
chart2.ChartAreas[0].AxisX.LabelStyle.Format = "{0:dd/MM H:mm}";
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "{0:dd/MM H:mm}";
}
}
}

Refreshing a chart control

This one is driving me a bit crazy. Any help gratefully received. It's a simple program to receive temperature data from an Arduino based temp sensor, and display it in a graph control on a form. The program works fine, and parses the temp data frame a treat. However..... the graph object doesn't refresh, and the whole point is to show the data over time. I thought that the chart1.DataBind command that I put in forced a refresh. I am using Visual Studio 2013 Express. Any thoughts as to what I am doing wrong very much appreciated.
// Start of program.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace serial_port_with_events_attempt_4
{
public partial class Form1 : Form
{
string RxString;
int RxRead;
int i;
int RxDec1;
int RxDec2;
int RxDec3;
float RxFloat;
float RxFloat2;
string locnString;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM8";
serialPort1.BaudRate = 9600;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
textBox1.ReadOnly = true;
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxRead = serialPort1.ReadByte();
this.Invoke(new EventHandler(DisplayText));
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
}
private void DisplayText(object sender, EventArgs e)
{
if (RxRead == 126)
{
textBox1.AppendText(Environment.NewLine);
i = 0;
}
if (i< 23)
{
if (i == 7)
{
if (RxRead == 51) // 51 in this position means that the temp sensor is the one in the wooden box
{
textBox1.AppendText("Temperature in Nick's office = ");
locnString = ("Nick's office");
}
}
if (i == 17)
{
RxDec1 = RxRead - 48; // Read the tens unit
}
if (i == 18)
{
RxDec2 = RxRead - 48; // Read the units
}
if (i == 20)
{
RxDec3 = RxRead - 49; // read the decimal
}
if (i == 22)
{
RxFloat = ((RxDec1 * 10) + RxDec2);
RxFloat2 = RxDec3;
RxFloat2 = RxFloat2 / 10;
RxFloat = RxFloat + RxFloat2;
RxString = RxFloat.ToString();
if (RxFloat < 30 && RxFloat >20)
{
// Put the value in the main text box if it is not corrupt, (checking if the range is reasonable
textBox1.AppendText(RxString); // Frig about to get the reads in the right format and added together
// Add a new line into the temperature database
temperature1DataSetTableAdapters.Temp1TableAdapter temp1tableadapter = new temperature1DataSetTableAdapters.Temp1TableAdapter();
temp1tableadapter.Insert(DateTime.Now, RxFloat, locnString);
}
// Delete any old data.
temperature1DataSetTableAdapters.TempTableAdapter temp2tableadapter = new temperature1DataSetTableAdapters.TempTableAdapter();
temp2tableadapter.DeleteTempQuery();
// The above two lines work, but I need to amend to select on date TODO
chart1.DataBind();
}
}
i=i+1;
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'temperature1DataSet.Temp' table. You can move, or remove it, as needed.
this.tempTableAdapter.Fill(this.temperature1DataSet.Temp);
}
}
}
Cheers,
Nick James

How can I implement effective Undo/Redo into my WinForms application?

I have a WinForm text editor.
I would like to be able to allow the user to undo and redo changes in the Rich Text Box, like they can in Microsoft Word.
I have spent the past week or so researching how to do this, and most results seem to be regarding graphics applications.
The standard richTextBox1.Undo(); gives disappointing results, as it undoes everything that the user has written.
Does anybody have any idea how I could implement effective undo/redo? Preferably one which undoes/redoes the action word-by-word as opposed to character-by-character.
This is a very basic idea, and I'm sure that many improvements could be made.
I would create a String Array and incrementally store the value of the RichTextBox (In the TextChanged event, under your own conditions) in the array. As you store the value, increment the value of a counter, say stackcount. When the user undoes, decrement the stackcount and set the RichTextBox.Text = array(stackcount). If they redo, then increment the value of the counter and set the value again. If they undo and then change the text, then clear all values onwards.
I am sure that many other people may have better suggestions/changes for this, so please post in comments and I will update, or edit it yourself!
Example in C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RedoUndoApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string[] RTBRedoUndo;
public int StackCount = 0;
public int OldLength = 0;
public int ChangeToSave = 5;
public bool IsRedoUndo = false;
private void Form1_Load(object sender, EventArgs e)
{
RTBRedoUndo = new string[10000];
RTBRedoUndo[0] = "";
}
private void undo_Click(object sender, EventArgs e)
{
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount - 1] != null)
{
StackCount = StackCount - 1;
richTextBox1.Text = RTBRedoUndo[StackCount];
}
}
private void redo_Click(object sender, EventArgs e)
{
IsRedoUndo = true;
if (StackCount > 0 && RTBRedoUndo[StackCount + 1] != null)
{
StackCount = StackCount + 1;
richTextBox1.Text = RTBRedoUndo[StackCount];
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (IsRedoUndo == false && richTextBox1.Text.Substring(richTextBox1.Text.Length - 1, 1) == " ")//(Math.Abs(richTextBox1.Text.Length - OldLength) >= ChangeToSave && IsRedoUndo == false)
{
StackCount = StackCount + 1;
RTBRedoUndo[StackCount] = richTextBox1.Text;
OldLength = richTextBox1.Text.Length;
}
}
private void undo_MouseUp(object sender, MouseEventArgs e)
{
IsRedoUndo = false;
}
private void redo_MouseUp(object sender, MouseEventArgs e)
{
IsRedoUndo = false;
}
}
}
One way to do this is use the TextChanged event to periodically store the contents of richtextbox.text in an array or list, as a stack. When you undo, "pop the stack" and copy the most recent version on the stack into richtextbox.text.
TextChange can determine whether a change should be saved onto the stack, whether a new word, line, or character.

Categories

Resources