[comp.windows.ms] MessageBox problem

davis@bdmrrr.bdm.com (Arthur Davis x4675) (09/10/90)

Someone mentioned having a problem with garbled strings in a
MessageBox call; i.e. MessageBox (hDlg, "abc", "xyz", MB_OK)
produces garbage on the display.

Unless you are working in large model (which you shouldn't be
without VERY good reasons), quoted string literals are certain
to be passed as near addresses.  The declaration of the string
parameters in the MessageBox function is LPSTR, or the long
address of string.  What is happening to you I guess is that
Windows is moving your segment around and the near addresses of
your strings is becoming invalid, leaving you with screen crud.

Try this:

MessageBox (hDlg, (LPSTR) "abc", (LPSTR) "xyz", MB_OK);

This will force the pass of a FAR or long address and should solve your
problem.

warsh@athena.mit.edu (Russell Williams) (09/10/90)

In article <1990Sep9.224303.10981@bdmrrr.bdm.com>, davis@bdmrrr.bdm.com (Arthur Davis x4675) writes:
| Someone mentioned having a problem with garbled strings in a
| MessageBox call; i.e. MessageBox (hDlg, "abc", "xyz", MB_OK)
| produces garbage on the display.
| 
| Unless you are working in large model (which you shouldn't be
| without VERY good reasons), quoted string literals are certain
| to be passed as near addresses.  The declaration of the string
| parameters in the MessageBox function is LPSTR, or the long
| address of string.  What is happening to you I guess is that
| Windows is moving your segment around and the near addresses of
| your strings is becoming invalid, leaving you with screen crud.
| 
| Try this:
| 
| MessageBox (hDlg, (LPSTR) "abc", (LPSTR) "xyz", MB_OK);
| 
| This will force the pass of a FAR or long address and should solve your
| problem.

Nope, the C compiler will automatically upgrade the near string to an
LPSTR since the MessageBox() function is declared using LPSTR arguments.
Also, the far address is generated by a push DS, so having a segment moved
would not cause things to go wrong (since the instance thunk/function prelude fixes DS
when your program is entered) unless your DS is wrong, as can happen
mysteriously when you forget to export your dialog function (thus DS will
contain the value of whatever data segment was last in use, which may
be another program, a DLL, etc).  Check that the dialog function is exported.

-Russell Williams

bcw@rti.rti.org (Bruce Wright) (09/10/90)

In article <1990Sep9.224303.10981@bdmrrr.bdm.com>, davis@bdmrrr.bdm.com (Arthur Davis x4675) writes:
> Someone mentioned having a problem with garbled strings in a
> MessageBox call; i.e. MessageBox (hDlg, "abc", "xyz", MB_OK)
> produces garbage on the display.
> 
> [...]
>
> Try this:
> 
> MessageBox (hDlg, (LPSTR) "abc", (LPSTR) "xyz", MB_OK);
> 
> This will force the pass of a FAR or long address and should solve your
> problem.

If you are using the Microsoft SDK, the windows.h file defines
MessageBox as:

	int FAR PASCAL MessageBox (HWND, LPSTR, LPSTR, WORD);

Unless your C compiler has some serious problems with parameter
definitions, you shouldn't need to use the (LPSTR) in the call
to MessageBox.

It's possible that the strings are getting clobbered by a
runaway pointer in another part of the program.

But the fact that the MessageBox call is using an hDlg handle
makes me wonder if the original author was calling this from
a dialog box window.  If so, one of the first things to look
for would be to see if a MakeProcInstance call was made for
the dialog box procedure, and if the procedure itself was
exported in the .DEF file.  Failure to do either of these
can cause serious problems that can sometimes show up in
flakey ways.  Also check for whether the application has
any memory or resource leaks (allocating memory or resources
without releasing them);  this can also sometimes cause funny
behavior (including screen garbage, depending on what the
application is doing and the mode Windows was started in).

					Bruce C. Wright

goodearl@world.std.com (Robert Goodearl) (09/10/90)

In article <1990Sep9.224303.10981@bdmrrr.bdm.com> davis@bdmrrr.bdm.com (Arthur Davis x4675) writes:
>Someone mentioned having a problem with garbled strings in a
>MessageBox call; i.e. MessageBox (hDlg, "abc", "xyz", MB_OK)
>produces garbage on the display.
>
>Unless you are working in large model (which you shouldn't be
>without VERY good reasons), quoted string literals are certain
>to be passed as near addresses.  The declaration of the string
>parameters in the MessageBox function is LPSTR, or the long
>address of string.  What is happening to you I guess is that
>Windows is moving your segment around and the near addresses of
>your strings is becoming invalid, leaving you with screen crud.
>
>Try this:
>
>MessageBox (hDlg, (LPSTR) "abc", (LPSTR) "xyz", MB_OK);
>
>This will force the pass of a FAR or long address and should solve your
>problem.

Using the LPSTR cast will not solve the problem of moving segments.  It will
insure that you pass a far pointer, but if you have included the file 
windows.h in your source, you will not need to cast as the function 
prototype included there will take care of that problem for you.

If you are passing literal strings to message box,
they are in your local data segment.  If your data segment is marked as
moveable, you may need to lock it down before calling message box.
Reference the function LockData on p 4-293 of the sdk.
-- 
Bob Goodearl -- goodearl@world.std.com

whkr@ciba-geigy.ch (Hans Kraft) (09/11/90)

It is correct, that the string constants have near addresses, but the
explicit casting to LPSTR does not change anything, as the function
MessageBoX is prototyped in windows.h, hence the compiler does the cast
automatically. I am posting this, as I had a similar problem recently.
When writing a library I made in one of the library functions an 
enumeration looking for a special window. This failed all the time due 
to wrong segment switching. Now back to the original posting I would
suspect a similar thing, maybe even a missing MakeProcInstance.
In doubt some example source code from the original poster would help.

Hans Kraft (Giovanni Forza)

hoang@Neon.Stanford.EDU (My Khanh Hoang) (09/12/90)

	I am the original poster of the problem. I would like to thank  all who
	attempted to help me solve the problem. Regrettably, none of the
	suggestions help.
	The casting is taken care of by #include <windows.h>.
	There was no missing MakeProcInstance or exported name.
	I even tried to LockData() and made the data segment fixed as Bob
	Goodearl suggested.
	I am still waiting for more help!
	The problem is MessageBox(hDlg, "abc", "xyz", MB_OK) does not display
	text strings as expected (strings are garbled up).
	The call is made within a dialog box window procedure. There is no
	global or local allocation of memory. I did try to increase the stack
	size in .def file but this did not help. The machine I use is a PS2
	80. Windows and SDK are 3.0.
	By the way, a similar call made outside the dialog box window procedure
	works MessageBox(hWnd, "abc", "xyz", MB_OK) where hWnd is parent of
	hDlg.

poffen@sj.ate.slb.com (Russell Poffenberger) (09/21/90)

In article <1990Sep12.043315.10404@Neon.Stanford.EDU> hoang@Neon.Stanford.EDU (My Khanh Hoang) writes:
>
>	I am the original poster of the problem. I would like to thank  all who
>	attempted to help me solve the problem. Regrettably, none of the
>	suggestions help.
>	The casting is taken care of by #include <windows.h>.
>	There was no missing MakeProcInstance or exported name.
>	I even tried to LockData() and made the data segment fixed as Bob
>	Goodearl suggested.
>	I am still waiting for more help!
>	The problem is MessageBox(hDlg, "abc", "xyz", MB_OK) does not display
>	text strings as expected (strings are garbled up).
>	The call is made within a dialog box window procedure. There is no
>	global or local allocation of memory. I did try to increase the stack
>	size in .def file but this did not help. The machine I use is a PS2
>	80. Windows and SDK are 3.0.
>	By the way, a similar call made outside the dialog box window procedure
>	works MessageBox(hWnd, "abc", "xyz", MB_OK) where hWnd is parent of
>	hDlg.


I have found that MessageBox doesn't work properly in all cases. In attempting
to write a dll (Screen Peace saver extension), I called MessageBox to try and
debug a problem, this failed and caused the system to hang. Running CVW spit
out a continuous ream of messages indicating that there were no more Device
Contexts available. It seemed to get stuck forever in a loop at that point.


Russ Poffenberger               DOMAIN: poffen@sj.ate.slb.com
Schlumberger Technologies       UUCP:   {uunet,decwrl,amdahl}!sjsca4!poffen
1601 Technology Drive		CIS:	72401,276
San Jose, Ca. 95110             (408)437-5254

risto@tuura.UUCP (Risto Lankinen) (09/21/90)

poffen@sj.ate.slb.com (Russell Poffenberger) writes:

>I have found that MessageBox doesn't work properly in all cases. In attempting
>to write a dll (Screen Peace saver extension), I called MessageBox to try and
>debug a problem, this failed and caused the system to hang. Running CVW spit
>out a continuous ream of messages indicating that there were no more Device
>Contexts available. It seemed to get stuck forever in a loop at that point.

Hi!

I have run into similar problem with DLL's.  I would have liked to show a
messagebox if the LibMain failed to initialize the DLL for some reason.
Since the actual application is unaware of LibMain being called, there's
no window handle to associate the MessageBox with.  So, I used the handle
returned from GetDesktopWindow(), but it wouldn't work (even though it does
when an *application* wants to display a MessageBox without having created
a window handle).  On the other hand, if the LibMain() returned false to
indicate the failure, there's no chance to tell the user what went wrong,
because the DLL-related application will not start in case LibMain fails.

What I've made myself a habit to do is always return TRUE from LibMain(),
but set a flag, which would be returned by the first call made to the DLL
by the application itself.  The application would call, say, InitDLL(),
which 'pseudo-initializes' the DLL and actually returns the possible error
condition flagged by LibMain().  There's an added convenience that the WEP
also knows which initializations were succesfully done in order to free
just those resources that were grabbed.

Terveisin: Risto Lankinen
-- 
Risto Lankinen / product specialist ***************************************
Nokia Data Systems, Technology Dept *  2                              2   *
THIS SPACE INTENTIONALLY LEFT BLANK * 2 -1 is PRIME!  Now working on 2 +1 *
replies: risto@yj.data.nokia.fi     ***************************************

efowler@milton.u.washington.edu (Eric Fowler) (09/22/90)

Netlanders:
	I have been fighting a losing battle with the MSC 5.1 linker for
several days now.  I have some windows code that compiles, links, and
executes flawlessly on my computer at work, a standard 386/33 clone. 
The same code with the same makefile(and the same .rc, .def, .h, and
.lib's) fails to link on the Epson Equity 386/20 that I have at home. 
The error returned by the linker is always "Warning:No stack segment",
followed by:"Unresolved external:", and either 23 or 36 functions.  The
functions it is failing to find all come from the WINDOWS.H file, with
the possible exception of '_acrtused'.  I have painstakingly proven
beyond any doubt that the LIB variable is pointing to the directory
containing the libraries(LIBW, SLIBCEW).  This was accomplished by:
using the explicit paths for the libraries(which gave no change);
deliberately introducing an error into the LIB setting(yielding a
different error message, "Cannot find libraries:<library names>"); and
using different libraries(which gave either more or less functions
unresolved).  Needless to say, I have reinstalled windows, the SDK, and
C5.1 many times.  Each time I use the same protocol as at work, namely,
Emulator math, build the libraries for all memory models, build combined
libraries, and install QuickC with the QuickC editor.  A call to
Microsoft got the suggestion that the installation of MSC 5.1 might have
quietly failed due to an environment problem(e.g.  a TSR).  With that in
mind, I copied all the (working) .LIB files from work to floppies and
thence to home, and tried again.  No dice:no change.  I have no TSRs
that I know about.  I have removed SHARE from my 32 meg disk, have tried
this with high memory both loaded and disabled, and with SMARTDRIVE both
loaded and disabled.  The DOS at work is 3.31, at home is 3.30.  All
compiling is done from the DOS environment-windows is not
loaded(exceptions below).  My config and autoexec files are studies in
simplicity, simply setting up COMSPEC=command.com, shell=command.com /p
/e:1024, files=20, buffers=30, break=on. 

Some possibly relevant facts: (1) The computer is not on the approved
hardware list for windows 3.  Just the same, I have been able to run
windows in Enhanced mode(not standard or real), and all the linking is
done in DOS/conventional memory.  (2) I have the MKS toolkit installed,
a psuedo-unix shell for PCs.  The MKS shell comes with its own UNIX
compatible MAKE utility.  I have rewritten the makefile for the MKS
make, come up under MKS, and had the same failure as when I boot from a
DOS floppy and use the Microsoft MAKE.  Under those conditions, no part
of the MKS toolkit is in memory.  (3) I cannot be certain that there is
no math coprocessor installed at home(there is none at work).  Microsoft
tech support assures me that that should not be a problem with the
Emulator package, which is what I am using.  None of the libraries
contain the digit '7' which appears in the coprocessor libraries.  (4)
Video is standard windows VGA.DRV at work, Video7 Vega 640x480 Version
1.47 at home.  This package dates back to 1987. 

I am nearly out of solutions.  I could call Epson for help, but most
hardware vendors will tell you that you have a software problem.  I
could fasten a rope around the computer, tie one end around my neck, and
dive into deep water, but this will still not resolve the problem with
the linker.  If anybody has any better ideas I would love to hear about
it. 
Thank You, 
=Eric Fowler

risto@tuura.UUCP (Risto Lankinen) (09/24/90)

efowler@milton.u.washington.edu (Eric Fowler) writes:

>Netlanders:
>	I have been fighting a losing battle with the MSC 5.1 linker for
>several days now.  I have some windows code that compiles, links, and
>executes flawlessly on my computer at work, a standard 386/33 clone. 
>The same code with the same makefile(and the same .rc, .def, .h, and
>.lib's) fails to link on the Epson Equity 386/20 that I have at home. 
>The error returned by the linker is always "Warning:No stack segment",
>followed by:"Unresolved external:", and either 23 or 36 functions.  The

Hi!

This may sound far too trivial to be the solution, but I think it could
be given a try...  There was a problem similar to this which was solved
by making sure that the LINK.EXE was the product's 'own' version, but
not the one which is usually packed with MS-DOS .  Try renaming the
LINK.EXE in the DOS-directory to something else (I'm using LINK!.EXE).

The problem focuses to the functions in the WINDOWS.H probably because
their 'executable' is in import libraries (as opposed to traditional
object libraries), whose packing method the too old a linker cannot
resolve.

Terveisin: Risto Lankinen
-- 
Risto Lankinen / product specialist ***************************************
Nokia Data Systems, Technology Dept *  2                              2   *
THIS SPACE INTENTIONALLY LEFT BLANK * 2 -1 is PRIME!  Now working on 2 +1 *
replies: risto@yj.data.nokia.fi     ***************************************