snarfblam
Leaders-
Posts
2156 -
Joined
-
Last visited
-
Days Won
2
Content Type
Profiles
Forums
Blogs
Events
Articles
Resources
Downloads
Gallery
Everything posted by snarfblam
-
Have you tried PD's suggestion? Something like this should work: [color="Green"]// Event args to hold data for event [/color]class ProgressEventArgs : Event Args { public float Progress {get; set; } } [color="Green"]// This class raises the event that will cause your form to be updated [/color]class BackgroundOperation { [color="Green"] // This event will be handled by the form [/color] public event EventHandler<ProgressEventArgs> ProgressChanged; [color="Green"] // other stuff[/color] private void UpdateProgress(float percent){ [color="Green"] // Cache event delegate to avoid subtle threading issues[/color] var eventDelegate = ProgressChanged; if(eventDelegate != null) { [color="Green"]// If there are any registered handlers (i.e. your form)...[/color] var args = new ProgressEventArgs(); [color="Green"]// Create event data[/color] args.Progress = percent; eventDelegate(this, args);[color="Green"] // Raise event[/color] } } } [color="Green"]// Your form class handles the ProgressChanged event and updates the progress bar[/color] class FormOrOtherUIClass : Whatever { [color="Green"]// Add the event handler where you create the worker[/color] public void CreateWorker() { [color="Green"]// ...create worker...[/color] worker.ProgressChanged += Worker_ProgressChanged; [color="Green"]// remember this event handler will need to be unregistered when[/color] [color="Green"]// you're done with the worker.[/color] } [color="Green"] // Handles the ProgressChanged event of the worker [/color] void Worker_ProgressChanged(object Sendor, ProgressEventArgs e){ UpdateProgressBar(e.Progress); } [color="Green"] // This function updates the progress bar. If we call it from the wrong thread, // it just re-routes it to the correct thread. [/color] void UpdateProgressBar(float percent) { if(InvokeRequired) [color="Green"]// (if wrong thread)[/color] [color="Green"]// Call this same function on the main thread.[/color] this.Invoke(new Action<float>(UpdateProgressBar), percent); else {[color="Green"] // (if correct thread)[/color] [color="Green"] // Caluclate progress bar value[/color] int newValue = (int)(percent / 100 * ProgressBar1.Maximum); [color="Green"]// Clamp value to be safe[/color] newValue = Math.Min(newValue, ProgressBar1.Maximum); [color="Green"]// Update progress bar[/color] progressBar1.Value = newValue; } } } Hope you're using C#. Also keep in mind that this code is not tested. It's just to demonstrate the concepts involved. The most important bit is the UpdateProgressBar function which makes sure that the UI is updated on the correct thread.
-
Where are you getting stuck? On how to access the UI from a background thread?
-
Well, what exactly is supposed to happen when the transactions timeout? The deadlock is the result of (infinite) recursion of your own locks. Both threads have frozen and are not running code, and there is no way for a TransactionAbortedException to be thrown. Are you trying to simulate an actual problem you ran into?
-
A select case works great when you need to make a decision based on a string or numeric value, but it doesn't work as well for most other types, such as controls. You can do a select case with the control's Name property, but that doesn't offer any advantage over an if statement. You can use a single event handler, but you need to identify which menu item raised the event and act based on that. For example, the two code listings will produce the same results: Private Sub MenuStrip1_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip1.ItemClicked [color="Blue"]If e.ClickedItem Is menuItem1 Then[/color] Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBoxB, text) [color="Blue"]ElseIf e.ClickedItem Is menuItem2 Then[/color] Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBoxB, text) End If End Sub Private Sub munuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) [color="Blue"]Handles munuItem1.Click[/color] Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBoxB, text) End Sub Private Sub menuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) [color="Blue"]Handles menuItem2.Click[/color] Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBoxB, text) End Sub I don't see any compelling reason to choose one over another. I personally would prefer the second one because I'd rather separate the code for different controls into different functions, but that's mostly a matter of taste.
-
This code has one major problem: Public Class optyTextBox Inherits System.Windows.Forms.TextBox Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Const WM_PASTE As Int32 = &H302 Select Case m.Msg Case WM_PASTE ' The clipboard contents were pasted... 'Code to handle paste event. End Select End Sub [color="Red"] MyBase.Wndproc(m)[/color] End Class When you override a method like this it means that the base method wont be called. Yours will be called instead. If you need the base method to be called, you must do this explicitly in your overriding method. In the case of WndProc, when you don't call the base method, the TextBox will not recieve any messages.
-
I'm not clear on exactly what the code is doing or how the app works. First of all, are the menu items and group boxes predefined, or are they created dynamically at runtime? If they are predefined it would probably make more sense to have a separate event handler for each menu item's Click event. Also, you haven't really explained how the code is not working when you use the Select Case. I'm guessing the problem is partly related to this code: Dim Group As New GroupBox Select Case Group.Name You are creating a new group box every time you run this code. It looks like you want to access an existing group box. How you access the group box will again depend on whether they are generated dynamically or predefined. I think it would help you a lot to work this sort of issue by starting with some pseudo-code. In this case, what you want will probably be along the lines of: Sub ContextMenuItem[color="Red"]A[/color]_Click(parameters) Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBox[color="Red"]A[/color], text) End Sub Sub ContextMenuItem[color="Red"]B[/color]_Click(parameters) Dim text As String = Me.ListView1.SelectedItems(0) Me.ListView1.Items.Remove(Me.ListView1.SelectedItems(0)) AddItemToGroupBox(GroupBox[color="Red"]B[/color], text) End Sub Sub AddItemToGroupBox(group As GroupBox, text As String) For Each C As Control In group If TypeOf C Is TextBox And String.IsNullOrEmpty(C.Text) Then C.Text = text Return End If Next End Sub Here each menu item has its own event handler, which removes the item from the listview and calls a sub that will add the text to the first empty textbox in the specified group box. Hope that helps.
-
Hmmm.... one suggestion I saw was to use the marquee style progress bar. Basically, if the progress increases too fast the control's animation won't keep up, especially if the UI thread is busy, and the end result is that it looks like the operation doesn't complete. If the operation happens quickly enough for you to run into the problem then the marquee style would probably work well. The animation will make it obvious to the user that the app is doing something and whatever you are doing will probably complete fast enough that the user won't find himself, in the absence of an actual progress update, wondering just how long he will have to wait. Edit: found this article with a couple of suggestions in the comments.
-
I think you may be talking to a robot. The profile is a bit of a giveaway... We've been getting alot of these lately. Funny thing is that they aren't posting spam. I'll never understand the mind of a robot.
-
Just a thought: are you calling Update (...or is it Refresh? hmm...) on the control in question? Using multi-threading does feel like overkill for a simple progress bar, but in an ideal world any and all long running tasks would be run in a thread other than the UI thread.
-
Getting the Clipboard paste change event in VB.NET
snarfblam replied to caeanis's topic in Windows Forms
I don't have any experince with this, but a couple of google searches turned up these: Clipboard copy/paste detection Easy Way Detect Changes On The Clipboard With Windows API -
Did you copy and paste that code? Because from what I can see you have (integer) = (integer) + (integer), and there is no reason that it should be treated like a string. If you are using a string constant for your "1" or start is declared as an object or string, then this behavior might make sense.
-
This code seems to work as far as keeping the edge on-screen: private void MenuTimer_Tick(object sender, EventArgs e) { const int distanceOnScreen = 1; [color="Green"]// Possible problem. Try 4.[/color] int finalPosition = Screen.PrimaryScreen.Bounds.Top - this.Height + distanceOnScreen; if (this.InstantMenu) { if (this.Top > finalPosition) { this.Top -= 1; } else { this.MenuMotionOn(false, true); } } else { if (this.Top > finalPosition) { this.Top -= 1; } else { this.MenuMotionOn(false, true); } } } One problem here is that you are showing your form in the MouseEnter event. This event is raised when the mouse enters the client region, which does not include the borders or title bar. You either need to leave more of the form on the screen (see the comment in the code) or get rid of the border (or detect the mouse another way).
-
Sorry, I guess I didn't read it well enough. Here is what seems to be the problem: I didn't realize that the Control.DoDragDrop method blocks the main thread until the drag and drop operation is complete. This is the corrected code for TryBeginDrag: Private Sub TryBeginDrag(ByVal source As ListBox) If source.SelectedIndex >= 0 Then [color="Red"]dragSource = source[/color] [color="Green"]' moved[/color] [color="Green"] ' This method blocks the main thread[/color] source.DoDragDrop(source.SelectedItem.ToString, DragDropEffects.Copy Or DragDropEffects.Move) End If End Sub dragSource needs to be set before calling DoDragDrop. Otherwise it won't get set until after the DragEnter and DragDrop events are raised. I guess I didn't realize that it worked that way because I'm not familiar with DotNet's drag and drop system. I don't use it because it just seems aweful (probably because it just wraps the Windows drag and drop system, which is, presumably, aweful).
-
My mistake. destination.Items.Add([color="Red"]e.[/color]Data.GetData(DataFormats.Text).ToString) [/Code] Should be [Code] destination.Items.Add(Data.GetData(DataFormats.Text).ToString) [/Code]
-
When the drag operation starts, you can store a reference to the control that started the operation. That way you don't have to go looking for it later on. Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown If ListBox1.SelectedIndex < 0 Then Return ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move) End Sub becomes... [color="Blue"]Dim dragSource As ListBox[/color] Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown If ListBox1.SelectedIndex < 0 Then Return ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move) [color="Green"]'Remember what control the data came from.[/color] [color="Blue"]dragSource = ListBox1[/color] End Sub But why not generalize it a bit more? [color="Blue"]Dim dragSource As ListBox[/color] Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown [color="Blue"]TryBeginDrag(ListBox1)[/color] End Sub [color="Green"]'We can use this sub for any ListBox we want to drag data from[/color] [color="Blue"]Private Sub TryBeginDrag(source As ListBox) If source.SelectedIndex >= 0 Then source.DoDragDrop(source.SelectedItem.ToString, DragDropEffects.Copy Or DragDropEffects.Move) dragSource = source End If End Sub[/color] Now when we drag and drop to another control, we already know exactly where to remove the string from. Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop If ListBox2.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then ListBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString) [color="Blue"] dragSource.Items.Remove(dragSource.SelectedItem)[/color] End If End Sub Again, we can generalize: Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop [color="Blue"] TryDrop(ListBox2, e.Data)[/color] End Sub [color="Blue"] Private Sub TryDrop(destination As ListBox, data As IDataObject) [color="Green"] 'I find it easier to read my code if I evaluate a large expression outside 'the if statement and give it a name.[/color] Dim destContainsData As Boolean = destination.FindStringExact(data.GetData(DataFormats.Text).ToString()) <> -1 If Not destContainsData Then destination.Items.Add(Data.GetData(DataFormats.Text).ToString) dragSource.Items.Remove(dragSource.SelectedItem) End If End Sub [/color] I haven't tested this code and my VB is a bit rusty, but at the very least you should get the idea. Hope it helps.
-
You should probably post the actual code you are using so it is easier to see where the problem is. I don't see any references to ListBox3 in what you've got there.
-
My understanding is that OpenOffice supports COM interop and it is, of course, free. It may not be the solution that you are looking for, but it is worth investigating.
-
You list the steps for drawing a colored line as:
-
Maybe check the security tab on the process properties for the two processes (in process explorer) and see if it is a permissions issue?
-
Just curious, what user is the process running under? Maybe there is something about the process that you can see in ProcExp that can explain why you can't terminate it.
-
If you look at the call stack (enable "Show External Code"), in what method is the exception being thrown? Or maybe just copy/paste the call stack. I don't know if the error is related to a file cacheing issue or what, but that kind of info can help.
- 3 replies
-
- 0x80070002
- documenttext
-
(and 2 more)
Tagged with:
-
And what is happening when you try to kill it? Do you get a message box? Or does the process just not disappear? There are some background processes which use a "guardian process" (or the program's front-end) that will restart the background process immediately after it is terminated, such as certain viruses, google updater, or zunebusenum for Microsoft's Zune. I personally find this behavior to be completely unacceptable under any situation on a personal computer at any time ever. If a user tries to terminate a process, it must end. Who's in charge of who? It might seem benign in certain cases, but it undermines a users authority over his own machine. I will go to any length to stop a process that I don't want running. It might seem appropriate to ensure that certain processes are running, say, on an employees computer, but I completely disagree. If there is a process that must be running on an employees computer, the process should phone home so that the main office knows that it is running, and it should have an obvious presence on the computer. If you need to outsmart employees, you're in a worse situation than you realize. So who is going to be using your software?
-
I'll kindly direct your attention over here.
-
You most-certainly can create custom attributes (Creating and Using Custom Attributes with VB.NET), but they can not execute any code. They are not even instantiated until you explicitly retrieve the attribute at runtime. You can create your own post-build process that does reflection on the compiled code and reports problems (or a pre-build process that examines the original code). Or maybe a script or an add-on... I don't know.
-
Re: exam scheduling system FYI, The thread you posted in is five years old and the most recent post by either of the users there is three years ago. Please check the dates. I don't know what, specifically, you are looking to learn. The thread addresses scheduling, data grids, and generic algorithms. None of these are my cup of tea, so I probably can't help you, but if you make your question more specific it becomes much easier to answer.