|
| Author |
Message |
Lucy Ludmiller
Joined: 04 Oct 2007 Posts: 3
|
Posted: Sun Sep 10, 2006 3:03 pm Post subject: Using MsgBox considered harmful ? |
|
|
Sorry about the cross posts. But the issue under discussion straddles
accross VB6, multi-threaded C++ Dlls, and (MFC) COM events - so it is
not clear which would be the most relevant group to target this post to
- though I suspect it is more relevant to (classic) VB (i.e. VB6) groups.
I wrote a mutithreaded C++ Dll which has a lot of methods/functions that
expect callback functions as paramters. I was using VB6 as a frontend
and experienced some horrendous unexpected crashes.
After spending a week on the problem I realized that VB6 was not thread
safe and making callbacks from seperate thread was a no-no. The way I
got round this was to wrap up the multi-threaded functionality in MFC
COM object - replacing the callbacks with COM events. I used MsgBox to
display the data received in the event sink. I noticed this code run
without errors or crashes in the VB6 IDE - however, when I compiled my
application into an executable - the crashes occured in VB - I was able
to debug the resulting exe, to find that the lin where the crash
occured was where the MsgBox() was being called.
I replaced MsgBox with a function that dumped the data onto a text box
and the errors (crashes) disapeared completely - DOES ANYONE KNOW WHY
THIS OCCURS ? - My hunch is that MsgBox is spawning another thread ...
Also, is simply substituting MsgBox with a function that runs in the
same thread as the event (i.e. a normal user function) the way to fix
this issue? - Have I missed something ?
Archived from group: microsoft>public>vb>enterprise |
|
| Back to top |
|
 |
J French
Joined: 04 Oct 2007 Posts: 2725
|
Posted: Sun Sep 10, 2006 2:52 pm Post subject: Re: Using MsgBox considered harmful ? |
|
|
On Sun, 10 Sep 2006 11:03:03 +0100, Lucy Ludmiller
wrote:
>Sorry about the cross posts. But the issue under discussion straddles
>accross VB6, multi-threaded C++ Dlls, and (MFC) COM events - so it is
>not clear which would be the most relevant group to target this post to
>- though I suspect it is more relevant to (classic) VB (i.e. VB6) groups.
>
>I wrote a mutithreaded C++ Dll which has a lot of methods/functions that
>expect callback functions as paramters. I was using VB6 as a frontend
>and experienced some horrendous unexpected crashes.
>
>After spending a week on the problem I realized that VB6 was not thread
>safe and making callbacks from seperate thread was a no-no. The way I
>got round this was to wrap up the multi-threaded functionality in MFC
>COM object - replacing the callbacks with COM events. I used MsgBox to
>display the data received in the event sink. I noticed this code run
>without errors or crashes in the VB6 IDE - however, when I compiled my
>application into an executable - the crashes occured in VB - I was able
>to debug the resulting exe, to find that the lin where the crash
>occured was where the MsgBox() was being called.
>
>I replaced MsgBox with a function that dumped the data onto a text box
>and the errors (crashes) disapeared completely - DOES ANYONE KNOW WHY
>THIS OCCURS ? - My hunch is that MsgBox is spawning another thread ...
>Also, is simply substituting MsgBox with a function that runs in the
>same thread as the event (i.e. a normal user function) the way to fix
>this issue? - Have I missed something ?
In VB5/6 MsgBox is 'blocking' in the IDE, but not when compiled
In other words Timer Events dont fire in the IDE, but they work fine
when compiled.
I don't think it is another thread, probably it uses a form of
DoEvents when compiled
I think I would have been inclined to have broken the App into two
separate EXEs and communicated with SendMessage
(possibly that is what you have done)
In general the rule appears to be to avoid using MsgBox inside events
in production code. I am pretty sure I've seen people mention that. |
|
| Back to top |
|
 |
Ralph
Joined: 04 Oct 2007 Posts: 4148
|
Posted: Sun Sep 10, 2006 10:15 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
Forgot to add...
And how are (you) passing the string to MsgBox() and to the TextBox?
A common mistake by C/C++ programmers when supporting a VB app is to forget
that a String in VB is NOT nul-terminated. A MsgBox accepts strings to 1024
and a TextBox 2048 (unless multi-line is selected). Usually, longer buffers
are just truncated but a MsgBox is more sensitive to buffer over-runs on
occasions.
-ralph |
|
| Back to top |
|
 |
Ralph
Joined: 04 Oct 2007 Posts: 4148
|
Posted: Sun Sep 10, 2006 10:23 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
"J French" wrote in message@news.btopenworld.com...
> On Sun, 10 Sep 2006 11:03:03 +0100, Lucy Ludmiller
> wrote:
>
> >Sorry about the cross posts. But the issue under discussion straddles
> >accross VB6, multi-threaded C++ Dlls, and (MFC) COM events - so it is
> >not clear which would be the most relevant group to target this post to
> >- though I suspect it is more relevant to (classic) VB (i.e. VB6) groups.
> >
> >I wrote a mutithreaded C++ Dll which has a lot of methods/functions that
> >expect callback functions as paramters. I was using VB6 as a frontend
> >and experienced some horrendous unexpected crashes.
> >
> >After spending a week on the problem I realized that VB6 was not thread
> >safe and making callbacks from seperate thread was a no-no. The way I
> >got round this was to wrap up the multi-threaded functionality in MFC
> >COM object - replacing the callbacks with COM events. I used MsgBox to
> >display the data received in the event sink. I noticed this code run
> >without errors or crashes in the VB6 IDE - however, when I compiled my
> >application into an executable - the crashes occured in VB - I was able
> >to debug the resulting exe, to find that the lin where the crash
> >occured was where the MsgBox() was being called.
> >
> >I replaced MsgBox with a function that dumped the data onto a text box
> >and the errors (crashes) disapeared completely - DOES ANYONE KNOW WHY
> >THIS OCCURS ? - My hunch is that MsgBox is spawning another thread ...
>
> >Also, is simply substituting MsgBox with a function that runs in the
> >same thread as the event (i.e. a normal user function) the way to fix
> >this issue? - Have I missed something ?
>
> In VB5/6 MsgBox is 'blocking' in the IDE, but not when compiled
>
> In other words Timer Events dont fire in the IDE, but they work fine
> when compiled.
>
> I don't think it is another thread, probably it uses a form of
> DoEvents when compiled
>
> I think I would have been inclined to have broken the App into two
> separate EXEs and communicated with SendMessage
>
> (possibly that is what you have done)
>
> In general the rule appears to be to avoid using MsgBox inside events
> in production code. I am pretty sure I've seen people mention that.
>
LOL
That's a good catch.
I never use MsgBox() in production code and have simply forgotten why?
-ralph |
|
| Back to top |
|
 |
Lucy Ludmiller
Joined: 04 Oct 2007 Posts: 3
|
Posted: Sun Sep 10, 2006 4:31 pm Post subject: Re: Using MsgBox considered harmful ? |
|
|
Ralph wrote:
> Forgot to add...
>
> And how are (you) passing the string to MsgBox() and to the TextBox?
>
> A common mistake by C/C++ programmers when supporting a VB app is to forget
> that a String in VB is NOT nul-terminated. A MsgBox accepts strings to 1024
> and a TextBox 2048 (unless multi-line is selected). Usually, longer buffers
> are just truncated but a MsgBox is more sensitive to buffer over-runs on
> occasions.
>
> -ralph
>
>
Ralph .. this is not an issue here. I am using BSTR when passing strings
to VB, in the COM object I am using BSTR and LPTCSTR etc where
approriate and converting between them as and when appropriate. I am
using the STL string class (std::string) in the C++ DLL.
I am exporting other functions from the C++ DLL (some are also callback
functions) with no problems at all - so the problem I highlighted in my
post seems to be entirely related to threading and the fact that the VB6
runtime is not re-entrant (i.e. not thread safe).
Lastly, the strings I am passing are far smaller than the buffer limits
you provided in your post. So that too (buffer overun issues) are not
the problem here - rember the code (with MsgBox) runs fine in the IDe
but only crashes when the VB6 app is compiled to an exe. |
|
| Back to top |
|
 |
Michael C
Joined: 04 Oct 2007 Posts: 1831
|
Posted: Mon Sep 11, 2006 1:54 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
"J French" wrote in message @news.btopenworld.com...
> In general the rule appears to be to avoid using MsgBox inside events
> in production code. I am pretty sure I've seen people mention that.
Avoid using MsgBox inside events?!? Just about everything is a friggin event
in vb!!!! Pretty much the only thing that isn't is SubMain.
Michael |
|
| Back to top |
|
 |
Michael C
Joined: 04 Oct 2007 Posts: 1831
|
Posted: Mon Sep 11, 2006 2:06 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
"Lucy Ludmiller" wrote in message @bt.com...
> I'll stick to the Vb side of things in my answer, to keep things simple.
> Lets say my ActiveX control is called "HellRaiser"
Damn it!! Why don't I get to code things called HellRaiser. Mine are always
far less interesting.
> This crashed when compiled as an exe, but run correctly in the VB6 IDE
As someone said the main difference with vb6 in the IDE is that events are
ignored in the IDE while a messagebox is visible. I'm not sure how this
would cause a problem though. The other difference is of cource P code vs
native which could be an issue.
Could it be some problem with who is destroying the string? In vb6 passing
the string ByVal copies the entire string, not just the pointer, so vb might
be expecting to destroy the string itself.
Michael |
|
| Back to top |
|
 |
Ralph
Joined: 04 Oct 2007 Posts: 4148
|
Posted: Sun Sep 10, 2006 11:39 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
"Lucy Ludmiller" wrote in message@bt.com...
>
>
> Ralph wrote:
>
> > Forgot to add...
> >
> > And how are (you) passing the string to MsgBox() and to the TextBox?
> >
> > A common mistake by C/C++ programmers when supporting a VB app is to
forget
> > that a String in VB is NOT nul-terminated. A MsgBox accepts strings to
1024
> > and a TextBox 2048 (unless multi-line is selected). Usually, longer
buffers
> > are just truncated but a MsgBox is more sensitive to buffer over-runs on
> > occasions.
> >
> > -ralph
> >
> >
> Ralph .. this is not an issue here. I am using BSTR when passing strings
> to VB, in the COM object I am using BSTR and LPTCSTR etc where
> approriate and converting between them as and when appropriate. I am
> using the STL string class (std::string) in the C++ DLL.
>
> I am exporting other functions from the C++ DLL (some are also callback
> functions) with no problems at all - so the problem I highlighted in my
> post seems to be entirely related to threading and the fact that the VB6
> runtime is not re-entrant (i.e. not thread safe).
>
> Lastly, the strings I am passing are far smaller than the buffer limits
> you provided in your post. So that too (buffer overun issues) are not
> the problem here - rember the code (with MsgBox) runs fine in the IDe
> but only crashes when the VB6 app is compiled to an exe.
>
That latter piece I wrote was pretty far-fetched, I just happened to
remember a bad incident from a few years ago and threw it out as a
possiblity. The result of the time of morning and only my third cup of
coffee.
I think Mr. French has most likely shown the real cause. MsgBox()s perform
differently in production (compiled) code than in the IDE.
I remember a particularily nasty bug that was eventually traced to a MsgBox
call in an ADO_Event. For that reason and others (ability to better format,
provide more options, control location, timed closure, etc) I long ago
substituted my own MessageDialog for the MsgBox, and never use the MsgBox
call except during development.
hth
-ralph |
|
| Back to top |
|
 |
J French
Joined: 04 Oct 2007 Posts: 2725
|
Posted: Sun Sep 10, 2006 4:48 pm Post subject: Re: Using MsgBox considered harmful ? |
|
|
On Sun, 10 Sep 2006 12:19:57 +0100, Lucy Ludmiller
wrote:
>I'll stick to the Vb side of things in my answer, to keep things simple.
>Lets say my ActiveX control is called "HellRaiser"
>My (original) Vb6 code looked like this:
>public sub HellRaiser1_OnEventOccured(byval id as long, byval note as
>string)
> MsgBox "Received event with Id : " & id & " and note : " & note
>end sub
>This crashed when compiled as an exe, but run correctly in the VB6 IDE
>I changed the implementation of the above sub to:
>public sub HellRaiser1_OnEventOccured(byval id as long, byval note as
>string)
> form1.Update "Received event with Id : " & id & " and note : " & note
>end sub
>Where Update was a simply method added to the form (form1) that took a
>string argument and dumped it onto a text box on form1, i.e. something
>like this:
>public sub Update(byval Info as string)
> with me
> .txtInfo = .txtInfo & Info & vbcrlf
> end with
>end sub
In the IDE a MsgBox freezes the App, the Windows Queue is not
processed until the MsgBox is dismissed.
When compiled Messages /are/ processed, yet the 'strand of execution'
is frozen, and only continues when the MsgBox is processed.
The main VB thread pops out of your DLL, shows the MsgBox and does not
return until you dismiss the MsgBox, but at the same time the Windows
Queue is being processed. (well maybe not - see later on)
Hazarding a guess, I would reckon that your DLL does another Callback,
and your VB App tries to shove another MsgBox on the screen.
I am not an expert on the precise inner workings of COM, but my
understanding is that it uses SendMessage
However, SendMessage works totally differently for in process and out
of process stuff - and there are wrinkles on threads
<| If the specified window was created by the calling thread, the
window procedure is called immediately as a subroutine. |>
<| If the specified window was created by a different thread, Windows
switches to that thread and calls the appropriate window procedure.
Messages sent between threads are processed only when the receiving
thread executes message retrieval code. |>
Now MsgBox when compiled /does/ perform message retrieval code, but it
does not in the IDE
I reckon that replacing the MsgBox with something that modifies a
Textbox and returns to your DLL makes a fragile program less fragile,
so it just happens to work.
It would probably crash if you did anything really time consuming in
the Callback - maybe not if the Callbacks always originate from a
different thread than the VB one and you don't have any DoEvents so
the message queue is left unprocessed.
You could test this by putting something like this instead of the
MsgBox:
For L9 = 1 To 100000
DoEvents
Next
I would expect a crash both in the IDE and when compiled, but if it
does not, then you probably have a fairly solid mechanism.
Your problem might be simply that you are trying to stick two MsgBoxes
on the screen at the same time.
I would still break the App into two EXEs - one in VB and one in pure
C and use SendMessage directly to communicate between them (actually
SendMessageTimeout)
It is re-writing the way in which an AX EXE works, but I shudder to
think what would happen if your C code started allocating memory while
VB was having a sulk.
I don't use C, and intensely dislike it, instead I use Delphi for
tricky stuff and DLLs
Using that I have written stuff that hammers data between as many Apps
as I can fit on a screen, and they work reliably even when a MsgBox is
showing. |
|
| Back to top |
|
 |
J French
Joined: 04 Oct 2007 Posts: 2725
|
Posted: Sun Sep 10, 2006 4:57 pm Post subject: Re: Using MsgBox considered harmful ? |
|
|
On Sun, 10 Sep 2006 21:54:28 +1000, "Michael C"
wrote:
>"J French" wrote in message
>@news.btopenworld.com...
>> In general the rule appears to be to avoid using MsgBox inside events
>> in production code. I am pretty sure I've seen people mention that.
>Avoid using MsgBox inside events?!? Just about everything is a friggin event
>in vb!!!! Pretty much the only thing that isn't is SubMain.
I know, but they are still a problem
- I've done some hard thinking about this, and I reckon that it is the
same code popping up another MsgBox before the first is dismissed |
|
| Back to top |
|
 |
Michael C
Joined: 04 Oct 2007 Posts: 1831
|
Posted: Mon Sep 11, 2006 2:28 pm Post subject: Re: Using MsgBox considered harmful ? |
|
|
"J French" wrote in message @news.btopenworld.com...
> I know, but they are still a problem
> - I've done some hard thinking about this, and I reckon that it is the
> same code popping up another MsgBox before the first is dismissed
That won't cause a GPF, you just get 2 messageboxes.
Michael |
|
| Back to top |
|
 |
J French
Joined: 04 Oct 2007 Posts: 2725
|
Posted: Mon Sep 11, 2006 11:41 am Post subject: Re: Using MsgBox considered harmful ? |
|
|
On Mon, 11 Sep 2006 10:28:04 +1000, "Michael C"
wrote:
>"J French" wrote in message
>@news.btopenworld.com...
>> I know, but they are still a problem
>> - I've done some hard thinking about this, and I reckon that it is the
>> same code popping up another MsgBox before the first is dismissed
>That won't cause a GPF, you just get 2 messageboxes.
Hmm...
Just tested it with two Timers, and you are right, two MsgBoxes
Strike that one
|
|
| Back to top |
|
 |
|
|