How to update a TextView text (decode text effect)? - c#

I need help as mentioned in the title.
I have a timer routine that will update the text of a label. It's a decode text effect, but it doesn't seem to update when the timer routine is executed. I am using C#.
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Text;
using System.Timers;
using System.Linq;
namespace ValidateCreditCardNumber_Android
{
[Activity (Label = "ValidateCreditCardNumber_Android", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
EditText editText;
DecodeTextView resultLabel;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
editText = FindViewById<EditText> (Resource.Id.editText);
Button validateButton = FindViewById<Button> (Resource.Id.validateButton);
resultLabel = FindViewById<DecodeTextView> (Resource.Id.resultLabel);
editText.KeyListener = Android.Text.Method.DigitsKeyListener.GetInstance("0123456789" + System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
validateButton.Click += OnNumberEntryCompleted;
}
void OnNumberEntryCompleted(object sender, EventArgs args)
{
var entry = editText;
var resultText = "";
if (Mod10Check (entry.Text)) {
// resultLabel.SetTextColor(Android.Graphics.Color.White);
resultText = "__VALID NUMBER";
} else {
resultText = "INVALID NUMBER";
}
// entry.Enabled = false;
// resultLabel.AnimateText (true, resultText, 10);
RunOnUiThread(() => resultLabel.AnimateText (true, resultText, 10));
}
public static bool Mod10Check(string creditCardNumber)
{
// Check whether input string is null or empty.
if (string.IsNullOrEmpty(creditCardNumber)) {
return false;
}
char[] charArray = creditCardNumber.ToCharArray();
// 1. Starting with the check digit double the value of every other digit
// 2. If doubling of a number results in a two digits number, add up.
// the digits to get a single digit number. This will results in eight single digit numbers.
// 3. Get the sum of the digits.
int sumOfDigits = charArray.Where((e) => e >= '0' && e <= '9')
.Reverse()
.Select((e, i) => ((int)e - 48) * (i % 2 == 0 ? 1 : 2))
.Sum((e) => e / 10 + e % 10);
// If the final sum is divisible by 10, then the credit card number.
// is valid. If it is not divisible by 10, the number is invalid.
return sumOfDigits % 10 == 0;
}
}
}
DecodeTextView.cs
using System;
using System.Text;
using System.Timers;
//using Android.Runtime;
using Android.Content;
using Android.Util;
namespace ValidateCreditCardNumber_Android
{
public class DecodeTextView : Android.Widget.TextView
{
private readonly Timer _timerAnimate = new Timer();
private TextDecodeEffect _decodeEffect;
private bool _showing;
private int _initGenCount;
public int Interval
{
get { return (int)_timerAnimate.Interval; }
set { _timerAnimate.Interval = value; }
}
// protected DecodeTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
_timerAnimate.Interval = 100;
_timerAnimate.Elapsed += _timerAnimate_Tick;
}
public void AnimateText(bool show, string text, int initGenCount)
{
_initGenCount = initGenCount;
_decodeEffect = new TextDecodeEffect(text) { TextVisible = !show };
Text = _decodeEffect.Peek (DecodeMode.None);
_showing = show;
_timerAnimate.Start ();
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Text = text;
}
}
}
public enum DecodeMode
{
None,
Show,
Numbers,
Hide
}
class TextDecodeEffect
{
private int _visibleCount;
private readonly Random _random = new Random ();
public bool TextVisible
{
get { return _visibleCount == OriginalText.Length; }
set { _visibleCount = value ? OriginalText.Length : 0; }
}
public string OriginalText { get; private set; }
public TextDecodeEffect(string text)
{
OriginalText = text;
}
public string Peek(DecodeMode mode)
{
switch (mode) {
case DecodeMode.Numbers:
return GenerateNumberRange (OriginalText.Length);
case DecodeMode.Hide:
if (_visibleCount == 0)
return null;
_visibleCount--;
break;
case DecodeMode.Show:
if (_visibleCount == OriginalText.Length)
return null;
_visibleCount++;
break;
}
var text = GenerateNumberRange (OriginalText.Length - _visibleCount);
text += OriginalText.Substring (OriginalText.Length - _visibleCount, _visibleCount);
return text;
}
public string GenerateNumberRange(int count)
{
var SB = new StringBuilder ();
for (int i = 0; i < count; i++)
SB.Append(_random.Next(0, 10));
return SB.ToString();
}
}
}
Here you can found the project
Please help me to fix this problem :( thank you.

This is a threading issue, you can only change UI elements on the UI thread and the timer callback _timerAnimate_Tick will execute on a background thread.
You can see this by logging the thread ID for DecodeTextViews constructor and its _timerAnimate_Tick method:
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
// ...
Console.WriteLine ("DecodeTextView executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
Console.WriteLine ("_timerAnimate_Tick executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
// ...
}
Which will render the following in the log output:
DecodeTextView executing on thread: 1
_timerAnimate_Tick executing on thread: 6
This is simply fixed by changing the Text property of DecodeTextView on the UI thread using the Post method:
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Post (() => {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
});
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Post (() => {
Text = text;
});
}
}

Related

C# Called method is ignored with no error

I am developing a C# Windows Form program in which there are a number of called Methods (what in VB I called Subs). Excuse me if I'm using the wrong terms, new to C#. One of these methods is being ignored, CreateFolder(). When I set break points to debug and step through, the program gets to the called method and goes right through it like it like it was a blank line, no errors warning just goes through. The program is a bit large so I'm including what I hope is helpful. Sorry if too much. The method (sub) not being executed is CreateFolder(). Again, the debugger will stop on this line[CreateFolder()] in the ProcessEmail() routine but just goes on without going to the called code. Thoughts?
public partial class FrmProcessNew : Form
{
...bunch of global vaiables
private void FrmProcessNew_Load(object sender, EventArgs e)
{
chkBoxTesting.Checked = Convert.ToBoolean(ConfigurationManager.AppSettings["testing"]); //check if test to ignore bad credit cards
}
private void btnStart_Click(object sender, EventArgs e)
{
ProcessEmail(); //check for, process and then move new Outlook emails
}
public void ScrollBox(string box) //try to get scroll box right
{
if (box == "Text")
{
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
}
if (box == "List")
{ listBox1.TopIndex = listBox1.Items.Count - 1; }
}
public static int GetLineNumber(COMException ex) //Get the line number if an error occurs - from stack overflow
{
var lineNumber = 0;
const string lineSearch = ":line ";
var index = ex.StackTrace.LastIndexOf(lineSearch);
if (index != -1)
{
var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
if (int.TryParse(lineNumberText, out lineNumber))
{
}
}
return lineNumber;
}
private void ProcessEmail() // Process the new email
{
while (inboxFolder.Items.Count == 0) //check for any email in Inbox
{
textBox1.Text = textBox1.Text + ("Inbox is empty - Listening for New emails!\r\n");
ScrollBox("Text");
textBox1.Update();
Delay(); //wait 5 seconds
}
CreateFolder(); //Create new destination folder to move processed emails to - NOT FORWARDING TO THIS SUB!!
try
{
foreach (Microsoft.Office.Interop.Outlook.MailItem mailItem in inboxFolder.Items)
{
....processing stuff
}
catch (System.Runtime.InteropServices.COMException ex)
{
....capture error
}
finally
{
....reset stuff
}
}
public void CreateFolder() //Create Outlook Folders to store processed emails = NEVER GETS TO THIS CODE!!!
{
DateTime fldDate = DateTime.Now;
if (fldDate.DayOfWeek != DayOfWeek.Friday) //must process with a Friday date, set date to next Friday
{
fldDate = NextFriday(fldDate);
}
String myYear = fldDate.ToString("yyyy");
string myMonth = fldDate.ToString("MM");
string myDay = fldDate.ToString("dd"); //day of the month
string fileDate = (myYear.ToString()) + "-" + (myMonth.ToString()) + "-" + myDay; // build the Date for Destination "file";
try
{olDestinationFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)]; }
catch
{ olDestinationFolder = ns.Folders[mailBoxName].Folders[("done")].Folders.Add(fileDate); }
try
{ olBadCreditFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders[("BadCredit")]; }
catch
{ olBadCreditFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders.Add("BadCredit"); }
try
{ olNonOrderEmails = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders[("Non-OrderEmails")]; }
catch
{ olNonOrderEmails = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders.Add("Non-OrderEmails"); }
}
private void Delay() //If no emails then want 5 seconds and try again
{
textBox1.Text = textBox1.Text + ("Inbox is empty - Listening for New emails!\r\n");
ScrollBox("Text");
textBox1.Update();
// await Task.Delay(5000); //Wait 5 seconds for new email
var t = Task.Run(async delegate
{
await Task.Delay(TimeSpan.FromSeconds(5.5));
ScrollBox("Text");
return 42;
});
}
static DateTime NextFriday(DateTime fldDate) //Find the next FRIDAY date.
{
do
{
fldDate = fldDate.AddDays(1);
}
while (fldDate.DayOfWeek != DayOfWeek.Friday);
return fldDate;
}
}
}

how to wait c# webbrowser to complete document load in TPL

Hi I have this two blocks of code
when I navigate the browser to a url and try to wait for it I get a deadlock I think=) any help suggestions are much appreciated!
I'm just adding some more text here so I am able to post the question :/ sorry
foreach (var davaType in davaTypes)
{
Parallel.ForEach(years, year =>
{
ts.Add(Task.Run(() =>
{
var th = new Thread(async () =>
{
await doWorkAsync(year, davaType, tarafType);
Application.Run();
});
th.IsBackground = true;
th.SetApartmentState(ApartmentState.STA);
th.Start();
}));
});
}
and
public static async Task doWorkAsync(int year, string davaType, string tarafType)
{
using (var browser = new MyBrowser())
{
Console.WriteLine("Im Created Here");
browser.Navigate("some url");
while (!browser.MyLoaded)
{
Console.WriteLine("waiting");
await Task.Delay(10);
}
Console.WriteLine("complete");
browser.Document?.GetElementById("DropDownList1")?.SetAttribute("value", davaType);
browser.Document.GetElementById("DropDownList3")?.SetAttribute("value", tarafType);
browser.Document.GetElementById("DropDownList4")?.SetAttribute("value", year.ToString());
browser.Document.GetElementById("Button1").MyClick();
await browser.WaitPageLoad(10);
Console.WriteLine("Im DoneHere");
}
}
You can use TaskCompletionSource to create a task and await for it after the page is loaded.
See: UWP WebView await navigate.
I have experienced this problem before and the solution I have applied is as follows;
private void waitTillLoad()
{
WebBrowserReadyState loadStatus = default(WebBrowserReadyState);
int waittime = 100000;
int counter = 0;
while (true)
{
loadStatus = webBrowser1.ReadyState;
Application.DoEvents();
if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
{
break; // TODO: might not be correct. Was : Exit While
}
counter += 1;
}
counter = 0;
while (true)
{
loadStatus = webBrowser1.ReadyState;
Application.DoEvents();
if (loadStatus == WebBrowserReadyState.Complete)
{
break; // TODO: might not be correct. Was : Exit While
}
counter += 1;
}
}
You need to create only one separate thread for WinForms. Other threads will be created by individual browsers themselves. What you do need is handling their DocumentCompleted event. The first time the document completes you enter and submit data, the second time it completes you get the result. When all browsers finish, you exit the winforms thread and you're done.
Note: To launch bots from winforms thread, I made use of Idle event handler, just because it was the first solution that came to my mind. You may find better way.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleBrowsers
{
class Program
{
static void Main(string[] args)
{
string url = "https://your.url.com";
string[] years = { "2001", "2002", "2003"};
string[] davas = { "1", "2", "3" };
string taraf = "1";
int completed = 0, succeeded = 0;
var bots = new List<Bot>();
var started = false;
var startBots = (EventHandler)delegate (object sender, EventArgs b)
{
if (started)
return;
started = true;
foreach (var dava in davas)
foreach (var year in years)
bots.Add(new Bot { Year = year, Dava = dava, Taraf = taraf, Url = url }.Run((bot, result) =>
{
Console.WriteLine($"{result}: {bot.Year}, {bot.Dava}");
succeeded += result ? 1 : 0;
if (++completed == years.Length * davas.Length)
Application.ExitThread();
}));
};
var forms = new Thread((ThreadStart) delegate {
Application.EnableVisualStyles();
Application.Idle += startBots;
Application.Run();
});
forms.SetApartmentState(ApartmentState.STA);
forms.Start();
forms.Join();
Console.WriteLine($"All bots finished, succeeded: {succeeded}, failed:{bots.Count - succeeded}.");
}
}
class Bot
{
public string Url, Dava, Taraf, Year;
public delegate void CompletionCallback(Bot sender, bool result);
WebBrowser browser;
CompletionCallback callback;
bool submitted;
public Bot Run(CompletionCallback callback)
{
this.callback = callback;
browser = new WebBrowser();
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += Browser_DocumentCompleted;
browser.Navigate(Url);
return this;
}
void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
if (submitted)
{
callback(this, true);
return;
}
var ok = SetValue("DropDownList1", Dava);
ok &= SetValue("DropDownList3", Taraf);
ok &= SetValue("DropDownList4", Year);
if (ok)
ok &= Click("Button1");
if (!(submitted = ok))
callback(this, false);
}
}
bool SetValue(string id, string value, string name = "value")
{
var e = browser?.Document?.GetElementById(id);
e?.SetAttribute(name, value);
return e != null;
}
bool Click(string id)
{
var element = browser?.Document?.GetElementById(id);
element?.InvokeMember("click");
return element != null;
}
}
}

Is that logic to reset the Lists and call Init() over again if there was an exception with the download/s?

And how can i report to the user that there was a problem and that it's trying over again ? And should i just do it like i'm doing it now reseting everything and calling Init() again or should i use some timer and wait some seconds before trying again ?
In the class i did:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;
using System.ComponentModel;
namespace TestingDownloads
{
class ExtractImages
{
static WebClient client;
static string htmltoextract;
public static List<string> countriescodes = new List<string>();
public static List<string> countriesnames = new List<string>();
public static List<string> DatesAndTimes = new List<string>();
public static List<string> imagesUrls = new List<string>();
static string firstUrlPart = "http://www.sat24.com/image2.ashx?region=";
static string secondUrlPart = "&time=";
static string thirdUrlPart = "&ir=";
public class ProgressEventArgs : EventArgs
{
public int Percentage { get; set; }
public string StateText { get; set; }
}
public event EventHandler<ProgressEventArgs> ProgressChanged;
public void Init()
{
object obj = null;
int index = 0;
ExtractCountires();
foreach (string cc in countriescodes)
{
// raise event here
ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
index +=1;
}
ImagesLinks();
}
public void ExtractCountires()
{
try
{
htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions;
client = new WebClient();
client.DownloadFile(htmltoextract, #"c:\temp\sat24.html");
client.Dispose();
string tag1 = "<li><a href=\"/en/";
string tag2 = "</a></li>";
string s = System.IO.File.ReadAllText(#"c:\temp\sat24.html");
s = s.Substring(s.IndexOf(tag1));
s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length);
s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries);
string tag3 = "<li><ahref=\"/en/";
for (int i = 0; i < parts.Length; i++)
{
if (i == 17)
{
//break;
}
string l = "";
if (parts[i].Contains(tag3))
l = parts[i].Replace(tag3, "");
string z1 = l.Substring(0, l.IndexOf('"'));
if (z1.Contains("</ul></li><liclass="))
{
z1 = z1.Replace("</ul></li><liclass=", "af");
}
countriescodes.Add(z1);
countriescodes.GroupBy(n => n).Any(c => c.Count() > 1);
string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1);
if (z2.Contains("&"))
{
z2 = z2.Replace("&", " & ");
}
countriesnames.Add(z2);
countriesnames.GroupBy(n => n).Any(c => c.Count() > 1);
}
}
catch (Exception e)
{
if (countriescodes.Count == 0)
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
Init();
}
}
}
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
public class ScriptDate
{
public string DateString { get; set; }
public int Year
{
get
{
return Convert.ToInt32(this.DateString.Substring(0, 4));
}
}
public int Month
{
get
{
return Convert.ToInt32(this.DateString.Substring(4, 2));
}
}
public int Day
{
get
{
return Convert.ToInt32(this.DateString.Substring(6, 2));
}
}
public int Hours
{
get
{
return Convert.ToInt32(this.DateString.Substring(8, 2));
}
}
public int Minutes
{
get
{
return Convert.ToInt32(this.DateString.Substring(10, 2));
}
}
}
public void ImagesLinks()
{
int cnt = 0;
foreach (string countryCode in countriescodes)
{
cnt++;
for (; cnt < DatesAndTimes.Count(); cnt++)
{
string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true";
imagesUrls.Add(imageUrl);
if (cnt % 10 == 0) break;
}
}
}
}
}
In both cases where i'm using try and catch if it's getting to the catch i'm trying over again the whole operation by reseting the Lists and calling Init() again.
Then in form1
ExtractImages ei = new ExtractImages();
public Form1()
{
InitializeComponent();
ProgressBar1.Minimum = 0;
ProgressBar1.Maximum = 100;
backgroundWorker1.RunWorkerAsync();
}
events of backgroundworker
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return; // this will fall to the finally and close everything
}
else
{
ei.ProgressChanged += (senders, eee) => backgroundWorker1.ReportProgress(eee.Percentage, eee.StateText);
ei.Init();
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar1.Value = e.ProgressPercentage;
label7.Text = e.UserState.ToString();
label8.Text = e.ProgressPercentage + "%";
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
ProgressBar1.Value = 100;
}
else
{
}
}
Another thing not sure if it's a problem. When there is no a problem with the class i see in form1 in label7 all the codes running from the first to the last.
But the progressBar1.Value and label8 both are getting only to 97% so i need in the completed event to add the progressBar1.Value = 100; is that fine or there is a problem with the reporting calculation in the class ?
For the 1st question:
Better catch the exception at client side and display the error msg, 'cause you probably need to control your program behavior accrodingly when sth went wrong.
Consider this: if the DOM struct of the page changed, according to you code, your program probably throw expections, with each exception catching, client.DownloadFile is excuted for one time, if this happens, u will need to know what go wrong, and if u donot change ur code behavior, such hi-freq client.DownloadFile excution will cause the firewall of the website block ur ip for a while.
Add a timer at client side is a good idea i think.
For the 2nd one:
did u define how to handle RunWorkerCompleted event?

Altering string array value with radio button

I'm having an issue with altering the value of a string array based on what radio button is selected, it's written in C# using Visual Studio 2013 professional.
Basically all that needs to happen is if the radio button called "smallCarRadBtn" is selected, then the string array call "carSize" has to hold the word "Small", and likewise for the other two radio buttons "medCarRadBtn" and "largeCarRadBtn".
At the moment it is telling me:
"Cannot implicitly convert type 'char' to 'string[]'
I have 'highlighted' the area that contains the code for this with asterisks'*'. Any help would be appreciated.
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.IO;
namespace Assignment2
{
public partial class Form1 : Form
{
TimeSpan daysHiredIn;
DateTime startDate, endDate;
DateTime dateToday = DateTime.Today;
public static string[] names = new string[50];
public static string[] carSize = new string[50];
public static int[] cardNumb = new int[50];
public static int[] cost = new int[50];
public static TimeSpan[] daysHired = new TimeSpan[50];
public static int entryCount = 0, cardNumbIn, carFee = 45, intDaysHired;
public Form1()
{
InitializeComponent();
smallCarRadBtn.Checked = true;
}
private void confirmBtn_Click(object sender, EventArgs e)
{
if (entryCount >= 50)
{
MessageBox.Show("Arrays are Full");//if array is full
}
else if (nameTxtBox.Text == "")
{
MessageBox.Show("You must enter a name");//Nothing entered
}
else if (!int.TryParse(cardNumbTxtBox.Text, out cardNumbIn))
{
MessageBox.Show("You must enter an integer number");
cardNumbTxtBox.SelectAll();
cardNumbTxtBox.Focus();
return;
}
else if (hireStartDatePicker.Value < dateToday)
{
MessageBox.Show("You cannot enter a date earlier than today");
}
else if (hireEndDatePicker.Value < dateToday)
{
MessageBox.Show("You cannot enter a date earlier than today");
}
else
{
*******************************************************************************************
if (smallCarRadBtn.Checked)
{
carSize = ("small"[entryCount]);
}
else if (MedCarRadBtn.Checked)
{
carSize = ("Medium"[entryCount]);
}
else if (largeCarRadBtn.Checked)
{
carSize = ("Large"[entryCount]);
}
*******************************************************************************************
names[entryCount] = nameTxtBox.Text;
cardNumb[entryCount] = cardNumbIn;
endDate = (hireEndDatePicker.Value);
startDate = (hireStartDatePicker.Value);
daysHiredIn = (endDate - startDate);
cost[entryCount] = (carFee * daysHiredIn);
daysHired[entryCount] = daysHiredIn;
entryCount++;
nameTxtBox.SelectAll();
nameTxtBox.Focus();
}
}
private void viewBtn_Click(object sender, EventArgs e)
{
for (entryCount = 0; entryCount < 50; entryCount++)
{
listBox1.Items.Add(names[entryCount]+"\t"+daysHired[entryCount].Days.ToString());
}
}
}
}
carSize is an array of strings but you are trying to assign it a char:
carSize = ("small"[entryCount]);
Here the "small" is a string, and "small"[entryCount] returns the character at the index entryCount
You should change carSize to char[] if you want to stores characters, and set the elements using indexer instead of assigning the array directly. Or if you want to store the text + entryCount then you should concatenate strings:
carSize[index] = "small" + entryCount;
Or if you just want to set carSize[entryCount] then:
carSize[entryCount] = "small";

Scripting in Sound forge

I am completely new to scripting in sound forge. I have a requirement of mixing 2 .wav files.
For example, 1.wav file mix with INVERTED 2.wav file.
I need to get the statistics of the resultant mixed output file.
Statistics like minimum sample value, maximum sample value for all the channels.
Below i have the code to mix 2 .wav files. But the 2nd is not inverted.
Can anyone please help me on the scripting for the above in C#?
Or if anyone can share a document with the standard API's available for sound forge scripting also will be helpful.
using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using SoundForge;
public class EntryPoint
{
public void Begin(IScriptableApp app)
{
//choose the first file.
OpenFileDialog openFile = new OpenFileDialog();
openFile.Title = "Open the input file.";
String inputFilePath = String.Empty;
if (openFile.ShowDialog() == DialogResult.OK)
{
inputFilePath = openFile.FileName.ToString();
}
OpenFileDialog openOutputFile = new OpenFileDialog();
openOutputFile.Title = "Open the output file.";
String outputFilePath = String.Empty;
if (openOutputFile.ShowDialog() == DialogResult.OK)
{
outputFilePath = openOutputFile.FileName.ToString();
}
ISfFileHost backFile = app.OpenFile(outputFilePath, true, false);
ISfFileHost file = app.OpenFile(inputFilePath, false, false);
long fileLen = file.Length;
SfAudioSelection asel = new SfAudioSelection(file);
file.DoMixReplace(SfAudioSelection.All, 1, 1, backFile, new SfAudioSelection(0, file.Length), null, null, EffectOptions.EffectOnly | EffectOptions.WaitForDoneOrCancel);
backFile.Close(CloseOptions.DiscardChanges);
}
public void FromSoundForge(IScriptableApp app)
{
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));
}
public static IScriptableApp ForgeApp = null;
public static void DPF(string sz) { ForgeApp.OutputText(sz); }
public static void DPF(string fmt, params object[] args) {
ForgeApp.OutputText(String.Format(fmt, args)); }
} //EntryPoint
Using the below code the requirement can be achieved.
Requirement was:
1.wav file mix with INVERTED 2.wav file. Get the statistics of the resultant mixed output file.
Statistics like minimum sample value, maximum sample value for all the channels.
using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using SoundForge;
public class EntryPoint
{
public void Begin(IScriptableApp app)
{
string strOutFile = GETARG("outfile", "path to save file at");
if ("" == strOutFile)
{
MessageBox.Show("invald output path");
return;
}
OpenFileDialog openFile = new OpenFileDialog();
openFile.Title = "Open the input file.";
////string to hold the path of input file.
String strFile1 = String.Empty;
if (openFile.ShowDialog() == DialogResult.OK)
{
strFile1 = openFile.FileName.ToString();
}
OpenFileDialog openOutputFile = new OpenFileDialog();
openOutputFile.Title = "Open the output file.";
////string to hold the path of output file.
String strFile2 = String.Empty;
if (openOutputFile.ShowDialog() == DialogResult.OK)
{
strFile2 = openOutputFile.FileName.ToString();
}
ISfFileHost fhOne = app.OpenFile(strFile1, true, true);
if (null == fhOne)
return;
ISfFileHost fhTwo = app.OpenFile(strFile2, true, true);
if (null == fhTwo)
{
fhOne.Close(CloseOptions.DiscardChanges);
return;
}
ISfFileHost fhOut = app.NewFile(fhOne.DataFormat, false);
fhOut.ReplaceAudio(new SfAudioSelection(0, 0), fhOne, new SfAudioSelection(fhOne));
fhOut.DoEffect("Invert/Flip", 0, new SfAudioSelection(fhOut), EffectOptions.EffectOnly);
fhOut.WaitForDoneOrCancel();
fhOut.MixAudio(new SfAudioSelection(fhOut), 1.0, 1.0, fhTwo, new SfAudioSelection(fhTwo));
fhOut.WaitForDoneOrCancel();
fhOut.SaveAs(strOutFile, fhOne.SaveFormat.Guid, "Default Template", RenderOptions.RenderOnly);
fhOut.WaitForDoneOrCancel();
fhOne.Close(CloseOptions.DiscardChanges);
fhTwo.Close(CloseOptions.DiscardChanges);
SfAudioStatistics[] stat = new SfAudioStatistics[fhOut.Channels];
fhOut.UpdateStatistics(SfAudioSelection.All);
stat[0] = fhOut.GetStatistics(0);
stat[1] = fhOut.GetStatistics(1);
stat[2] = fhOut.GetStatistics(2);
stat[3] = fhOut.GetStatistics(3);
stat[4] = fhOut.GetStatistics(4);
stat[5] = fhOut.GetStatistics(5);
stat[6] = fhOut.GetStatistics(6);
stat[7] = fhOut.GetStatistics(7);
MessageBox.Show(String.Format("Max Sample Value Channel 1 - {0},Channel 2 - {1},Channel 3 - {2},Channel 4 - {3},Channel 5 - {4},Channel 6 - {5},Channel 7 - {6},Channel 8 - {7}", stat[0].MaxValue, stat[1].MaxValue, stat[2].MaxValue, stat[3].MaxValue, stat[4].MaxValue, stat[5].MaxValue, stat[6].MaxValue, stat[7].MaxValue));
MessageBox.Show(String.Format("Min Sample Value Channel 1 - {0},Channel 2 - {1},Channel 3 - {2},Channel 4 - {3},Channel 5 - {4},Channel 6 - {5}, Channel 7 - {6}, Channel 8 - {7}", stat[0].MinValue, stat[1].MinValue, stat[2].MinValue, stat[3].MinValue, stat[4].MaxValue, stat[5].MinValue, stat[6].MinValue, stat[7].MinValue));
System.Diagnostics.Process curr = System.Diagnostics.Process.GetCurrentProcess();
}
public void FromSoundForge(IScriptableApp app)
{
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));
}
public static IScriptableApp ForgeApp = null;
public static void DPF(string sz) { ForgeApp.OutputText(sz); }
public static void DPF(string fmt, object o) { ForgeApp.OutputText(String.Format(fmt, o)); }
public static void DPF(string fmt, object o, object o2) { ForgeApp.OutputText(String.Format(fmt, o, o2)); }
public static void DPF(string fmt, object o, object o2, object o3) { ForgeApp.OutputText(String.Format(fmt, o, o2, o3)); }
public static string GETARG(string k, string d) { string val = Script.Args.ValueOf(k); if (val == null || val.Length == 0) val = d; return val; }
public static int GETARG(string k, int d) { string s = Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d; else return Script.Args.AsInt(k); }
public static bool GETARG(string k, bool d) { string s = Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d; else return Script.Args.AsBool(k); }
} //EntryPoint

Categories