I want to create a simple one time activation process for my windows form application. So, I basically have two forms, form1 is the activation window and form2 is the actual program. I've create a very basic activation program in form1 given below
string mac = textBox1.Text;
string str1 = mac.Substring(4,1);
string str2 = mac.Substring(5,1);
string str3 = mac.Substring(7,1);
string str4 = mac.Substring(2, 1);
string pattern = str1 + str2 + str2 + str3 + str4;
if (textBox2.Text == pattern)
{
MessageBox.Show("Program activated!!!");
Form2 n = new Form2();
n.Show();
this.Hide();
}
else { MessageBox.Show("Wrong key"); }
Now, the problem is every time I load my program it always loads form1 even when someone successfully entered the key(i.e. pattern) once before. How do I store that information so that if someone enters the correct key, every time after that whenever the program is loaded it will automatically show form2 (i.e. my actual program) and skip form1.
BTW, I'm aware that there are other more advanced and secure ways of doing this but I'm just currently interested in this very basic method.
Can anyone help?
Here's one very rudimentary way - write a file to a known location when they activate, then check for the existence of that file each time you load the form. If it's there, immediately show Form2. If not, give them the chance to activate.
Differing methods would be to save the activation status in the Registry or in a Database, or somewhere else, but the overall process is about the same
Sample code:
First, a method to get the path to the file we're going to create:
private string GetActivatedFilePath()
{
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var thisExeName = Path.GetFileNameWithoutExtension(
System.Reflection.Assembly.GetEntryAssembly().Location);
return Path.Combine(appDataPath, thisExeName, "Activated.txt");
}
Then a couple of methods to create the file (Activate()), check if the file exists (IsActivated), and delete the file (Deactivate()):
private void Activate()
{
if (!IsActivated())
{
var filePath = GetActivatedFilePath();
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.Create(filePath);
}
}
private bool IsActivated()
{
return File.Exists(this.GetActivatedFilePath());
}
private void Deactivate()
{
if (IsActivated())
{
File.Delete(GetActivatedFilePath());
}
}
Then we can also create a method to show the second form, since we will be calling this in more than one place. I've modified this to first hide the current form, then show the second form as a dialog (which means they can't switch back to the main form and code will pause in the first form until the second one closes), and then close the first form when the second one closes:
private void ShowForm2()
{
Form2 n = new Form2();
this.Hide();
n.ShowDialog();
this.Close();
}
Now we can check if they're activated in our Form_Load event, and if they are then immediately show the second form:
private void Form1_Load(object sender, EventArgs e)
{
// If they user is already activated, show the second form immediately
if (IsActivated())
{
ShowForm2();
}
}
And then your current code can also make use of these functions to activate the user. I'm assuming the code lives behind an Activate button:
private void btnActivate_Click(object sender, EventArgs e)
{
bool activated = false;
if (textBox1.Text.Length > 7)
{
string mac = textBox1.Text;
string str1 = mac.Substring(4, 1);
string str2 = mac.Substring(5, 1);
string str3 = mac.Substring(7, 1);
string str4 = mac.Substring(2, 1);
string pattern = str1 + str2 + str2 + str3 + str4;
activated = textBox2.Text == pattern;
}
if (activated)
{
MessageBox.Show("Program activated!!!");
Activate();
ShowForm2();
}
else
{
MessageBox.Show("Wrong key");
}
}
Related
I'm writing a FlashCard app in Windows Form.
Right now I'm trying to do is read word from string array and pass it to label. Then asking user to write the translation of this word. And finally pass the result to label box.
Here is my code:
public partial class EnglishPolishScreen : Form
{
//English words array
string[] words = new string[] { "word1", "word2", "word3", "word4" };
// meanings words array
string[] wordB = new string[] { "slowo1", "slowo2", "slowo3", "slowo4" };
int element = 0;
Thread thread;
public EnglishPolishScreen()
{
InitializeComponent();
}
private void CloseAppEvent(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
thread = new Thread(Threadd);
thread.Start();
}
private void Threadd()
{
englishWord.Text = words[element];
counterLabel.Text = element + 1 + " of " + words.Length;
if (answerBox.Text.Equals(wordB[element]))
{
resultLabel.Text = "Good";
element++;
}
else
resultLabel.Text = "Bad";
if (element == words.Length)
{
element = 0;
}
}
private void EnglishPolishScreen_Load(object sender, EventArgs e)
{
englishWord.Text = words[element];
}
Edited
Guys, Why I have to click two times in button to see next item from array? And why I can see "bad" answer straight after I click button? The "Good" answer shows up after second click.
Edited v2.xD
Sorted. Anyway is it good way to write code like this? If not how It could look better? Thanks
Regards
On button click, it is going through the whole for loop, i.e. the entire list of meanings, you would have to break the for loop as soon as a right match is found. So just use break; after resoultLabel.Text = "Good answer!";. Also as pointed out by #Neil, it is not good to use UI in a separate background thread.
By the way, I am not able to wrap my head around the logic of chances. For giving chances you would have to declare a global variable which would get added/subtracted when the a bad answer is found after Iterating through whole for loop, disallowing any further trial for the word.
I'm really confused so I'm hoping someone can help me out here. I'm working on a programming assignment for uni but there's one part that's really been bugging me and I can't move on until it is fixed. I have created two classes. The problems in each are shown here:
class Login : Form1
{
Form1 f = new Form1();
public void LoginCorrect()
{
Form1.attempts = 3;
MessageBox.Show("Correct Credentials Entered!");
f.loginScreenVar = false;
f.mainScreenVar = true;
f.ChangeScreen();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void ChangeScreen()
{
//Login Screen
txtUsername.Visible = loginScreenVar;
txtPassword.Visible = loginScreenVar;
btnLogin.Visible = loginScreenVar;
lblLoginCaption.Visible = loginScreenVar;
lblUsername.Visible = loginScreenVar;
lblPassword.Visible = loginScreenVar;
//Main Screen
lblWelcomeUser.Visible = mainScreenVar;
btnViewDetails.Visible = mainScreenVar;
btnViewAccounts.Visible = mainScreenVar;
btnLogout.Visible = mainScreenVar;
MessageBox.Show(loginScreenVar.ToString());
}
}
I have some controls on screen in my design which consist of text boxes, labels, and buttons, and these are meant to show and hide at diffferent times. I have created some booleans which can be set to true and false which will also set the visibility of these controls to true and false.
My problem is when accessing ChangeScreen() from my Login class, for some reason the controls don't hide when they're meant to. I've literally got a message box in the ChangeScreen() method which outputs the result of 'loginScreenVar' and this is false. Please can someone tell me why my 'Login Screen' controls are NOT hiding even though 'loginScreenVar' = false.
Another thing to note is when calling this code from a button in the Form1 class, it does work. However, due to the brief of my assignment I need to use multiple classes.
I really hope this isn't a bug and someone can help me here because I literally can't move on until this is fixed, thanks!
The issue is that, as noted in the comments, you create a new instance of Form1.
A whole new object, with own states.
Why can't I see this new instance? - well, if you did f.show() THEN you'd see it.
As it stands, you're still looking at the old instance.
So, what you need is a publicly accessible instance of Form1 which your two classes access, without creating a new instance.
OR
you could also work with two different windows. For example:
Form1_loaded(object sender, EventArgs e)
{
LoginWindow lw = new LoginWindow();
var result = lw.ShowDialog();
if(result == DialogResult.Cancel)
{
Application.Quit();
}
}
Let's assume you have a button for login. When clicked, it checks whether password and user name are correct. If not, the incorrect count gets increased by one. If the incorrect count is >= 3, then you just close the LoginWindow. (Default DialogResult is DialogResult.Cancel). The code might look like this:
LoginBtn_Click(object sender, EventArgs e)
{
if(UserNameInput.Text == userName && PasswordInput.Text == password)
{
failedAttempts = 0;
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
failedAttempts++;
if(failedAttempts >= 3)
{
MessageBox.Show("Wrong password. Shutting down the application...");
this.Close();
}
else
{
MessageBox.Show("Wrong password. " + (3-failedAttempts) + " tries left.");
}
}
}
This way, if login isn't successful, app quits. Otherwise the main screen appears.
Note: This is a basic solution. In a more complex app, you'd want more sophisticated output (not hard-coded strings) and comparisions using VariableName.Equals();
Let's keep it simple (and in the style you've started) for now:
public partial class Form1 : Form //Change the default "form1" "Button1" etc names as soon as possible
{
private bool loginScreenVar = true; //when naming booleans, use "truth test" sounding names like isLoginScreenMode
private bool mainScreenVar = true;
public Form1() //this is a constructor, a method that is always called when a new instance of this object is created
{
InitializeComponent();
//use the constructor to set things up
loginScreenVar = true;
mainScreenVar = false;
ChangeScreen();//make sure loginscreen is showing
}
public void ChangeScreen()
{
//Login Screen
txtUsername.Visible = loginScreenVar;
txtPassword.Visible = loginScreenVar;
btnLogin.Visible = loginScreenVar;
lblLoginCaption.Visible = loginScreenVar;
lblUsername.Visible = loginScreenVar;
lblPassword.Visible = loginScreenVar;
//Main Screen
lblWelcomeUser.Visible = mainScreenVar;
btnViewDetails.Visible = mainScreenVar;
btnViewAccounts.Visible = mainScreenVar;
btnLogout.Visible = mainScreenVar;
MessageBox.Show(loginScreenVar.ToString());
}
//call this method when the login is correct
public void LoginCorrect()
{
loginScreenVar = false;
mainScreenVar = true;
ChangeScreen();
}
//double click your login button in the forms designer to add this click event handler
public void LoginButton_Clicked(object sender, ClickEventArgs e){
if(txtUsername.Text == "user" && txtPassword.Text == "pass"){
LoginCorrect();
} else {
MessageBox.Show("Login incorrect");
}
}
}
Forget the class Login:Form stuff unless you're really trying to explore object instantiation and making your own classes for things. Your Form1 will be on show when your app starts, do all the logic inside it
A better way to change screens in winforms is by creating two separate panels each one contains the desired controls to be shown and hide so that you can switch between them
Code example:
Form1_loaded(object sender, EventArgs e)
{
LogInPanel.Visible=true;
}
private void ConnectBtn_Click(object sender, EventArgs e)
{
// Do your checking here
// IF conditions met
MainPanel.Visible=true;
}
private void DisconnectBtn_Click(object sender, EventArgs e)
{
// Do your checking here
// IF conditions met
LogInPanel.Visible=true;
}
If you want to keep you methadologie make sure your program.cs runs Login class instead of Form1 class
I am with a problem where I have 3 forms and a class called Languages. The 3 Forms are the Main Form, The Settings Form and Languages Form. So what I need help with is, when I click in the language flag, I am trying to access to Main Form to pick up there a function I created there called 'changedLanguages()' I can access it, but when I click the flag, the Main Form is not Updating the changes without close the actual opened Main Form. But if i write a line of code mus.Show(); it opens a new one with the changes.
But I want to do the changes in the actual opened Main Form. Is it possible?
Below you have the LanguagesForm from the flag image click:
private void ptLang_img_Click(object sender, EventArgs e)
{
enLang_img.BackColor = Color.Transparent;
ptLang_img.BackColor = Color.CadetBlue;
Form1 mus = new Form1();
Languages PT_lang = new Languages();
mus.changeLanguage(PT_lang.file_PT, PT_lang.open_PT, PT_lang.settings_PT, PT_lang.exit_PT, PT_lang.controls_PT, PT_lang.play_PT, PT_lang.pause_PT, PT_lang.stop_PT, PT_lang.next_PT, PT_lang.prev_PT, PT_lang.playRecently_PT, PT_lang.volUp_PT, PT_lang.volDown_PT, PT_lang.help_PT, PT_lang.about_PT, PT_lang.faq_PT, PT_lang.update_PT);
mus.Refresh();
}
And here you have the function of 'changedLanguages()':
public void changeLanguage(string file, string open, string settings, string exit, string controls, string play, string pause, string stop, string next, string prev, string recPlayed, string volUp, string volDown, string help, string about, string faq, string update)
{
fileToolStripMenuItem.Text = file;
openToolStripMenuItem.Text = open;
settingsToolStripMenuItem.Text = settings;
exitToolStripMenuItem.Text = exit;
controlsToolStripMenuItem.Text = controls;
playToolStripMenuItem.Text = play;
pauseToolStripMenuItem.Text = pause;
stopToolStripMenuItem.Text = stop;
forwardToolStripMenuItem.Text = next;
backwardToolStripMenuItem.Text = prev;
playRecentToolStripMenuItem.Text = recPlayed;
volumeUpToolStripMenuItem.Text = volUp;
volumeDownToolStripMenuItem.Text = volDown;
helpToolStripMenuItem.Text = help;
aboutUMusicToolStripMenuItem.Text = about;
fAQToolStripMenuItem.Text = faq;
updatesToolStripMenuItem.Text = update;
}
Any help is welcome...
create a static instance of your main form, I hope that the changes will be immediately visible, if it does not work, add this statement after making your changes
Application.DoEvents();
I am building winforms .net Application , I have a E-Pos printer on Network ,
using this Code below :
On Form Loading Printer initializing :
explorer = new PosExplorer(this);
DeviceInfo receiptPrinterDevice = explorer.GetDevice("PosPrinter", Properties.Settings.Default.KitchenPrinter); //May need to change this if you don't use a logicial name or use a different one.
kitchenPrinter = (PosPrinter)explorer.CreateInstance(receiptPrinterDevice);
ConnectToPrinter();
private void ConnectToPrinter()
{
kitchenPrinter.Open();
kitchenPrinter.Claim(10000);
kitchenPrinter.DeviceEnabled = true;
}
Function Call on Print Button :
private void PrintReceipt()
{
try
{ kitchenPrinter.PrintNormal(PrinterStation.Receipt, "test");
}
finally
{
}
}
When I want to Switch to Other Form I call Disconnect Function
DisconnectFromPrinter(kitchenPrinter);
Reporting frm = new Reporting(curuser);
frm.Show();
this.Hide();
private void DisconnectFromPrinter(PosPrinter kitchenPrinter)
{
try
{
kitchenPrinter.Release();
kitchenPrinter.Close();
}
catch { }
}
It prints successful one time ,when pressing to print next time it throws and exception
Method ClaimDevice threw an exception. Attempt was made to perform an illegal or unsupported operation with the device, or an invalid parameter value was used.
any suggestion ?
Since the Release command is not being effective and may Claim command is throwing an error every time I am loading my form because it is being Claimed before.
So I have Create a separate Class Called "createPOS"
class createPOS
{
public static PosExplorer explorer;
public static PosPrinter kitchenPrinter;
public static void createPos()
{
explorer = new PosExplorer();
DeviceInfo receiptPrinterDevice = explorer.GetDevice("PosPrinter", Properties.Settings.Default.KitchenPrinter); //May need to change this if you don't use a logicial name or use a different one.
kitchenPrinter = (PosPrinter)explorer.CreateInstance(receiptPrinterDevice);
kitchenPrinter.Open();
kitchenPrinter.Claim(10000);
kitchenPrinter.DeviceEnabled = true;
}
public static void Print(string text){
if (kitchenPrinter.Claimed)
PrintTextLine(kitchenPrinter, text); // kitchenPrinter.PrintNormal(PrinterStation.Receipt, text ); //Print text, then a new line character.
}
private static void PrintTextLine(PosPrinter printer, string text)
{
if (text.Length < printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, text + Environment.NewLine); //Print text, then a new line character.
else if (text.Length > printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, TruncateAt(text, printer.RecLineChars)); //Print exactly as many characters as the printer allows, truncating the rest, no new line character (printer will probably auto-feed for us)
else if (text.Length == printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, text + Environment.NewLine); //Print text, no new line character, printer will probably auto-feed for us.
}
private static string TruncateAt(string text, int maxWidth)
{
string retVal = text;
if (text.Length > maxWidth)
retVal = text.Substring(0, maxWidth);
return retVal;
}
}
and On the Login form that it will only be accessed once I have initialized my printer
createPOS.createPos();
and on MainForm I have called the Printing Method :
createPOS.Print("This allows me to Print Several times");
on that way I am able to print several times and even I navigate to other forms and come back that works fine.
Thank you guys.
In my application, I have one form. When a button is pressed to open a new instance of that form I have the following code (Which also is run at first application start up):
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists(#"C:\Users\Vlad\Documents\" + this.Text.ToString() +"_Settings_Save.rtf"))
{
try
{
richTextBox2.LoadFile(#"C:\Users\Vlad\Documents\" + this.Text.ToString() + "_Settings_Save.rtf", RichTextBoxStreamType.RichText);
richTextBox1.LoadFile(richTextBox2.Text + #"\" + this.Text.ToString() + "_Save_File.rtf", RichTextBoxStreamType.RichText);
}
catch
{
}
}
else if (File.Exists(#"C:\Users\Vlad\Documents\" + this.Text.ToString() + "_Settings.txt"))
{
richTextBox2.LoadFile(#"C:\Users\Vlad\Documents\" + this.Text.ToString() + "_Settings.txt");
richTextBox1.LoadFile(richTextBox2.Text + #"\" + this.Text.ToString() + "_TestSave.txt");
}
else
{
}
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
double n = Application.OpenForms.Count;
double x = n + 1;
Form1 newForm = new Form1();
newForm.Show();
newForm.Text = "Notables " + x.ToString();
}
I was hoping that when a new instance is opened, the new form would do the form1_load event and load that file.
This application is meant to be universal in saving. Meaning, you can open and close as many instances as you want, and in EACH instance, there will be the same text as before the instance was closed.
I apologize if this was confusing.
Its time for me to go now, I will respond to all questions tomorrow morning. About 6 hours from now.
Thank you.
--EDIT--
Here is the extreme simplification of what I wanted to do.
If the user opens two instances of form 1. and then closes them. Upon opening each, both of the forms should have saved data from the last close
--EDIT 2--
Now, Here is a simplification of what is happening instead.
The application does indeed save correctly but however, new instances do not open the correct files. They simply open the same file as from the first instance. but the save file is correct.
Run your code under a debugger, and step through it to see what it is doing.
I suspect the problem is that you open the form before you set the Text property to the name of the file you want to be loaded, so the Load() method generates invalid filenames and thus executes the empty else {} block.
Form1 newForm = new Form1();
newForm.Show();
newForm.Text = "Notables " + x.ToString();
when you are calling a new instance, simply call another method to do that work for you. If you need to save some data from the first instance, save it in an application wide object or in a static variable.
I assume that the file exists. It's probably not getting loaded because of some exception, and you can't see that because you have an empty catch block:
try
{
richTextBox2.LoadFile(#"C:\Users\Vlad\Documents\" + this.Text.ToString() + "_Settings_Save.rtf", RichTextBoxStreamType.RichText);
richTextBox1.LoadFile(richTextBox2.Text + #"\" + this.Text.ToString() + "_Save_File.rtf", RichTextBoxStreamType.RichText);
}
catch
{
}
Catch the exception and notify the user, instead:
catch (Exception exception)
{
NotifyUser(exception);
}
Notify user could raise a message box, or write to a log file, or both.
Also, if the file doesn't exist, you could raise an exception or call NotifyUser to alert the user (i.e., at this point, you the developer) of that fact:
else
{
NotifyUser("File not found: " + fileName);
}
Ok, so the problem is that the form was being opened as form 1 then changing to a specific text. and in between those two processes the rest of my application was not able to run the first part of my code. I fixed this by switching the Form.Show() AFTER I change its text programmatically.
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
double n = Application.OpenForms.Count;
double x = n + 1;
Form1 newForm = new Form1();
newForm.Text = "Notables " + x.ToString();
newForm.Show();
}