C# Open Form and run fuction at the same time - c#

I am trying to code a memory cheat for a game but I want to create a menu so I decided to make it. And now I want that my program is opening the form and doing the cheat at the same time. Because now the cheat is doing it or otherwise the cheat is not working and the form is opening.
I am pretty new in C# so sorry if I am noob ... :P
Thanks,
IzzyMichiel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ac_client_cheat
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Main();
}
public static int Pbase = 0x00509B74;
public static int Health = 0xf8;
public static int mgammo = 0x150;
public static int fly = 0x44;
public void Main()
{
VAMemory vam = new VAMemory("ac_client");
int localplayer = vam.ReadInt32((IntPtr)Pbase);
{
while (true)
{
int address = localplayer + fly;
float aimlock = vam.ReadFloat((IntPtr)address);
vam.WriteFloat((IntPtr)address, -5);
address = localplayer + Health;
vam.WriteInt32((IntPtr)address, 1337);
address = localplayer + mgammo;
vam.WriteInt32((IntPtr)address, +1337);
}
}
}
}
}

You can show the form and run your cheat loop simultaneously as following:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static int Pbase = 0x00509B74;
public static int Health = 0xf8;
public static int mgammo = 0x150;
public static int fly = 0x44;
/// <summary>The main entry point for the application.</summary>
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var f = new Form1();
f.Show();
VAMemory vam = new VAMemory("ac_client");
int localplayer = vam.ReadInt32((IntPtr)Pbase);
while (f.Visible) //loop while form is not closed
{
int address = localplayer + fly;
float aimlock = vam.ReadFloat((IntPtr)address);
vam.WriteFloat((IntPtr)address, -5);
address = localplayer + Health;
vam.WriteInt32((IntPtr)address, 1337);
address = localplayer + mgammo;
vam.WriteInt32((IntPtr)address, +1337);
Application.DoEvents(); //Yield control to the message loop
}
}
private void Form1_Load(object sender, EventArgs e)
{
//...
}
}

Windows forms applications start out as single-threaded, so you can't do two things at once.
The typical way to handle this would be to start up a worker thread, e.g. using Task.Run.
However, since your application is so simple, we can use
Application.DoEvents instead.
When you call DoEvents, your thread will check the message loop for the form and handle any pending events, such as menu clicks or whathaveyou. If there are no events pending, it'll let your main loop resume. This scheme lets you get away with running the form and the loop on the same thread.
while (true)
{
int address = localplayer + fly;
float aimlock = vam.ReadFloat((IntPtr)address);
vam.WriteFloat((IntPtr)address, -5);
address = localplayer + Health;
vam.WriteInt32((IntPtr)address, 1337);
address = localplayer + mgammo;
vam.WriteInt32((IntPtr)address, +1337);
Application.DoEvents(); //Yield control to the message loop
}
Also, make sure you are starting your message loop with Application.Run. See this answer for more information. Here's one way to do it:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}

The problem with your code is that the constructor never exits, so the form can never be displayed.
Remove the call to Main from your constructor and put it in a Timer event handler instead. Since the timer will handle repetition for you, you can remove the while loop too.

Related

Button classes that I've written with C# won't show up in Windows Form when running

Just started learning Visual Studio and I'm trying to make a soundboard in Windows Forms.
ButtonMaker(); is the function I use to make a button for each soundfile in my directory so I don't have to make 70 different buttons for every sound, but when I run the program nothing shows up in the forms window. Anybody know why? I've tried calling the function in Main() and in the initial Form1 class but nothing happens in either. Forms class file here:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace MySoundBoard
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
///Tried running it here
}
private void Form1_Load(object sender, EventArgs e)
{
///Tried running it here
}
private void ButtonMaker()
{
string[] files = Soundfiles.GetFile();
foreach (var item in files)
{
string btnName = item.ToUpper();
Button btNname = new Button();
btNname.Text = item;
int x = 40;
int y = 40;
btNname.Location = new Point(x, y);
x = x + 50;
if (x>900)
{
x = 40;
y = y + 30;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
Here is the SoundFiles class:
using System.IO;
using System;
using System.Text;
using System.Diagnostics;
using WMPLib;
namespace MySoundBoard
{
class Soundfiles {
WMPLib.WindowsMediaPlayer Player;
static public string[] GetFile() {
string txtPath = #"C:\Documents\path\to\sound effects";
string[] files =
Directory.GetFiles(txtPath, "*ProfileHandler.cs", SearchOption.TopDirectoryOnly);
return files;
}
public void PlayFile(String url)
{
Player = new WMPLib.WindowsMediaPlayer();
Player.URL = url;
Player.controls.play();
}
}
}
And the main project file(not that worked with yet):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MySoundBoard
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
///Tried running it here
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
As said, I'm very new to this language and any help would be appriciated!
You create the buttons but never add them to the form. Just add
this.Controls.Add(btNname);
The next thing is, that your buttons will not do something. You'll need to add an event handler as well.
btNname.Click += ...;
In order to know which button plays which sound, you need to find a way to have that association. A hacky approach is
btNname.Tag = item;
and then evaluate Tag later

WPF handle multiple key down events in several threads

I'm trying to make a game with two players in WPF, that are controlled with WASD/ arrow keys and can move on the game field. When a control key of first player is pressed while second player is already moving (key is down), the second player stops moving. But I'd like them to move simultaneously.
MainWindow.xaml.cs:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
//Player1
if(Keyboard.IsKeyDown(Key.W)) GameVM.MovePlayer("1W");
if (Keyboard.IsKeyDown(Key.S)) GameVM.MovePlayer("1S");
if (Keyboard.IsKeyDown(Key.A)) GameVM.MovePlayer("1A");
if (Keyboard.IsKeyDown(Key.D)) GameVM.MovePlayer("1D");
//Player2
if (Keyboard.IsKeyDown(Key.Up)) GameVM.MovePlayer("2W");
if (Keyboard.IsKeyDown(Key.Down)) GameVM.MovePlayer("2S");
if (Keyboard.IsKeyDown(Key.Left)) GameVM.MovePlayer("2A");
if (Keyboard.IsKeyDown(Key.Right)) GameVM.MovePlayer("2D");
}
I would do it with an external class from c++ (I guess it is c++) and a main class where all the threads get started from.
For 1 Player you would need 1 class or even better 1 struct which contains the states for the keys aswell as the specific buttons you want for it (changeable because of variables, maybe consider settings.txt/json to safe the new keys etc....)
Key Settings and State Class:
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media; //Maybe you dont need some of them but you will see it in your IDE if you use them or not
namespace GAME.Settings
{
public class Settings //standard Values and states for the keys
{
internal struct SettingsPlayer1
{
public static Keys UPkey = Keys.A; //List https://learn.microsoft.com/en-en/dotnet/api/system.windows.forms.keys?view=netcore-3.1
public static Keys LEFTkey = Keys.A;
public static Keys DOWNkey = Keys.S;
public static Keys RIGHTkey = Keys.D;
public static bool UP = false; //key states
public static bool LEFT = false;
public static bool DOWN = false;
public static bool RIGHT = false;
}
internal struct SettingsPlayer1
{
public static Keys UPkey = Keys.UP;
public static Keys LEFTkey = Keys.LEFT;
public static Keys DOWNkey = Keys.DOWN;
public static Keys RIGHTkey = Keys.RIGHT;
public static bool UP = false; //key states
public static bool LEFT = false;
public static bool DOWN = false;
public static bool RIGHT = false;
}
}
}
Get Key State class
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using GAME.Settings;
namespace GAME.Keys
{
internal class Imports //imports from .dll
{
[DllImport("user32.dll")]
public static extern short GetAsyncKeyState(Keys vKey); //needed to get the async Key state
}
public class GetKeysPressedP1
{
static bool GetAsyncKeyState(Keys key) => Imports.GetAsyncKeyState(key) != 0;
public static void Run() //this is the method which the thread will run
{
while (true)
{
Thread.Sleep(5); //you can choose your sleep time for input delay
if (GetAsyncKeyState(Settings.SettingsPlayer1.UPkey)) Settings.SettingsPlayer1.UP = true;
else Settings.SettingsPlayer1.UP = false;
if (GetAsyncKeyState(Settings.SettingsPlayer1.LEFTkey)) Settings.SettingsPlayer1.LEFT = true;
else Settings.SettingsPlayer1.LEFT = false;
if (GetAsyncKeyState(Settings.SettingsPlayer1.DOWNkey)) Settings.SettingsPlayer1.DOWN = true; //you could also do something in here like move to x direction etc.
else Settings.SettingsPlayer1.DOWN = false;
if (GetAsyncKeyState(Settings.SettingsPlayer1.RIGHTkey)) Settings.SettingsPlayer1.RIGHT = true;
else Settings.SettingsPlayer1.RIGHT = false;
}
}
}
}
Main Class
using System;
using System.Threading;
using GAME.Keys;
using GAME.Settings;
namespace GAME.Main
{
public class main //can be any class in which the thread will be created and started
{
public main()
{
public static Thread GetKeysPressedThreadP1 = new Thread(GetKeysPressedP1.Run); //new thread
GetKeysPressedThreadP1.Start(); //starting the new thread in the background
while(true)
{
//Do Something with it if(GAME.Settings.SettingsPlayer1.UP){ P1.position.x++;}
}
}
}
}
As I've done this on notepad right now, I can not check if everything is right, I will check it in 20mins but maybe this will already help you
If you have questions regarding this code, just ask.
If this is all wrong or makes no sense in this specific case, feel free to edit or mark it so I can either delete or edit it because I'm not an expert in c# myself:)

use multithread to write into text files using C#

Hope you can help me with this one.i am beginner in multithreading programming with C#.
I am trying to build a program to write all numbers from range 1 to 2000 in two text files using two threads.
Every thread should write number from 1 to 2000 that not found at any of the two files "there is no duplicated numbers in the files" and every thread should't write the number that have been wrote by the another thread.
At the end if we merged the numbers of the two files we should have the numbers from 1 to 2000
Here is the source code i am trying but there is a problem in the writing for loop in the below image
i can't handle the process of writing by the two synchronized threads and i had exception:
Object synchronization method was called from an unsynchronized block of code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace Multithreading
{
class Program
{
static TextWriter file2 = new StreamWriter("file2 location");
static TextWriter file1 = new StreamWriter("file1 location");
static void Main(string[] args)
{
try
{
int[] array = new int[2000];
Thread thread1 = new Thread(Program.writeinfile1);
Thread thread2 = new Thread(Program.writeinfile2);
for (int counter = 1; counter <= 2000; counter++)
{
thread1.Start(counter);
thread2.Start(++counter);
Monitor.Enter(thread1);
Monitor.Wait(thread1);
Monitor.PulseAll(thread2);
}
}
catch (FileNotFoundException)
{
Console.WriteLine("the file you are trying to open is not found");
}
}
public static void writeinfile1(object x)
{
int converttointx = (int)x;
file1.WriteLine(converttointx);
file1.Close();
}
public static void writeinfile2(object y)
{
int converttointy = (int)y;
file2.WriteLine(converttointy);
file2.Close();
}
}
}
Here's an example of multi-threaded calls talking to one another to ensure they don't duplicate work.
I've not done exactly what you've asked for, since this looks quite homeworky; but hopefully this will help you to figure out the solution to your issue...
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
new Program();
Console.WriteLine("done");
Console.ReadKey();
}
Program()
{
int noThreads = 5;
int target = 2000;
StartThread(noThreads, target);
}
//kicks off our threads / waits for all threads to complete before returning
void StartThread(int noThreads, int target)
{
int id = noThreads--;
if (id > 0)
{
Doer doer = new Doer(id, target);
Thread t = new Thread(doer.Do);
t.Start();
StartThread(noThreads,target);
t.Join();
}
}
}
class Doer
{
static int marker = 0;
static readonly object syncLocker = new object();
readonly int id;
readonly int target;
public Doer(int id, int target)
{
this.id = id;
this.target = target;
}
public void Do()
{
while (marker < this.target)
{
int i;
lock (syncLocker)
{
i = ++marker;
}
System.Console.WriteLine("{0:00}: {1:###0}", id, i);
//Thread.Sleep(RandomNo()); //uncomment this & code below if your threads are taking turns / behaving too predictably
}
}
/*
static readonly Random rnd = new Random();
static readonly object rndSyncLocker = new object();
public static int RandomNo()
{
lock (rndSyncLocker)
{
return rnd.Next(0, 1000);
}
}
*/
}
}
You are not using the Monitor class correctly. The call to Monitor.PulseAll(thread2); should be called within thread the thread which owns the lock, which in this case would be within the writeinfile1 and writeinfile2 method.
This is why you are getting the exception:
Object synchronization method was called from an unsynchronized block of code.
See the following StackOverflow question for the correct way to use Monitor.PulseAll(object):
Help needed in Monitor.PulseAll()

Changing a picture box visibility from C# code

So I tried to create a new form and reference it...the compiler didn't mind this but it clearly wasn't changing the visibility of my picturebox. this is how I was calling my method found in my form, FROM my c# script.
Form1 updateForm = new Form1();
updateForm.setLights();
It called the method, and seemed like it worked! Until I read a post about instancing forms, and how by creating a "new" instance of Form1, that anything referenced by my updateForm would not change what I would see on my Form1.
So what I need to do is to call the function in setLights() which is in my Form1, and get it to change the visibility of my image on that form, from my C# code. Please see below (i understand the issue of the instancing problem mentioned above, but I left it in so that hopefully it will give better insight into what I am "trying" to do :) ALSO, please keep in mind that setLightCall() is running in a separate thread. Thanks in advance!
This code is also in my main c# script, and is the main function that I use to call my threads
static void Main(string[] args)
{
Thread FormThread = new Thread(FormCall);
FormThread.Start();
Thread setLightThread = new Thread(setLightCall);
setLightThread.Start();
log4net.Config.XmlConfigurator.Configure();
StartModbusSerialRtuSlave();
}
This code is in my main C# script
public void setLightCall(Form1 parent)
{
Form1 updateForm = new Form1();
while(true)
{
updateForm.setLights();
}
}
The below code is in my form1
public void setLights()
{
Input1GreenLight.Visible = false;
}
Here is an example of what I think you are wanting to try. Note the use of Invoking and delegates to be able to access the PictureBox's Visible method. I had to add the System.Windows.Forms Namespace to the Console Application to be able to access the instance of the Form that was created in the FormThread Method, this is assuming that you only have 1 Form in your FormCollection.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
namespace ConsoleApplication59
{
class Program
{
static void Main(string[] args)
{
Thread FormThread = new Thread(FormCall);
FormThread.Start();
Thread.Sleep(2000); //Sleep to allow form to be created
Thread setLightThread = new Thread(setLightCall);
setLightThread.Start(Application.OpenForms[0]); //We can get by with this because just one form
Console.ReadLine();
}
public static void setLightCall(object parent)
{
Form1 updateForm = (Form1)parent;
while (true)
{
updateForm.Invoke(updateForm.setLights, new object[] { false });
}
}
public static void FormCall()
{
Application.Run(new Form1());
}
}
}
Form1
public partial class Form1 : Form
{
public delegate void Lights(bool state);
public Lights setLights;
public Form1()
{
InitializeComponent();
setLights = new Lights(setLightsDelegate);
}
public void setLightsDelegate(bool state)
{
Input1GreenLight.Visible = state;
}
}

How to create a Sleep method for my application

I want to create a method which makes my application wait X number of seconds, then continues on down a line of scripts. For example, this is the code that I have so far, after reading many similar help topics:
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
methods.WriteTextToScreen(label1, "Hello!");
methods.sleepFor(1);
methods.WriteTextToScreen(label1, "Welcome!");
methods.sleepFor(1);
methods.WriteTextToScreen(label1, "Allo!");
}
public class methods
{
public static int timeSlept;
public static void WriteTextToScreen(Label LabelName, string text)
{
LabelName.Text = text;
}
public static void sleepFor(int seconds)
{
timeSlept = 0;
System.Timers.Timer newTimer = new System.Timers.Timer();
newTimer.Interval = 1000;
newTimer.AutoReset = true;
newTimer.Elapsed += new System.Timers.ElapsedEventHandler(newTimer_Elapsed);
newTimer.Start();
while (timeSlept < seconds)
{
Application.DoEvents();
}
Application.DoEvents();
}
public static void newTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timeSlept = IncreaseTimerValues(ref timeSlept);
Application.DoEvents();
}
public static int IncreaseTimerValues(ref int x)
{
int returnThis = x + 1;
return returnThis;
}
}
}
}
What I want to do is have my program do the methods.WriteTextToScreen(label1, "Hello!")
then wait for 1 second, then continue on in the same fashion. The problem is that the Form I'm displaying the text on doesn't show up at all until it has written "Allo!" onto the screen, so the first time it appears it already says that. Am I doing something wrong, or is there just no way to do this?
The form doesn't show until it has been constructed i.e. all the code in Form1 is run. See here for info on form constructors: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.form.aspx
To fix your problem you could move the writeTextToScreen and sleep code into the forms on load method. See http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onload.aspx

Categories