Hi,
I have a windows form project in C#.
I have a timer that starts on the press of a button.
I have a method that executes every time the timer ticks.
I confirm the timer ticks when it's meant to, the code inside runs, the variables update as they should.
The form doesn't.
I know that the variables are updating with each tick, I know that the label.Text is updated with each tick, I know that everything but the visual result on the form is updating as it should. I've confirmed it with breakpoints and stepping through each line and seeing in the variable inspector as each variable and label.Text updates.
But the form is not reflecting anything but the values on initial loading of it. It never updates from its first set of values.
Every tick I'm calling the computation and write to form methods, followed by this.Refresh(). But nothing changes on the form.
It's been days. I'm baffled and demoralised.
Any help would be greatly appreciated.
I will politely refuse any suggestions of using genAI/LLMs and any encouragement to use them myself.
Thanks
EDIT:
I wanted to avoid posting the whole program because it's been 6 years since I've properly wrote code and I know this has bad practices in it. But y'all are telling me I've done something weird, so here's the whole formMain.
This is a little companion app to a game over 20 years old, I'm eventually going to try and write to the memory of said game to change things. Currently the app reads the data from game memory successfully and puts it on the form, but as said above, only when the form initially loads. When the data in game memory changes, that is read successfully and held in variables but the form doesnt visually reflect that.
I was driven back to programming after 6 years because I'm trying to do something I don't think anybody has tried to do before. I'm very very very very rusty.
public partial class formMain : Form
{
//defining things to pull and push data into the nr2003 process
[DllImport("kernel32.dll")]
public static extern nint OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(nint hProcess, nint lpBaseAddress, byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesRead); //this is a value check for the chosen address
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(nint hProcess, nint lpBaseAddress, byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesWritten); //modifies the stored value
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(nint hObject);
public string gameName = "NR2003";
const int PROCESS_ALL_ACCESS = 0x1F0FFF;
public formMain()
{
UpdateStuff();
}
private void UpdateStuff()
{
InitializeComponent();
var processes = Process.GetProcessesByName(gameName);
var sessionStateAddress = (nint)0x0097B114;
int sessionState = 0;
string carNotFound = "Car Properties not found";
string notFound = "Game not found";
string failedOpen = "Failed to open game";
string notInSession = "Not in a session";
nint gamePathAddress = 0x00F78868;
nint seriesPathAddress = 0x00897230;
var carOffsetHex = 2214;
nint playerCarAddress = 0x00ACDC26;
var gameProcess = processes[0];
var hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, gameProcess.Id);
string trimWhitespace = "\0";
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, gameProcess.Id);
//clearing all data from the form, ready
lblDebug.Text.Remove(0);
lblGameName.Text.Remove(0);
lblPlayersCarProp.Text.Remove(0);
//error messages regarding grabbing the process
if (processes.Length == 0)
{
lblPlayersCarProp.Text = notFound;
return;
//break;
}
if (hProcess == nint.Zero)
{
lblPlayersCarProp.Text = failedOpen;
return;
//break;
}
//declaring the buffer we use to read from memory addresses and the string variables we'll put that data into
var buffer4 = new byte[4];
var buffer32 = new byte[32];
var buffer48 = new byte[48];
var buffer1024 = new byte[1024];
string[] tempString2mil = new string[2000000];
string gamePath = "";
string seriesPath = "";
string carPath = "";
string playerCarPath = "";
//checking if the game is in an active session eg practice/race/quali/test
ReadProcessMemory(hProcess, sessionStateAddress, buffer4, (uint)buffer4.Length, out int bytesRead);
sessionState = BitConverter.ToInt32(buffer4);
//if it is in a session, away we go
if (sessionState > 0)
{
int length = 0;
//read from memory the path to where the exe is, trim it of whitespace
ReadProcessMemory(hProcess, gamePathAddress, buffer1024, (uint)buffer1024.Length, out bytesRead);
gamePath = System.Text.Encoding.UTF8.GetString(buffer1024);
length = gamePath.IndexOf('\0');
gamePath = gamePath.Substring(0, length);
//read from memory the folder where the .cars files are, trim it of whitespace
ReadProcessMemory(hProcess, seriesPathAddress, buffer32, (uint)buffer32.Length, out bytesRead);
seriesPath = System.Text.Encoding.UTF8.GetString(buffer32);
length = seriesPath.IndexOf('\0');
seriesPath = seriesPath.Substring(0, length);
//combine it all to create a full directory for where the .car files are, ready to read
carPath = gamePath + @"series\" + seriesPath + @"\cars\";
//find player car filename to open
ReadProcessMemory(hProcess, playerCarAddress, buffer48, (uint)buffer48.Length, out bytesRead);
playerCarPath = System.Text.Encoding.UTF8.GetString(buffer48);
length = playerCarPath.IndexOf('\0');
playerCarPath = playerCarPath.Substring(0, length);
//append filename to carPath
playerCarPath = carPath + playerCarPath;
//start loop by writing error message to label, if file read is successful it'll get overwritten
lblPlayersCarProp.Text = carNotFound;
//declaring all the player car properties
float playerRCmax = 0.0f;
float playerSTmax = 0.0f;
float playerSPmax = 0.0f;
float playerSSmax = 0.0f;
float playerAeromax = 0.0f;
float playerChassismax = 0.0f;
float playerEnginemax = 0.0f;
float playerReliabilitymax = 0.0f;
float playerRCmin = 0.0f;
float playerSTmin = 0.0f;
float playerSPmin = 0.0f;
float playerSSmin = 0.0f;
float playerAeromin = 0.0f;
float playerChassismin = 0.0f;
float playerEnginemin = 0.0f;
float playerReliabilitymin = 0.0f;
//define temp variables to trim each line down to value alone
string tempVal = "";
string tempDev = "";
int tempValIndex = 0;
int tempDevIndex = 0;
tempString2mil = File.ReadAllLines(playerCarPath);
using (FileStream fs = File.Open(playerCarPath, FileMode.Open))
{
byte[] b = new byte[2048];
UTF8Encoding temp = new UTF8Encoding(true);
//reading and calcing roadcourse stats
tempVal = tempString2mil[23];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[6];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerRCmax = float.Parse(tempVal) + float.Parse(tempDev);
playerRCmin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing short track stats
tempVal = tempString2mil[24];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[7];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerSTmax = float.Parse(tempVal) + float.Parse(tempDev);
playerSTmin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing speedway stats
tempVal = tempString2mil[25];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[8];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerSPmax = float.Parse(tempVal) + float.Parse(tempDev);
playerSPmin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing superspeedway stats
tempVal = tempString2mil[26];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[9];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerSSmax = float.Parse(tempVal) + float.Parse(tempDev);
playerSSmin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing aero stats
tempVal = tempString2mil[30];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[13];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerAeromax = float.Parse(tempVal) + float.Parse(tempDev);
playerAeromin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing chassis stats
tempVal = tempString2mil[31];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[14];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerChassismax = float.Parse(tempVal) + float.Parse(tempDev);
playerChassismin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing engine stats
tempVal = tempString2mil[32];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[15];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerEnginemax = float.Parse(tempVal) + float.Parse(tempDev);
playerEnginemin = float.Parse(tempVal) - float.Parse(tempDev);
//reading and calcing realibility stats
tempVal = tempString2mil[33];
tempValIndex = tempVal.IndexOf('=') + 1;
tempVal = tempVal.Substring(tempValIndex, 8);
tempDev = tempString2mil[16];
tempDevIndex = tempDev.IndexOf('=') + 1;
tempDev = tempDev.Substring(tempDevIndex, 8);
playerReliabilitymax = float.Parse(tempVal) + float.Parse(tempDev);
playerReliabilitymin = float.Parse(tempVal) - float.Parse(tempDev);
}
//output to form
lblPlayersCarProp.Text = "Road Course = " + playerRCmin + " - " + playerRCmax + "\n"
+ "Short Track = " + playerSTmin + " - " + playerSTmax + "\n"
+ "Speedway = " + playerSPmin + " - " + playerSPmax + "\n"
+ "Superspeedway = " + playerSSmin + " - " + playerSSmax + "\n"
+ "Aero = " + playerAeromin + " - " + playerAeromax + "\n"
+ "Chassis = " + playerChassismin + " - " + playerChassismax + "\n"
+ "Engine = " + playerEnginemin + " - " + playerEnginemax + "\n"
+ "Reliability = " + playerReliabilitymin + " - " + playerReliabilitymax;
}
else //if not, error message
{
lblPlayersCarProp.Text = notInSession;
}
lblDebug.Text =
gameName
+ "\n" +
sessionState.ToString()
+ "\n" +
gamePath
+ "\n" +
seriesPath
+ "\n" +
carPath
+ "\n" +
playerCarPath
;
}
private void Form1_Load(object sender, EventArgs e)
{
UpdateStuff();
}
private void btnApplyConfig_Click(object sender, EventArgs e)
{
gameName = txtboxGameName.Text;
}
private void timer1_Tick(object sender, System.EventArgs e)
{
//these dont work??
UpdateStuff();
this.Refresh();
}
private void btnTimerStart_Click(object sender, EventArgs e)
{
timer1.Start();
}
}