|
Here is a block of code that copies a file:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string[] src = e.Argument as string[];
cnt = 0;
while (cnt < src.Length && src[cnt] != null)
{
toolStripStatusLabel1.Text = "Copying " + src[cnt] + "...";
string[] words = src[cnt].Split('\\');
string dest = keeppath2 + "\\" + words[words.Length - 1];
if (dest.IndexOf(".") > -1)
{
FileStream inFile = new FileStream(src[cnt].ToString(), System.IO.FileMode.Open);
if (!System.IO.File.Exists(dest))
{
using (System.IO.FileStream fs = System.IO.File.Create(dest))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
}
FileStream outFile = new FileStream(dest, System.IO.FileMode.Open);
long size = inFile.Length;
int lineSize = 1024 * 64;
long filesize1 = inFile.Position / 1024;
long filesize2 = inFile.Length / 1024;
byte[] buffer = new byte[lineSize];
while ((inFile.Read(buffer, 0, lineSize)) > 0)
{
outFile.Write(buffer, 0, lineSize);
filesize1 = inFile.Position / 1024;
toolStripStatusLabel1.Text = "Copying " + src[cnt] + "... " + filesize1 + "KB of " + filesize2 + "KB";
}
outFile.Flush();
outFile.Close();
inFile.Flush();
inFile.Close();
}
else
{
try
{
copyDirectory(src[cnt].ToString(), dest, toolStripStatusLabel1);
}
catch (Exception error)
{
}
}
cnt++;
}
}
Every once in a while I get this error when copying:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Windows.Forms.ToolStripItem.get_ContentRectangle()
at System.Windows.Forms.ToolStripSystemRenderer.RenderLabelInternal(ToolStripItemRenderEventArgs e)
at System.Windows.Forms.ToolStripSystemRenderer.OnRenderToolStripStatusLabelBackground(ToolStripItemRenderEventArgs e)
at System.Windows.Forms.ToolStripRenderer.DrawToolStripStatusLabelBackground(ToolStripItemRenderEventArgs e)
at System.Windows.Forms.ToolStripStatusLabel.OnPaint(PaintEventArgs e)
at System.Windows.Forms.ToolStripItem.HandlePaint(PaintEventArgs e)
at System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.StatusStrip.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
Filemon
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
Does anyone know how to avoid this error?
I will also occasionally get this error:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.ArrayList.get_Item(Int32 index)
at System.Windows.Forms.ToolStripItemCollection.get_Item(Int32 index)
at System.Windows.Forms.ToolStrip.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.StatusStrip.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
Filemon
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
CodeBase: file:----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
Thanks for looking
|
|
|
|
|
Hi,
I see two errors:
1.
your DoWork() method contains accesses to toolStripStatusLabel1.Text which it shouldn't. AFAIK (documentation doesn't contain this) all GUI parts, not just Controls, are untouchable by another than the main thread. You could read this[^] for more; I believe ToopStrip parts need the same approach; however they don't offer InvokeRequired/Invoke, so you would have to borrow another Control on the same Form (or the Form itself).
This would be sufficient to explain most erratic behavior your app may show, especially regarding the GUI. It probably is sufficient to cause the problem you're having, however only fixing and testing will tell.
2.
in while ((inFile.Read(buffer, 0, lineSize)) > 0) the Read method returns the number of bytes read, which you test for non-zero, but you don't otherwise use it; you really should store the value in a variable and use that instead of linesize in outFile.Write(buffer, 0, lineSize); as the value may be different, especially at the end of the file.
I also have several comments:
3.
I think a foreach would be much more elegant than while (cnt < src.Length && src[cnt] != null)
4.
when the destination file does not exist, you create a dummy one first; I see no use for that.
5.
you are reporting progress inside your copy loop; that will probably slow down the operation npticeably; I suggest you display the sizes in MB, not KB, and only update the GUI when the number has changed.
6.
you have some Flush-and-Close sequences; they don't make much sense, Close() implies Flush().
7.
you don't create the destination folder; if it does not exist, your app will fail copying files to it. A simple Directory.Create() would do, no need to test for existence. You must calculate the path though. The Path class has methods for that.
8.
I saw an empty catch block; that is a very bad idea as it hides potential problems. You should only catch what you can handle (i.e. solve) and leave the rest to the caller; alternatively, you should log the problem, but never let it disappear without treatment.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Wow, thanks for the advice! This is my first c# program. I implemented your fix for the second problem but you are telling me that I cannot alter a status label from another thread at all? How would I show copy progress, with a messagebox instead?
|
|
|
|
|
A MessageBox would work, but I dislike it. It is ugly, and very limited.
The link I provided explains about threads and Controls, using Invoke. IMO that is what you need.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Okay, I have this in my backgroundworker now:
labeltext = "Copying " + src[cnt] + "... " + filesize1 + "KB of " + filesize2 + "KB";
SetText(statusStrip1, labeltext);
and then this later on:
public delegate void ControlStringConsumer(Control control, string text);
public void SetText(Control control, string text)
{
if (control.InvokeRequired)
{
control.Invoke(new ControlStringConsumer(SetText), new object[] { control, text });
}
else
{
control.Text = text;
}
}
I have to pass a control to invoke it, how do I access toolstripstatuslabel1.text this way?
|
|
|
|
|
As I said in other post, you don't have to work with Invoke/BeginInvoke directly when using BackgroundWorker . Do all the UI update in the ProgressChanged event handler. MSDN[^] has a neat example on how to use BackgroundWorker class.
Best wishes,
Navaneeth
|
|
|
|
|
OK, pass some Control on your Form, or the Form itself.
And change the "functional part" to directly set the GUI part you need, assuming it is always the same.
BTW: Navaneeth's approach is valid too, it is probably easier than mine for BackgroundWorker stuff; it does not exist for general Threads though.
Suggestion: Use the ReportProgress() overload with a userState parameter to pass the string you want displayed.
PS: once you got it working, make sure to apply my original remark (5) for performance.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
You need to delegate that to ProgressChanged event handler by calling worker.ReportProgress() from DoWork . This event handler will be executed on the main thread and you can access controls without any issues.
Best wishes,
Navaneeth
|
|
|
|
|
Ok here is my dowork:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string[] src = e.Argument as string[];
cnt = 0;
while (cnt < src.Length && src[cnt] != null)
{
toolStripStatusLabel1.Text = "Copying " + src[cnt] + "...";
string[] words = src[cnt].Split('\\');
string dest = keeppath2 + "\\" + words[words.Length - 1];
if (dest.IndexOf(".") > -1)
{
FileStream inFile = new FileStream(src[cnt].ToString(), System.IO.FileMode.Open);
if (!System.IO.File.Exists(dest))
{
using (System.IO.FileStream fs = System.IO.File.Create(dest))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
}
FileStream outFile = new FileStream(dest, System.IO.FileMode.Open);
long size = inFile.Length;
int lineSize = 1024 * 64;
long filesize1 = inFile.Position / 1024;
long filesize2 = inFile.Length / 1024;
byte[] buffer = new byte[lineSize];
while ((inFile.Read(buffer, 0, lineSize)) > 0)
{
outFile.Write(buffer, 0, lineSize);
filesize1 = inFile.Position / 1024;
labeltext = "Copying " + src[cnt] + "... " + filesize1 + "KB of " + filesize2 + "KB";
backgroundWorker1.ReportProgress(0);
}
outFile.Close();
inFile.Close();
}
else
{
copyDirectory(src[cnt].ToString(), dest, toolStripStatusLabel1);
}
cnt++;
}
}
I handed off the toolstripstatuslabel1.text to backgroundWorker1.ReportProgress
here is the code:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
toolStripStatusLabel1.Text = labeltext;
}
This works like a dream for files. The problem is when I call copyDirectory when I am copying a directory.
I can't call reportprogress from that and need to update the statuslabel which bombs. Here is the code for copyDirectory:
public static void copyDirectory(string Src, string Dst, ToolStripStatusLabel tool)
{
String[] Files;
long filesize1 = 0;
long filesize2 = 0;
if (Dst[Dst.Length - 1] != Path.DirectorySeparatorChar)
{
Dst += Path.DirectorySeparatorChar;
}
if (!Directory.Exists(Dst))
{
Directory.CreateDirectory(Dst);
}
Files = Directory.GetFileSystemEntries(Src);
foreach (string Element in Files)
{
if (Directory.Exists(Element))
{
copyDirectory(Element, Dst + Path.GetFileName(Element), tool);
}
else
{
FileStream inFile = new FileStream(Element, System.IO.FileMode.Open);
if (inFile != null)
{
if (!System.IO.File.Exists(Dst + Path.GetFileName(Element)))
{
using (System.IO.FileStream fs = System.IO.File.Create(Dst + Path.GetFileName(Element)))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
}
FileStream outFile = new FileStream(Dst + Path.GetFileName(Element), System.IO.FileMode.Open);
long size = inFile.Length;
int lineSize = 1024 * 64;
filesize2 = inFile.Length / 1024;
byte[] buffer = new byte[lineSize];
while ((inFile.Read(buffer, 0, lineSize)) > 0)
{
outFile.Write(buffer, 0, lineSize);
filesize1 = inFile.Position / 1024;
tool.Text = "Copying " + Element + "... " + filesize1 + "KB of " + filesize2 + "KB";
}
outFile.Close();
inFile.Close();
}
}
}
}
What is the best way to update the label from copyDirectory?
Thanks for all the help!
|
|
|
|
|
I'm not sure why I'm getting this error. First I created an enum in my static main class:
public enum ItemTypes
{
None,
Root,
Clients
}
Then I created a class that refers to it:
public class csNodeInfo
{
private csWorkITApp.ItemTypes _ItemType = csWorkITApp.ItemTypes.None;
public csWorkITApp.ItemTypes ItemType
{
get { return _ItemType; }
set { _ItemType = value; }
}
private DataAccess.AppDataAccess _DataRecord = null;
public DataAccess.AppDataAccess DataRecord
{
get { return _DataRecord; }
set { _DataRecord = value; }
}
}
It's erroring on
public csWorkITApp.ItemTypes ItemType saying
"Inconsistent accessibility: property type '...csWorkITApp.ItemTypes' is less accessible than property '...csNodeInfo.ItemType'"
Anyone?
Everything makes sense in someone's mind
|
|
|
|
|
Is the enum declared w/in the declaration for the static class?
If so moving the enum declaration outside of the class declaration will probably fix your problem.
|
|
|
|
|
It's monday....
The main class was not public
Everything makes sense in someone's mind
|
|
|
|
|
yup. The program.cs file Visual creates for you has a static class without explicit scope, making it less than public. Either add public to that class, or move your enum out of there.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Background
I have an old program that I wrote a few years ago in C#. I no longer have the source code. I have a dialog box in the program that I want to add a button to. All the button will do is launch a program. I've used Resource Hacker to add the button, but how would I go about basically adding a listener to it?
There are two ways I can think to do this:
1. Intercept Win32 messages using a separate program and wait for the WM_COMMAND for that specific button to come up. The program with this is that I don't know enough about API calls to do this on my own in a reasonable amount of time (and I'm guessing I'd have to dive into some C++).
2. Inject code into the existing executable. I've seen examples of how to inject code at the starting point of an executable, but nothing that comes close to being a 'listener' for a button.
I'm thinking unless someone has an easy way of accomplishing number 2, intercepting the messages will be the way to go. So... How on earth would I accomplish this? Using Spy++, I have found the call that I would like to intercept:
004103C8 S WM_COMMAND wNotifyCode:BN_CLICKED wID:12345 hwndCtl:00450346 [wParam:00003039 lParam:00450346]
I've seen code samples for all kinds of hooks, but I can't seem to find one that will grab this.
The question:
Does anyone know of some code that demonstrates how to catch a WM_COMMAND from an external application? If not, how should I go about implementing this strategy?
|
|
|
|
|
Hi,
here is what I would try:
1.
create a new program "B" that will "replace" your existing one ("A").
it is a WinForm app however it remains windowless most of the time (just showing a NotifyIcon probably),
it does three things:
2.
launch "A"
3.
periodically check the child windows of B for the specific dialog, based on some characteristic (easiest is window text); when the dialog appears, show a little, borderless window containing one button, and positioning all of that in the right location.
4.
exit when "A" exits.
None of this relies on explicit window messages; it does take some P/Invoke to enumerate ChildWindows, GetWindowText and GetWindowPosition.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Hi, Everbodys.
i am writing a code that is about calculating shortest paths in feed forward neural network
i have like the following code with neural structure
in code: nron=6 and lay=6;
class neuron
{
public int[] nextconnect = new int[nron];
public int[] preconnect = new int[nron];
public int number;
public int dents;//dentrit count
public int nextid,preid; // next and pre connections counts
~neuron() { }
}
class layer {
public neuron[] noron = new neuron[nron];
public layer()
{
for (int index = 0; index < noron.Length; index++)
{
noron[index] = new neuron();
}
}
~layer(){}
}
class net {
public double lr;//learning rate;
public int ban, hen;
public layer[] layers = new layer[lay];
public net()
{
for (int index = 0; index < layers.Length; index++)
{
layers[index] = new layer();
}
}
~net(){}
}
net network;
i have prepared using feed forward connection structure but i didn't development a algorithm that has strong code
can u help me as algorithm or code ?
regards.
|
|
|
|
|
I think I have figured out why some messages are not working on my ticket system application. It seems to be when a user does the shift+enter. Basically if the message they send is over 100 characters I trim it down to 100. When a user types a message in a textbox on the submit form page and use a shift+enter it causes it to fail.
How would I remove this? Because it appears as nothing like that is in the subject field, but thats not the case.
|
|
|
|
|
Handle keydown event. Check whether shift key is pressed while pressing enter and do accordingly.
|
|
|
|
|
Here is the weird thing.
The user submits a ticket via the web. It works fine there with the multiline textbox. Subject goes through and everything.
Here is on the web side of things:
string Sub;
if (txtProblem.Text.Length > 100) Sub = "** NEW ** " + txtProblem.Text.Substring(0, 100) + "...";
else Sub = "** NEW ** " + txtProblem.Text;
mm.Subject = Sub.Replace('\r', ' ').Replace('\n', ' ');
Ahh crap... I wasn't doing the replace on the windows form side of things. Because I passed the value from my listview to the update form (differnet forms) and place it in the textbox. I guess the textbox will take the character on a singleline textbox but the subject won't..
I put the replace on the windows side of things and it works good now!
Sorry to bother you
|
|
|
|
|
Jacob Dixon wrote: Sorry to bother you
No problem at all..
Cheers.
|
|
|
|
|
I'm trying to figure out if there's a way to set the enable and disable for the main form's ToolStripMenuItem. I'm processing UDP packets inside of a thread and when I receive a specific packet I want to allow a previously disabled item to become enabled. I am able to do this with buttons, but I don't know if I can with toolstrip items.
For example, to do what I want with a button from my thread I can use the following line:
this.bSendButton.Invoke(new MethodInvoker(delegate { this.bSendButton.Enabled = true; }));
There is no invoke function associated with the toolstrip item, so that previous way does not work. Is there another way I can do this? Am I trying to do this the completely wrong way? Any input would be helpful.
|
|
|
|
|
Hi,
I'm aware there are some GUI parts that aren't Controls, and hence don't have InvokeRequired and Invoke().
Although I did search a lot at some time, I haven't found any official stance.
I think it is OK to use a real Control instead of the non-Control part for calling InvokeRequired and Invoke(), provided those parts really got created by the same thread the Controls are. In the end, you probably could use the Form itself for all of them. After all, all the object is used for is determining the right thread for executing the delegate.
I haven't checked this yet, it is on my TODO list though.
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
I am wanting to (in real time) play a mp3 or wav file (can be played from an external source (windows media player plug-in) and interpret the data so that I can do various tasks if it detects certain pitches, frequencies etc...
I have seen many sound API like lame and audiere, these seem to just allow me to load in the songs and call play on them, this is not useful, because I actually need to see the stream data of the song
I have also looked into RIFF parsers, this seems to be more along the lines of what I want, but I guess I would like some more direction as to if there is a better API out there for what I am looking for
So to recap:
Language doesn't really matter I can do C, C++, C#, java, DirectX
I am using a windows machine, also can boot linux
I want to be able to look at the audio data of a file ( format doesn't matter can be .mp3, WAV, AIFF w/e I can convert the music files into whatever) and determine when a certain triggers (frequency, amp etc) take place in a song and have my application react accordingly
|
|
|
|
|
I would like to start a second form relative to the first form.
frmMain is the first form,
frmView2 is the second form being opened by frmMain:
frmView2 FView2 = new frmView2();
FView2.Show();
In frmView2 I have:
this.Location = windowpoint;
How do I properly pass a Point from frmMain to frmView2?
Thank you
|
|
|
|
|
You have to set the starting location ( there's a property, and I forget it, sorry ), before you show it. You can set it to center screen, center parent, or you can set it to manual, and then setting the position will work.
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|