Visualizzazione dei messaggi in finestre finestra di dialogo con “cout” - C ++
-
20-09-2019 - |
Domanda
Può una finestra di messaggio di Windows essere display utilizzando la sintassi cout?
Ho bisogno anche la finestra del prompt dei comandi per essere soppresso / nascosto.
Ci sono modi per chiamare la funzione MessageBox e visualizzare il testo attraverso il suo utilizzo, ma il vincolo principale è che la sintassi cout deve essere utilizzato.
cout << "message";
Stavo pensando di invocare il comando VB msgbox nell'output cout, ma non ho trovato nulla che funzionasse.
Tutte le idee?
Soluzione
La prima cosa che si dovrebbe prendere in considerazione è che MessageBox interrompe il filo fino a quando si chiude la finestra. Se questo è il comportamento desiderato, andare avanti.
È possibile creare una streambuf personalizzato e impostarlo 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
}
Un pop-up verrà mostrato ogni volta flusso std :: cout viene svuotata.
Altri suggerimenti
flussi C ++ funzionano con flussi di console o di file. Finestre di lavoro su un paradigma più o meno completamente diversa, in modo che il contesto cout non è davvero una buona per lavorare con questo. Si potrebbe probabilmente completamente mash up qualcosa che finirebbe per più o meno di lavoro, e guardando più o meno simile a questa sintassi, ma non è davvero la pena quando solo si può fare:
MessageBox( NULL, message, "", MB_OK );
Vedere la documentazione completa su MessageBox per maggiori informazioni.
Con l'inclusione di sstream
, è possibile utilizzare std::ostringstream
e costruire un messaggio utilizzando la libreria iostream. È quindi possibile chiamare .str().c_str()
e ottenere un char *
da passare al MessageBox.
Di fronte a questo in passato, ho usato un stringstream
insieme a un manipolatore che visualizza il contenuto corrente del stringstream
utilizzando 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;
}
Per usare questo, la sintassi si presenta una discreta quantità come l'utilizzo di cout
, ma con la sostituzione MessageBox
std::endl
. Ad esempio:
std::ostringstream stm;
stm << " blah blah blah. Value: " << 1213.1231 << MessageBox;
Modifica: per lo più per fnieto. In questo caso, gli afflitti davvero è necessarie. La ragione è abbastanza semplice: un inseritore tipico riceve e restituisce un riferimento a un ostream:
std::ostream &operator<<(std::ostream &os, T const &t) {
// code here to insert t into os, then return os;
}
Questo prende l'oggetto stringstream originale e in silenzio (e sicuro) getta fino ad un semplice ostream. Questo va bene in se stesso, e funziona bene per la maggior parte inseritori e manipolatori, perché interagiscono solo con l'interfaccia ostream
stessi.
Questo manipolatore, però, è un po 'diverso - utilizza il membro str()
, che ostream
non definisce affatto. Per la nostra chiamata alla str()
per risolvere e compilare, dobbiamo convertire il ostream &
a un ostringstream &
, in modo che il compilatore è consapevole del fatto che l'oggetto stiamo lavorando con realtà avrà un membro str()
.
Per eliminare gli afflitti, ci piacerebbe davvero avere una sola scelta: fare il suo parametro di un ostringstream &
. Ciò funzionerà fino a quando non abbiamo mai incatenati operatori:
my_stream << x;
my_stream << MessageBox;
ma cercando di catena coloro fallirebbe:
// should be equivalent:
my_stream << x << MessageBox;
Peggio ancora, il messaggio di errore del compilatore probabilmente cercherà di dire all'utente qualcosa su std::basic_ostream<char>::str()
, che non è menzionato nel codice utente a tutti. Peggio ancora, la maggior parte delle persone sono sufficientemente abituati a concatenamento o non dare risultati identici che sarebbe probabilmente prendere un po 'per capire anche il motivo per cui il codice a volte funzionava bene, e altre volte non è riuscito a compilare, con un messaggio di errore del tutto indecifrabili.
Non c'è modo semplice in ogni caso.
Il c in cout è sinonimo di console, quindi probabilmente siete fuori di fortuna.
Se è solo la sintassi che stai cercando di copiare, allora si potrebbe scrivere la propria classe torrente che crea una finestra di messaggio sotto il cofano e lo visualizza.
Si consiglia di controllare questo fuori: Come posso reindirizzare stdout a un po 'di visualizzazione visibile in un'applicazione Windows?
Può una finestra di messaggio di Windows essere display utilizzando la sintassi cout?
Non si può farlo con std::cout
. std::cout
non ha nemmeno promette di gestire i caratteri Unicode / larghezza (vedi std::wcout
), anche se cout
di Windows non ha nessun problema con caratteri estesi.
Si potrebbe facilmente farlo con lo stesso sintassi ; che è, si potrebbe facilmente scrivere una libreria che sovraccarica operator<<
per visualizzare le finestre di dialogo. Cercando di passare tutte le informazioni per la finestra di dialogo in questo modo sarebbe molto difficile, anche se (come è possibile dire che i pulsanti per mostrare, che cosa quei bottoni dovrebbero fare quando viene premuto, se tali pulsanti dovrebbero essere, e la dimensione e la posizione del finestra stessa?).
Si consiglia di guardare qualcosa di simile a ncurses . La sintassi è diverso, ma ho una sensazione è quello che il vostro collega sta cercando.