469,356 Members | 1,958 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,356 developers. It's quick & easy.

Trouble displaying MessageBox from VC++ form

I'm having a strange problem (or at least it seems strange to me) trying to
display a MessageBox in a VC++ .NET forms application.

If I put the call to MessageBox::Show in the form's .h file, it works just
fine.

If I put the call in the .cpp file, I get the following two errors:

error C2653: 'MessageBoxA': is not a class or namespace name
error C2660: 'System::Windows::Forms::Control::Show': function does not take
2 arguments

I have tested this out as follows:

Create a .NET Windows Forms application with the default form, Form1, and
add two buttons to it, button1 and button2. Double-click on each button to
add the default event handlers. In the class declaration in Form1.h, I added
this:

// Declaration and definition together in .h file
private: System::Void button1_Click(System::Object * sender,
System::EventArgs * e)
{
MessageBox::Show(S"Clicked Button 1",S"Title");
}

// Declaration only in .h file, definition in the .cpp file
private: System::Void button2_Click(System::Object * sender,
System::EventArgs * e);

Then in the class definition in Form1.cpp, I added:

// Definition in .cpp file corresponding to declaration in .h file
System::Void Form1::button2_Click(System::Object * sender,
System::EventArgs * e)
{
MessageBox::Show(S"Clicked Button 2",S"Title");
}

When I'm typing the code, I get the expected auto-completion after the
MessageBox:: so it seems that the System::Windows::Forms namespace is known,
as is the specific MessageBox object. System.Windows.Forms is included as a
reference in the project. I have also tried explicitly including

#using <System.Windows.Forms.dll>
using namespace System::Windows::Forms;

in the .cpp file, but that has no effect.

I tried to figure out what is going on with the reference to MessageBoxA in
the first error message. Searching in the help for MessageBoxA turns up a
reference to "Macros and the Preprocessor" which says

#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE

So apparently UNICODE is not defined in my .cpp file, but it is in my .h
file?

Going on this I experimented -- adding

#include <windows.h>

to the .h file (not something you'd normally do -- it's an experiment)
causes the same two errors to occur in the .h file as in the .cpp file. So
now it looks like this is what's happening: Inclusion of windows.h in the
..cpp file causes MessageBox to be expanded into MessageBoxA which is
unknown. Absence of windows.h from the .h file causes MessageBox to be
expanded into MessageBoxW, which works. However, attempting to call
MessageBoxW explicity from the .cpp file gets me the same two errors again,
except for a different class:

error C2653: 'MessageBoxW': is not a class or namespace name
error C2660: 'System::Windows::Forms::Control::Show': function does not take
2 arguments

In short -- there doesn't seem to be any way to display a MessageBox from
the .cpp code of a form. Which leaves the option of displaying it from the
..h file, which is just wrong in so many ways, but gets the job done.

Suggestions? Thanks in advance.
Nov 17 '05 #1
20 8442
If you are doing a #include <windows.h", MessageBox is a macro which expands
to either MessageBoxA or MessageBoxW depending in whether you have UNICODE
defined. So your MessageBox::Show then expands to MessageBoxA::Show and the
compiler says correctly there is no MessageBoxA class or namespace in .NET,
which is correct. As a workaround try an #undef MessageBox after your
#include <windows.h> .

Peter E. Granger wrote:
I'm having a strange problem (or at least it seems strange to me)
trying to display a MessageBox in a VC++ .NET forms application.

If I put the call to MessageBox::Show in the form's .h file, it works
just fine.

If I put the call in the .cpp file, I get the following two errors:

error C2653: 'MessageBoxA': is not a class or namespace name
error C2660: 'System::Windows::Forms::Control::Show': function does
not take 2 arguments

Nov 17 '05 #2
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:Ol**************@TK2MSFTNGP12.phx.gbl...
If you are doing a #include <windows.h", MessageBox is a macro which expands to either MessageBoxA or MessageBoxW depending in whether you have UNICODE
defined. So your MessageBox::Show then expands to MessageBoxA::Show and the compiler says correctly there is no MessageBoxA class or namespace in ..NET, which is correct. As a workaround try an #undef MessageBox after your
#include <windows.h> .


Thanks, Edward, for confirming what I'd determined, and for the workaround.
Doing the #undef MessageBox works, although it seems really
counterintuitive, undefining the specific thing that I want defined. (I
know, I'm just removing a prior redefinition of it, but it still seems odd.)

Just to be thorough, I also checked what happened if I switched the
character set to Unicode in the project configuration. As expected,
MessageBox is now expanded to MessageBoxW, which is also unknown.

Can you shed any light on the reason behind this? It seems strange that the
macro that's defined in the windows.h header prevents use of the MessageBox
when it's such a common object in Windows applications. Or is there perhaps
a different class that can be used to do the same job, that doesn't have
this problem? I see quite a few different dialog controls in the toolbox,
but no simple message box control.

Thanks again.

- Peter
Nov 17 '05 #3
Peter E. Granger wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:Ol**************@TK2MSFTNGP12.phx.gbl...
If you are doing a #include <windows.h", MessageBox is a macro which
expands to either MessageBoxA or MessageBoxW depending in whether
you have UNICODE defined. So your MessageBox::Show then expands to
MessageBoxA::Show and the compiler says correctly there is no
MessageBoxA class or namespace in .NET, which is correct. As a
workaround try an #undef MessageBox after your #include <windows.h> .


Thanks, Edward, for confirming what I'd determined, and for the
workaround. Doing the #undef MessageBox works, although it seems
really counterintuitive, undefining the specific thing that I want
defined. (I know, I'm just removing a prior redefinition of it, but
it still seems odd.)

Just to be thorough, I also checked what happened if I switched the
character set to Unicode in the project configuration. As expected,
MessageBox is now expanded to MessageBoxW, which is also unknown.

Can you shed any light on the reason behind this?


Macros in C++ get textually substituted before the compile sees
MessageBox::Show. So what the compiler sees, if you #include <windows.h>
before invoking MessageBox::Show is MessageBoxA::Show. Since there is no
MessageBoxA::Show the compilation fails. If you use the VC++ precompiler to
precompile your code to produce a .i file and view the .i file, you will see
this yourself.
Nov 17 '05 #4
Peter E. Granger wrote:
error C2653: 'MessageBoxA': is not a class or namespace name
error C2660: 'System::Windows::Forms::Control::Show': function does not
take 2 arguments


I discovered this on my first day of VC++.NET. It's astonishing that
M$ did not find such an obvious fault in their own extensive battery
of tests. ;-)

What more proof could you need that macros are evil?
Arnold the Aardvark
http://www.codeproject.com/cpp/garbage_collect.asp

Nov 17 '05 #5
We knew of this before we even needed to have the first test fail. The issue
is just that this is simply the way the preprocessor works and that the kind
of extensive change needed to the windows headers to avoid this is extremely
scary.

We have several possible solutions we are investigating for future versions.

Ronald Laeremans
Visual C++ team

"Arnold the Aardvark" <no@way.com> wrote in message
news:bv*******************@news.demon.co.uk...
Peter E. Granger wrote:
error C2653: 'MessageBoxA': is not a class or namespace name
error C2660: 'System::Windows::Forms::Control::Show': function does not
take 2 arguments


I discovered this on my first day of VC++.NET. It's astonishing that
M$ did not find such an obvious fault in their own extensive battery
of tests. ;-)

What more proof could you need that macros are evil?
Arnold the Aardvark
http://www.codeproject.com/cpp/garbage_collect.asp

Nov 17 '05 #6
Ronald Laeremans [MSFT] wrote:
We knew of this before we even needed to have the first test fail. The
issue is just that this is simply the way the preprocessor works.


I'm grateful you replied but is this response intended to inspire
me with confidence? Now I wonder what else is lurking in VC++.NET
that the compiler may not be good enough to complain about...

Simple solution - don't use names that are already *commonly used*
macros.
Arnold the Aardvark
http://www.codeproject.com/cpp/garbage_collect.asp

Nov 17 '05 #7
Ronald Laeremans [MSFT] <ro*****@online.microsoft.com> wrote:
We knew of this before we even needed to have the first test fail. The issue
is just that this is simply the way the preprocessor works and that the kind
of extensive change needed to the windows headers to avoid this is extremely
scary.
While the change would certainly impact
a lot of declarations in the Windows
headers, it would also be fairly simple.
Replacing
#if define(UNICODE)
# define SomeFunc SomeFuncW
#else
# define SomeFunc SomeFuncW
#endif
with
#if define(UNICODE)
inline void SomeFunc() {SomeFuncW();}
#else
inline void SomeFunc() {SomeFuncA();}
#endif
doesn't seem very sophisticated even
when different argument lists and return
types come into play.
We have several possible solutions we are investigating for future versions.

Ronald Laeremans
Visual C++ team
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #8
"Hendrik Schober" <Sp******@gmx.de> wrote in message
news:up**************@TK2MSFTNGP10.phx.gbl...
While the change would certainly impact
a lot of declarations in the Windows
headers, it would also be fairly simple.
Replacing
#if define(UNICODE)
# define SomeFunc SomeFuncW
#else
# define SomeFunc SomeFuncW
#endif
with
#if define(UNICODE)
inline void SomeFunc() {SomeFuncW();}
#else
inline void SomeFunc() {SomeFuncA();}
#endif
doesn't seem very sophisticated even
when different argument lists and return
types come into play.


Do all compilers understand inline?

Regards,
Will
Nov 17 '05 #9
William DePalo [MVP VC++] wrote:
"Hendrik Schober" <Sp******@gmx.de> wrote in message
news:up**************@TK2MSFTNGP10.phx.gbl...
While the change would certainly impact
a lot of declarations in the Windows
headers, it would also be fairly simple.
Replacing
#if define(UNICODE)
# define SomeFunc SomeFuncW
#else
# define SomeFunc SomeFuncW
#endif
with
#if define(UNICODE)
inline void SomeFunc() {SomeFuncW();}
#else
inline void SomeFunc() {SomeFuncA();}
#endif
doesn't seem very sophisticated even
when different argument lists and return
types come into play.


Do all compilers understand inline?


It is a keyword of the C++ standard language. If a compiler doesn't
understand it, I don't think MS should worry about it. Your point may be
that 'inline' doesn't force the compiler to actually inline the call, which
I believe is true. But if it doesn't inline the call, then I believe it must
create a function which represents it, and to which any call of SomeFunc
will be directed, so Mr. Schober's solution should still be OK.
Nov 17 '05 #10
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:O4*************@tk2msftngp13.phx.gbl...
Do all compilers understand inline?


It is a keyword of the C++ standard language. If a compiler doesn't
understand it, I don't think MS should worry about it.


I know. But should they worry about those still using the (old procedural)
API with C compilers?

Regards,
Will
Nov 17 '05 #11
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:OO**************@TK2MSFTNGP10.phx.gbl...
Thanks, Edward, for confirming what I'd determined, and for the
workaround. Doing the #undef MessageBox works, although it seems
really counterintuitive, undefining the specific thing that I want
defined. (I know, I'm just removing a prior redefinition of it, but
it still seems odd.)

Just to be thorough, I also checked what happened if I switched the
character set to Unicode in the project configuration. As expected,
MessageBox is now expanded to MessageBoxW, which is also unknown.

Can you shed any light on the reason behind this?
Macros in C++ get textually substituted before the compile sees
MessageBox::Show. So what the compiler sees, if you #include <windows.h>
before invoking MessageBox::Show is MessageBoxA::Show. Since there is no
MessageBoxA::Show the compilation fails. If you use the VC++ precompiler

to precompile your code to produce a .i file and view the .i file, you will see this yourself.


Right, understood. The question wasn't so much about *how* the macro
expansion in the preprocessor works, but about *why* such an absurd macro
exists in the first place.

But from looking at other messages in this thread, I think the answer can be
summed up pretty succinctly: "Oops!"

Cheers!

- Peter
Nov 17 '05 #12
Slows down builds by about 20%. We tried this as one of the possible
approaches.

Ronald

"Hendrik Schober" <Sp******@gmx.de> wrote in message
news:up**************@TK2MSFTNGP10.phx.gbl...
Ronald Laeremans [MSFT] <ro*****@online.microsoft.com> wrote:
We knew of this before we even needed to have the first test fail. The issue is just that this is simply the way the preprocessor works and that the kind of extensive change needed to the windows headers to avoid this is extremely scary.


While the change would certainly impact
a lot of declarations in the Windows
headers, it would also be fairly simple.
Replacing
#if define(UNICODE)
# define SomeFunc SomeFuncW
#else
# define SomeFunc SomeFuncW
#endif
with
#if define(UNICODE)
inline void SomeFunc() {SomeFuncW();}
#else
inline void SomeFunc() {SomeFuncA();}
#endif
doesn't seem very sophisticated even
when different argument lists and return
types come into play.
We have several possible solutions we are investigating for future versions.
Ronald Laeremans
Visual C++ team
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers

Nov 17 '05 #13
The answer is "yes, we do" we would have to protect this change within a
further C++ only block.

Ronald

"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:Ol**************@TK2MSFTNGP12.phx.gbl...
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:O4*************@tk2msftngp13.phx.gbl...
Do all compilers understand inline?


It is a keyword of the C++ standard language. If a compiler doesn't
understand it, I don't think MS should worry about it.


I know. But should they worry about those still using the (old procedural)
API with C compilers?

Regards,
Will

Nov 17 '05 #14
Hi Ron,
The answer is "yes, we do" we would have to protect this change within a
further C++ only block.


I know, it was a rhetorical question. But thanks for the clarification. <g>

Regards,
Will
Nov 17 '05 #15
Ronald Laeremans [MSFT] wrote:
Slows down builds by about 20%. We tried this as one of the possible
approaches.
Perhaps you should seek to find out why the build is slowed down by 20% and
correct that in your compiler. I am not a compiler writer but it is really
hard to see why an 'inline' would slow down the build process so much as
compared to a macro. Finally, in these days of very fast machines, is it not
possible to choose a clean solution to a difficult problem even if it does
"slows down builds by about 20%".

Ronald

"Hendrik Schober" <Sp******@gmx.de> wrote in message
news:up**************@TK2MSFTNGP10.phx.gbl...
Ronald Laeremans [MSFT] <ro*****@online.microsoft.com> wrote:
We knew of this before we even needed to have the first test fail.
The issue is just that this is simply the way the preprocessor
works and that the kind of extensive change needed to the windows
headers to avoid this is extremely scary.


While the change would certainly impact
a lot of declarations in the Windows
headers, it would also be fairly simple.
Replacing
#if define(UNICODE)
# define SomeFunc SomeFuncW
#else
# define SomeFunc SomeFuncW
#endif
with
#if define(UNICODE)
inline void SomeFunc() {SomeFuncW();}
#else
inline void SomeFunc() {SomeFuncA();}
#endif
doesn't seem very sophisticated even
when different argument lists and return
types come into play.
We have several possible solutions we are investigating for future
versions.

Ronald Laeremans
Visual C++ team
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers

Nov 17 '05 #16
William DePalo [MVP VC++] wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:O4*************@tk2msftngp13.phx.gbl...
Do all compilers understand inline?


It is a keyword of the C++ standard language. If a compiler doesn't
understand it, I don't think MS should worry about it.


I know. But should they worry about those still using the (old
procedural) API with C compilers?


One could put in #ifdef __cplusplus blocks to at least save those who
compile their source as C++ files the headache of macros changing the name
in .NET classes. I can't imagine that there are many programmers anymore who
use Windows and use the C programming language instead of the C++
programming language.
Nov 17 '05 #17
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:Oz**************@tk2msftngp13.phx.gbl...
I can't imagine that there are many programmers anymore who
use Windows and use the C programming language instead of the C++
programming language.


If we are talking about new development, I'd agree. I'd be willing to bet
that there is significant maintenance of old C code still.

Regards,
Will
Nov 17 '05 #18
William DePalo [MVP VC++] <wi***********@mvps.org> wrote:
[...]
Do all compilers understand inline?
C++ compilers do.
C compiler must not see this.
Regards,
Will

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #19
Ronald Laeremans [MSFT] <ro*****@online.microsoft.com> wrote:
Slows down builds by about 20%. We tried this as one of the possible
approaches.
Well, then I guess ways must be found to
avoid this.
If the compiler cannot cope with (so many)
included functions and if this cannot be
fixed, maybe the huge beast <windows.h>
can be cut down into smaller files each
representing a single one API. I hate the
dreaded <windows.h> anyway for forcing me
to spell out what I do _not_ want instead
of doing it the right way and say what I
want.
Ronald
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #20
My reply was more for the benefit of other people reading the thread. ;-)

Ronald

"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:uo**************@TK2MSFTNGP12.phx.gbl...
Hi Ron,
The answer is "yes, we do" we would have to protect this change within a
further C++ only block.
I know, it was a rhetorical question. But thanks for the clarification.

<g>
Regards,
Will

Nov 17 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Rich Tasker | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.