Display message in windows dialogue box using "cout" - C++
Can a windows message box be display using the cout syntax?
I also need the command prompt window to be suppressed / hidden.
There are ways to call the messagebox function and display text through its usage, but the main constraint here is that cout syntax must be used.
cout << "message";
I was t开发者_运维问答hinking of invoking the VB msgbox command in the cout output, but couldn't find anything that worked.
Any ideas?
C++ streams work with console or file streams. Windows work on a more or less completely different paradigm, so the cout context isn't really a good one for working with this. You could probably completely mash up something that would end up more or less working, and looking more or less similar to this syntax, but it's not really worth it when you can just do:
MessageBox( NULL, message, "", MB_OK );
See the full docs on MessageBox for more info.
First thing you should take into account is that MessageBox stops the thread until you close the window. If that is the behavior you desire, go ahead.
You can create a custom streambuf and set it to std::cout
:
#include <windows.h>
#include <sstream>
#include <iostream>
namespace {
class mb_streambuf : public std::stringbuf {
virtual ~mb_streambuf() { if (str().size() > 0) sync(); }
virtual int sync() {
MessageBoxA(0, str().c_str(), "", MB_OK);
str("");
return 0;
}
} mb_buf;
struct static_initializer {
static_initializer() {
std::cout.rdbuf(&mb_buf);
}
} cout_buffer_switch;
}
int main()
{
std::cout << "Hello \nworld!"; // Will show a popup
}
A popup will be shown whenever std::cout stream is flushed.
By including sstream
, you can use std::ostringstream
and build a message using the iostream library. You can then call .str().c_str()
and get a char *
to pass to MessageBox.
When confronted with this in the past, I've used a stringstream
along with a manipulator that displays the current contents of the stringstream
using MessageBox
:
#include <windows.h>
#include <sstream>
#include <ostream>
std::ostream &MessageBox(std::ostream &s) {
std::ostringstream *st = dynamic_cast<std::ostringstream *>(&s);
if (NULL != st)
::MessageBox(NULL, st->str().c_str(), "", MB_OK);
return s;
}
To use this, the syntax looks a fair amount like using cout
, but with MessageBox
replacing std::endl
. For example:
std::ostringstream stm;
stm << " blah blah blah. Value: " << 1213.1231 << MessageBox;
Edit: mostly for fnieto. In this case, the downcast really is necessary. The reason is fairly simple: a typical inserter receives and returns a reference to an ostream:
std::ostream &operator<<(std::ostream &os, T const &t) {
// code here to insert t into os, then return os;
}
This takes the original stringstream object and silently (and safely) casts it up to a simple ostream. That's fine in itself, and works fine for most inserters and manipulators, because they only interact with the ostream
interface themselves.
This manipulator, however, is a bit different -- it uses the str()
member, which ostream
doesn't define at all. For our call to str()
to resolve and compile, we have to convert the ostream &
to an ostringstream &
, so the compiler is aware that the object we're working with really will have a str()
member.
To eliminate the downcast, we'd really only have one choice: make its parameter an ostringstream &
. That would work as long as we never chained operators:
my_stream << x;
my_stream << MessageBox;
but trying to chain those would fail:
// should be equivalent:
my_stream << x << MessageBox;
Worse, the compiler's error message will probably try to tell the user something about std::basic_ostream<char>::str()
, which isn't mentioned in the user's code at all. Worse still, most people are sufficiently accustomed to chaining or not giving identical results that it would probably take them a while to even figure out why the code sometimes worked fine, and other times failed to compile, with a completely indecipherable error message.
No simple way anyway.
The c in cout stands for console, so you're probably out of luck.
If it's just the syntax you're looking to copy, then you could write your own stream class that creates a message box under the hood and displays it.
You may want to check this out: How can I redirect stdout to some visible display in a Windows Application?
Can a windows message box be display using the cout syntax?
You can't do it with std::cout
. std::cout
doesn't even promise to handle Unicode/wide characters (see std::wcout
), although Windows's cout
has no trouble with wide characters.
You could easily do it with the same syntax; that is, you could easily write a library that overloads operator<<
to display dialog boxes. Trying to pass all the information to the dialog box that way would be very difficult, though (how would you you say which buttons to show, what those buttons should do when pressed, where those buttons should be, and the size and position of the window itself?).
You may want to look at something like ncurses. The syntax is different, but I have a feeling it's what your coworker is looking for.
精彩评论