> Hello All. Im having lots of fun with window handles
> and invoke.
Welcome to the imposter.
> The code started off in a single class. Main thread set
> up a worker thread and the worker thread updated . . .
Welcome to the imposter.
> First problem was with beginInvoke. An exception
> was being generated saying that "Invoke or . . "
Welcome to the imposter.
> Any Gurus able to point me in the right direction.
Yes. Have a look for newsgroups that deal with the imposter. This group is
for the *real* Visual Basic.
Mike
Steve Gerrard - 09 Dec 2007 23:26 GMT
As Mike said (cryptically), this should be in a .Net newsgroup, so leave off the
microsoft.public.vb.general.discussion.
You need to understand forms and classes and instances better before you tackle
worker threads. You should probably change your worker class to work within the
same thread first, and get the form reference all squared away, before doing a
worker thread and invoking a method in the main thread.
> ' I think this may actually be creating the handle, which may
> not exist otherwise.
> winhandle = ProgressBar1.Handle
> Dim worker_obj As New worker_class(Me)
Creating a new instance of a form does *not* load it, and therefore does *not*
create the windows, or handles to those windows. Only when the form loads are
those available. You are forcing the form to load in the constructor, which is
daft. You think you need this because your attempt at invoking a method is
creating a second instance of Form1, which otherwise never gets loaded. See
below.
> Dim worker_obj As New worker_class(Me)
Okay, your worker_obj instance of class worker_class gets passed a reference to
the actual instance of the calling form.
> Public Class worker_class....
> Public form_reference As Form
Why is form_reference of class Form, not class Form1? And why is it Public?
> Public Sub New(ByVal form_ref)
> form_reference = form_ref
> End Sub
Okay, that will store a reference to the calling form, when an instance of
worker_class is created. It would be smarter to specify the type, not leave it
as Object.
Now that you have it, it seems like it would make sense to use form_reference
somewhere in your worker_class code, don't you think?
> result = Form1.ProgressBar1.BeginInvoke(New
Having just saved a reference to the actual form instance, why are you now
referring to Form1? Form1 is a class name. It can also be a default instance
name, but often not the instance you want. The above line is triggering the
creation of a new (second) instance of Form1, not referring to the already
loaded instance that called this method.
Can you guess what you should put instead of Form1 in the line above?
MikeD - 10 Dec 2007 00:50 GMT
>> Hello All. Im having lots of fun with window handles
>> and invoke.
[quoted text clipped - 15 lines]
> Yes. Have a look for newsgroups that deal with the imposter. This group is
> for the *real* Visual Basic.
And he probably has no clue at all what you're talking about. <g>
To the OP, you cross-posted to both VB classic (VB6 and under) and .NET
newsgroups. Don't do this.

Signature
Mike
Microsoft MVP Visual Basic
> [...]
> First problem was with beginInvoke. An exception was being generated
[quoted text clipped - 5 lines]
> winhandle = ProgressBar1.Handle
> This solved this problem. Though Im not sure whats going on.
Yes, retrieving the handle forces it to be created. However, it would be
better to just either not start whatever processing might call
BeginInvoke() until the form has been loaded and/or shown (see FormLoad
and FormShown events). Alternatively, the processing code calling
BeginInvoke() should just check the IsHandleCreated property before trying
to invoke and not bother if the control hasn't been fully initialized yet.
The way you're doing it now, you allow some update to be invoked on the
progress bar before the form is really completely initialized. By forcing
the progress bar itself to be initialized enough, you may avoid problems.
But there's no guarantee of that, and it could easily lead to a subtle,
hard to find bug later.
> Now Im on the next problem. When BeginInvoke is called as in
> " result = Form1.ProgressBar1.BeginInvoke(New
[quoted text clipped - 6 lines]
> effort to see if the form1 object is being removed. And ive passed the
> form1 to the second class in its constructor. All to no avail.
Do you have an example of the code that generates that behavior? The code
you posted is the version with the static/shared ProgressBar instance.
One thing I notice is that BeginInvoke() takes as the second parameter an
array, not a single value. I'm not that familiar with the VB syntax, and
if you're sure your code is correct then I'll take your word for it. But
what I expected to see there is you created a new Object() array with one
element, set to the value of 25 (which will wind up boxed, being a value
type).
If you have that parameter wrong, in C# you just wouldn't be able to
compile the code. But in VB maybe it compiles but then causes some weird
error.
The other thing I notice is that it _looks_ like you are calling an
instance method in your Form1 class (UpdateProgressDisplay), but using the
synax for a static/shared method. Again, not being that familiar with VB
syntax maybe I'm wrong, but I thought you'd have a "Shared" in the method
declaration if it were a static method. If it _is_ an instance method,
then maybe VB is creating a new dummy instance for you when you call
BeginInvoke(), since you didn't provide an instance.
Again, in C# you just wouldn't be able to do that. But maybe in VB it's
doing something on your behalf (scary, but possible).
Finally, you should look at the BackgroundWorker class. At least for this
simple kind of processing you've got here, it's exactly the right thing to
use. It has a ProgressChanged event that the Form1 class can subscribe
to, as well as a RunWorkerCompleted event. Both of these events will be
raised on the form instance's thread, eliminating any need for you to mess
with BeginInvoke() at all. It would eliminate the issues you've described
here.
For RunWorkerCompleted, it's raised automatically for you when your DoWork
handler returns. For the ProgressChanged event, your worker thread code
will need to call the ReportProgress() method any time you want the event
raised.
Pete
Jim Mack - 10 Dec 2007 01:38 GMT
Please trim the group 'microsoft.public.vb.general.discussion' from
any replies you make to this thread
It's inappropriate for that group.
Thanks.
dgleeson3@eircom.net - 10 Dec 2007 11:24 GMT
Hi Guys
Thanks for the input. Appologies to the VB6'rs
Pete responses below.
On Dec 9, 11:39 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> > [...]
> > First problem was with beginInvoke. An exception was being generated
[quoted text clipped - 18 lines]
> But there's no guarantee of that, and it could easily lead to a subtle,
> hard to find bug later.
So the worker thread is not setup until the user can press the button
on the form.
Long after form load. But Im now checking with IsHandleCreated. Very
strange!
> > Now Im on the next problem. When BeginInvoke is called as in
> > " result = Form1.ProgressBar1.BeginInvoke(New
[quoted text clipped - 16 lines]
> element, set to the value of 25 (which will wind up boxed, being a value
> type).
Ok Ive modified this setting up an array. No change in operation with
my problem.VB was
helping me on this.
> If you have that parameter wrong, in C# you just wouldn't be able to
> compile the code. But in VB maybe it compiles but then causes some weird
[quoted text clipped - 7 lines]
> then maybe VB is creating a new dummy instance for you when you call
> BeginInvoke(), since you didn't provide an instance.
Nice one.
This appears to be the problem.
Changing the method decleration to include "shared" removes the
behaviour where
the form1 object is being re created.
Public Shared Sub UpdateProgressDisplay(ByVal
Value_for_progress_bar As
Integer)
This is strange as Im not receiving even a warning during the build.
Multi threaded VB apps
may be a step too far. Might be time for C#.
Thanks for your help.
Denis
> Again, in C# you just wouldn't be able to do that. But maybe in VB it's
> doing something on your behalf (scary, but possible).
[quoted text clipped - 13 lines]
>
> Pete