Whats the problem in this function C# - c#

I have written the below function to select a numeric string such as 1,23,000.00
In the WebBrowser I am trapping Double_Click Event and then passing the selected range to the below function.
lets say the initial selection was 000 and my target is to select the whole string as mentioned above.
myRange=doc.selection.createRange()
myRange=SelectCSNumbers(myRange)
I am returning a Range object from the below function. The issue here is
return tmpRange.duplicate();//here it should terminate
count++;
when I am returning the final range this method is getting called again
How I dont know, Can anyone pointout my mistake.
private mshtml.IHTMLTxtRange SelectCSNumbers(mshtml.IHTMLTxtRange myRange)
{
mshtml.IHTMLTxtRange tmpRange = myRange.duplicate();
string[] strInt = tmpRange.text.Split(',');
bool result = false;
result = CheckText(tmpRange, strInt, result);
if (result && count==0)//
{
//Expand the Range with a single Character
tmpRange.expand("character");
if (tmpRange.text.Length > myRange.text.Length)
{
if (tmpRange.text.IndexOf(' ') == -1) //if no space is found that means the selection is not proper
{
//Check for ,/.
if (tmpRange.text.IndexOf(',') == -1)//if NO Comma is found
{
if (tmpRange.text.IndexOf('.') == -1)
{
//EOS
}
else
{
//. is found
SelectCSNumbers(tmpRange.duplicate());
}
}
else
{
SelectCSNumbers(tmpRange.duplicate());
}
}
else if (tmpRange.text.IndexOf(' ') != -1)
{
tmpRange = myRange.duplicate();
tmpRange.moveStart("character", -1);
if (tmpRange.text.IndexOf(' ') == -1) //if no space is found that means the selection is not proper
{
//Check for ,/.
if (tmpRange.text.IndexOf(',') == -1)//if NO Comma is found
{
if (tmpRange.text.IndexOf('.') == -1)
{
//EOS
}
else
{
//. is found
SelectCSNumbers(tmpRange.duplicate());
}
}
else
{
SelectCSNumbers(tmpRange.duplicate());
}
}
}
}
else if (tmpRange.text.Length == myRange.text.Length)
{
tmpRange = myRange.duplicate();
tmpRange.moveStart("character", -1);
if (tmpRange.text.Length == myRange.text.Length)
{
//tmpRange = null;
return tmpRange.duplicate();//here it should terminate
count++;
}
else if (tmpRange.text.IndexOf(' ') == -1) //if no space is found that means the selection is not proper
{
if (tmpRange.text.IndexOf(',') == -1)//if NO Comma is found
{
if (tmpRange.text.IndexOf('.') == -1)
{
//EOS
}
else
{
//. is found
SelectCSNumbers(tmpRange.duplicate());
}
}
else
{
SelectCSNumbers(tmpRange.duplicate());
}
}
}
}
return tmpRange.duplicate();
}

This doesn't help immediately, but addresses a bigger problem
This code needs to be refactored. It will cause problems for you down the line. You have copy-pasted code that will be a pain to take care of. And also, it makes it harder for others to help.
Here is a suggestion for a refactoring (Not Tested)
private mshtml.IHTMLTxtRange SelectCSNumbers(mshtml.IHTMLTxtRange myRange)
{
mshtml.IHTMLTxtRange tmpRange = myRange.duplicate();
string[] strInt = tmpRange.text.Split(',');
bool result = false;
result = CheckText(tmpRange, strInt, result);
if (result && count==0)//
{
//Expand the Range with a single Character
tmpRange.expand("character");
if (tmpRange.text.Length > myRange.text.Length)
{
if (tmpRange.text.IndexOf(' ') == -1) //if no space is found that means the selection is not proper
{
SomeOtherFunction(tmpRange);
}
else if (tmpRange.text.IndexOf(' ') != -1)
{
tmpRange = myRange.duplicate();
tmpRange.moveStart("character", -1);
SomeOtherFunction(tmpRange);
}
}
else if (tmpRange.text.Length == myRange.text.Length)
{
tmpRange = myRange.duplicate();
tmpRange.moveStart("character", -1);
if (tmpRange.text.Length == myRange.text.Length)
{
//tmpRange = null;
return tmpRange.duplicate();//here it should terminate
count++;
}
else if (tmpRange.text.IndexOf(' ') == -1) //if no space is found that means the selection is not proper
{
SomeOtherFunction(tmpRange);
}
}
}
return tmpRange.duplicate();
}
private void SomeOtherFunction(mshtml.IHTMLTxtRange tmpRange)
{
if (tmpRange.text.IndexOf(',') == -1)//if NO Comma is found
{
if (tmpRange.text.IndexOf('.') == -1)
{
//EOS
}
else
{
//. is found
SelectCSNumbers(tmpRange.duplicate());
}
}
else
{
SelectCSNumbers(tmpRange.duplicate());
}
}

Random guess:
if (tmpRange.text.Length == myRange.text.Length)
{
count++;
return tmpRange.duplicate();
}
If you put count++ after the return statement, it will never be executed.

Related

Superpower: match a string with tokenizer only if it begins a line

When tokenizing in superpower, how to match a string only if it is the first thing in a line (note: this is a different question than this one) ?
For example, assume I have a language with only the following 4 characters (' ', ':', 'X', 'Y'), each of which is a token. There is also a 'Header' token to capture cases of the following regex pattern /^[XY]+:/ (any number of Xs and Ys followed by a colon, only if they start the line).
Here is a quick class for testing (the 4th test-case fails):
using System;
using Superpower;
using Superpower.Parsers;
using Superpower.Tokenizers;
public enum Tokens { Space, Colon, Header, X, Y }
public class XYTokenizer
{
static void Main(string[] args)
{
Test("X", Tokens.X);
Test("XY", Tokens.X, Tokens.Y);
Test("X Y:", Tokens.X, Tokens.Space, Tokens.Y, Tokens.Colon);
Test("X: X", Tokens.Header, Tokens.Space, Tokens.X);
}
public static readonly Tokenizer<Tokens> tokenizer = new TokenizerBuilder<Tokens>()
.Match(Character.EqualTo('X'), Tokens.X)
.Match(Character.EqualTo('Y'), Tokens.Y)
.Match(Character.EqualTo(':'), Tokens.Colon)
.Match(Character.EqualTo(' '), Tokens.Space)
.Build();
static void Test(string input, params Tokens[] expected)
{
var tokens = tokenizer.Tokenize(input);
var i = 0;
foreach (var t in tokens)
{
if (t.Kind != expected[i])
{
Console.WriteLine("tokens[" + i + "] was Tokens." + t.Kind
+ " not Tokens." + expected[i] + " for '" + input + "'");
return;
}
i++;
}
Console.WriteLine("OK");
}
}
I came up with a custom Tokenizer based on the example found here. I added comments throughout the code so you can follow what's happening.
public class MyTokenizer : Tokenizer<Tokens>
{
protected override IEnumerable<Result<Tokens>> Tokenize(TextSpan input)
{
Result<char> next = input.ConsumeChar();
bool checkForHeader = true;
while (next.HasValue)
{
// need to check for a header when starting a new line
if (checkForHeader)
{
var headerStartLocation = next.Location;
var tokenQueue = new List<Result<Tokens>>();
while (next.HasValue && (next.Value == 'X' || next.Value == 'Y'))
{
tokenQueue.Add(Result.Value(next.Value == 'X' ? Tokens.X : Tokens.Y, next.Location, next.Remainder));
next = next.Remainder.ConsumeChar();
}
// only if we had at least one X or one Y
if (tokenQueue.Any())
{
if (next.HasValue && next.Value == ':')
{
// this is a header token; we have to return a Result of the start location
// along with the remainder at this location
yield return Result.Value(Tokens.Header, headerStartLocation, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else
{
// this isn't a header; we have to return all the tokens we parsed up to this point
foreach (Result<Tokens> tokenResult in tokenQueue)
{
yield return tokenResult;
}
}
}
if (!next.HasValue)
yield break;
}
checkForHeader = false;
if (next.Value == '\r')
{
// skip over the carriage return
next = next.Remainder.ConsumeChar();
continue;
}
if (next.Value == '\n')
{
// line break; check for a header token here
next = next.Remainder.ConsumeChar();
checkForHeader = true;
continue;
}
if (next.Value == 'A')
{
var abcStart = next.Location;
next = next.Remainder.ConsumeChar();
if (next.HasValue && next.Value == 'B')
{
next = next.Remainder.ConsumeChar();
if (next.HasValue && next.Value == 'C')
{
yield return Result.Value(Tokens.ABC, abcStart, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else
{
yield return Result.Empty<Tokens>(next.Location, $"unrecognized `AB{next.Value}`");
}
}
else
{
yield return Result.Empty<Tokens>(next.Location, $"unrecognized `A{next.Value}`");
}
}
else if (next.Value == 'X')
{
yield return Result.Value(Tokens.X, next.Location, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else if (next.Value == 'Y')
{
yield return Result.Value(Tokens.Y, next.Location, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else if (next.Value == ':')
{
yield return Result.Value(Tokens.Colon, next.Location, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else if (next.Value == ' ')
{
yield return Result.Value(Tokens.Space, next.Location, next.Remainder);
next = next.Remainder.ConsumeChar();
}
else
{
yield return Result.Empty<Tokens>(next.Location, $"unrecognized `{next.Value}`");
next = next.Remainder.ConsumeChar(); // Skip the character anyway
}
}
}
}
And you can call it like this:
var tokens = new MyTokenizer().Tokenize(input);

Weird results in c# app game

For an internship project I'm making an app based on Foley sound effects. I made a game for it. One button generates the effect, one plays the sound and four buttons for possible awnsers.
Somehow, the text displays ('helaas' and 'juist!') aren't consistent. The awnser could be right and it will display 'helaas', but when clicken multiple times, it will display 'juist!'. Can anyone help me with what I am doing wrong here?
int kiesnummer()
{
Random randomSound = new Random();
int theSound = randomSound.Next(1, 4);
return theSound;
}
NewSound.Click += delegate
{
kiesnummer();
if (kiesnummer() == 1)
{
welk.Text = "Open haard";
}
else if (kiesnummer() == 2)
{
welk.Text = "Regen";
}
else if (kiesnummer() == 3)
{
welk.Text = "Hondenpootjes op hout";
}
else if (kiesnummer() == 4)
{
welk.Text = "Paardenhoeven op beton";
}
};
Play.Click += delegate
{
if (kiesnummer() == 1)
{
_chips.Start();
}
else if (kiesnummer() == 2)
{
_rain.Start();
}
else if (kiesnummer() == 3)
{
_doggo.Start();
}
else if(kiesnummer() == 4)
{
_koko.Start();
}
};
//Parameters aan functie koppelen bij klikken op de knop
Aw1.Click += delegate
{
kiesknop(1);
};
Aw2.Click += delegate
{
kiesknop(2);
};
Aw3.Click += delegate
{
kiesknop(3);
};
Aw4.Click += delegate
{
kiesknop(4);
};
//Beoordelen of keuze juist of onjuist is
bool kiesknop(int knop)
{
if (knop == kiesnummer())
{
end.Text = "Juist!";
return true;
}
else
{
end.Text = "Helaas!";
return false;
}
}
(I left the button and media declerations out, since it didn't seem relevant)
Calling kiesnummer(); in every if condition will give you different results as it generates new random value every time.
Call it once and use its value through-out:
int value = kiesnummer();
if (value == 1)
{
welk.Text = "Open haard";
}
else if (value == 2)
{
welk.Text = "Regen";
}
else if (value) == 3)
{
welk.Text = "Hondenpootjes op hout";
}
else if (value == 4)
{
welk.Text = "Paardenhoeven op beton";
}

How to return "if" in a if loop?

Hi guys actually first I wanted to do this loop.
Process p = Process.GetProcessesByName("etcProgram.bin")[0];
foreach (System.Diagnostics.ProcessModule moz in p.Modules)
if (csh.Text == "csh" || bin.Text == "bin")
{
if (moz.FileName.IndexOf("csh") != -1)
{
csh.Text = moz.BaseAddress.ToString();
}
if (moz.FileName.IndexOf("bin") != -1)
{
bin.Text = moz.BaseAddress.ToString();
}
}
else
{
!!!!!! return to "if" until "if code" happens !!!!!!
}
But my poor code knowledge can't come through this problem. So I wrote nearly same thinh with timer. Then I wrote this code.
private void tmrActive_Tick(object sender, EventArgs e)
{
try
{
Process p = Process.GetProcessesByName("Wolfteam.bin")[0];
foreach (System.Diagnostics.ProcessModule moz in p.Modules)
if (csh.Text == "csh" || bin.Text == "bin")
{
if (moz.FileName.IndexOf("csh") != -1)
{
csh.Text = moz.BaseAddress.ToString();
}
if (moz.FileName.IndexOf("bin") != -1)
{
bin.Text = moz.BaseAddress.ToString();
}
}
else
{
tmrActive.Stop();
MessageBox.Show("It's stopped");
}
}
But I saw that MessageBox appears 5-6 times when I started this.And I dont know why. So I dont feel very safe about use this code.
1- Do you know what's the problem with that timer. Shouldn't this messagebox appear once?
2- Can you help me about the code without timer.Is there anyway to do it?
You mean something like...
foreach (System.Diagnostics.ProcessModule moz in p.Modules)
{
bool breakloop = false;
while (!breakloop)
{
if (csh.Text == "csh" || bin.Text == "bin")
{
if (moz.FileName.IndexOf("csh") != -1)
csh.Text = moz.BaseAddress.ToString();
if (moz.FileName.IndexOf("bin") != -1)
bin.Text = moz.BaseAddress.ToString();
breakloop = true;
}
}
}
You can simply use break statement in order to stop a loop.
foreach (System.Diagnostics.ProcessModule moz in p.Modules)
{
if (csh.Text == "csh" || bin.Text == "bin")
{
if (moz.FileName.IndexOf("csh") != -1)
{
csh.Text = moz.BaseAddress.ToString();
}
if (moz.FileName.IndexOf("bin") != -1)
{
bin.Text = moz.BaseAddress.ToString();
}
break;
}
}
Hope this helps.
You could use this whole code as a Recursive function with a Specific condition to stop the condition whenever you want like this
foreach (System.Diagnostics.ProcessModule moz in p.Modules) { looping () {
bool breakloop = false;
while (!breakloop)
{
if (csh.Text == "csh" || bin.Text == "bin")
{
if (moz.FileName.IndexOf("csh") != -1)
csh.Text = moz.BaseAddress.ToString();
if (moz.FileName.IndexOf("bin") != -1)
bin.Text = moz.BaseAddress.ToString();
breakloop = true;
looping();
}
}

Simple 2 Boolean Efficiency

Just a quick one guys - y'know when your brain hurts just looking at something. Just seeing if there is a "better" way to do this in terms of boolean logic.
private RegenerationType AccquireRegenerationState (int floor, int playerFloor)
{
bool entranceExists = (floorBlocks[floor].doorBlocks.Count != 0) ? true : false;
if (floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited)
{
if (entranceExists)
{
return RegenerationType.Still;
}
else
{
return RegenerationType.Limit;
}
}
else
{
if (entranceExists)
{
return RegenerationType.Prime;
}
else
{
return RegenerationType.Full;
}
}
}
I guess that's the best you can achieve. Of course, assuming that you maintain code readability and clearness:
private RegenerationType AccquireRegenerationState (int floor, int playerFloor)
{
var entranceExists = floorBlocks[floor].doorBlocks.Count != 0;
var whatever = floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited;
if (whatever)
{
return entranceExists ? RegenerationType.Still : RegenerationType.Limit;
}
else
{
return entranceExists ? RegenerationType.Prime : RegenerationType.Full;
}
}
bool entranceExists = (floorBlocks[floor].doorBlocks.Count != 0);
return
(floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited)?
(entranceExists? RegenerationType.Still: RegenerationType.Limit):
(entranceExists? RegenerationType.Prime: RegenerationType.Full);

How to disable more than one NumericUpDown controls using one method?

i have a form with more than one NumericUpDown as controls to input answer. i want every input is true for an operation (multiplication, sum etc), NumericUpDown for that operation will be disable. i have used the code below (just for sum operation), but i think its not efficient because i have to make a method to check every operation.
private void IsSumTrue() {
if (add1 + add2 == sum.Value)
{
sum.Enabled = false;
}
}
private void IsDifferenceTrue()
{
if (add1 - add2 == difference.Value)
{
difference.Enabled = false;
}
}
private void IsProductTrue()
{
if (add1 * add2 == product.Value)
{
product.Enabled = false;
}
}
private void IsQuotientTrue()
{
if (add1 / add2 == quotient.Value)
{
quotient.Enabled = false;
}
}
anyone have idea how to make it more efficient with just a method for all operation?
below is my idea, but to check the value is true for every NumericUpDown i don't know how.
private void DisableIfValueIsTrue()
{
foreach(Control control in this.Controls)
{
NumericUpDown value = control as NumericUpDown;
// if(value [NEED HELP]
}
}
Considering your situtaion, you can set a tag for each NumericUpDown in design mode like this:
sum.Tag=1;
square.Tag=2;
etc
Then define some int variables:
int iSum=add1+add2;
int iSquare= //Whatever you want
etc
And finally loop through your controls this way:
foreach (NumericUpDown control in this.Controls.OfType<NumericUpDown>())
{
int intCondition = Convert.ToInt32(control.Tag) == 1
? iSum
: Convert.ToInt32(control.Tag) == 2
? iSquare
: Convert.ToInt32(control.Tag) == 3
? i3
: i4; //You should extend this for your 8 controls
control.Enabled = intCondition == control.Value;
}
OK! Second way I offer
Since you will have to always check 8 different conditions, you could simply forget about looping through the controls and just change your method like this:
private void DisableIfValueIsTrue()
{
sum.Enabled = add1 + add2 != sum.Value;
difference.Enabled= add1 - add2 != difference.Value;
product.Enabled= add1 * add2 != product.Value;
quotient.Enabled= (add2 !=0) && (add1 / add2 != quotient.Value);
//etc
}
I came across this while doing some research and would like to give my solution I used for my situation and hope it helps people. I needed minimum and maximum numbers for a calculation, so mine are named appropriately and I correlated these with some CheckBoxes. I used null in beginning of minimum and end of maximum to account for empty. I also had to create an event handler SubscribeToEvents() shown below.
In my load event for my form:
SubscribeToEvents();
_checkBoxs = new[] { cbXLight, cbLight, cbMedium, cbHeavy, cbXHeavy, cbXXHeavy, cbXXXHeavy };
_minimumsNumericUpDowns = new[] { null, nLightMin, nMediumMin, nHeavyMin, nXHeavyMin, nXXHeavyMin, nXXXHeavyMin };
_maximumsNumericUpDowns = new[] { nXLightMax, nLightMax, nMediumMax, nHeavyMax, nXHeavyMax, nXXHeavyMax, null };
then I created a method:
private void DisableNumericUpDowns()
{
// disable everything:
foreach (var n in _minimumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
foreach (var n in _maximumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
}
The event handler:
private bool _eventsSubscribed;
private void SubscribeToEvents()
{
if (_eventsSubscribed)
return;
_eventsSubscribed = true;
cbXXHeavy.CheckedChanged += CheckBox_NumericState;
cbXHeavy.CheckedChanged += CheckBox_NumericState;
cbXLight.CheckedChanged += CheckBox_NumericState;
cbHeavy.CheckedChanged += CheckBox_NumericState;
cbLight.CheckedChanged += CheckBox_NumericState;
cbMedium.CheckedChanged += CheckBox_NumericState;
cbXXXHeavy.CheckedChanged += CheckBox_NumericState;
}
Now I can used this to check when they are enabled and if they are greater than or less than 0 if needed in the method CheckBox:
private void CheckBox_NumericState(object sender, EventArgs e)
{
// disable everything
DisableNumericUpDowns();
// see if more than one checkbox is checked:
var numChecked = _checkBoxs.Count((cb) => cb.Checked);
// enable things if more than one item is checked:
if (numChecked <= 1) return;
// find the smallest and enable its max:
var smallest = -1;
for (var i = 0; i < _checkBoxs.Length; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
smallest = i;
break;
}
// find the largest and enable its min:
var largest = -1;
for (var i = _checkBoxs.Length - 1; i >= 0; i--)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
largest = i;
break;
}
// enable both for everything between smallest and largest:
var tempVar = largest - 1;
for (var i = (smallest + 1); i <= tempVar; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
}
}
So I can check each state as required:
I want to check if Extra Light is check:
// Extra Light
if (!cbXLight.Checked) return;
if (nXLightMax.Enabled == false)
{
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
if (nXLightMax.Value > 0)
{
_dMax = nXLightMax.Value;
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Extra Light Max cannot be zero (0)");
}
}
and next light checks both:
// Light
if (cbLight.Checked)
{
if (nLightMin.Enabled == false && nLightMax.Enabled == false)
{
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMin.Enabled && nLightMin.Value > 0)
{
if (nXLightMax.Enabled && nLightMin.Enabled && nLightMax.Enabled == false)
{
_dMin = nLightMin.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMax.Value > 0)
{
_dMin = nLightMin.Value;
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
return;
}
}
}
else if (nLightMin.Enabled == false && nLightMax.Enabled)
{
if (nLightMax.Value > 0)
{
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
}
}
else
{
MessageBox.Show(#"Light Min cannot be zero (0)");
return;
}
}
}
Hope this helps someone.
Tim
thanks for #AlexJoliq and #BrettCaswell. just want to inform that before Alex edited his answer from using "==" to "!=", i (thought) already solved the problem. but i don't know where is the more effective and efficient way, alex's or mine.
below is my code for DisableIfValueIsTrue():
if (add1 + add2 == sum.Value) sum.Enabled = false;
if (add1 - add2 == difference.Value) difference.Enabled = false;
if (add1 * add2 == product.Value) product.Enabled = false;
if (add1 / add2 == quotient.Value) quotient.Enabled = false;

Categories

Resources