2009-11-13 9 views
4

Peut-on afficher une boîte de message Windows en utilisant la syntaxe cout? J'ai également besoin de la fenêtre d'invite de commande pour être supprimée/masquée.Afficher le message dans la boîte de dialogue Windows en utilisant "cout" - C++

Il existe des moyens d'appeler la fonction messagebox et le texte affiché à travers son utilisation, mais la contrainte principale ici est que la syntaxe de cout doit être utilisée.

cout << "message"; 

Je pensais d'invoquer la commande VB msgbox dans la sortie Cout, mais n'a pas pu trouver quelque chose qui a fonctionné.

Des idées?

+3

Si vous avez une application de console C++ et que vous essayez de la transformer en application Windows, c'est le moindre de vos soucis. –

+1

Combien de boîtes de dialogue 'cout <<" Bonjour "<< nom_utilisateur;' affichage? –

+0

@Dan - C'était une demande d'un instructeur de l'école où je travaille qui enseigne le C++ mais ne veut pas que les étudiants puissent accéder à la commande promopt. @Eric - juste 1 – CheeseConQueso

Répondre

9

La première chose à prendre en compte est que MessageBox arrête le thread jusqu'à ce que vous fermiez la fenêtre. Si c'est le comportement que vous désirez, allez-y.

Vous pouvez créer un streambuf personnalisé et le mettre à 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 
} 

Une fenêtre sera affiché chaque fois flux std :: Cout est rincé.

+0

eu des erreurs sur celui-ci ..... Im utilisant visual studio 08 si cela fait une différence – CheeseConQueso

+0

la première chose qu'il m'a dit était d'inclure stdafx.h .... après avoir compris cela, je J'ai eu un tas d'erreurs auxquelles je n'ai pas accès jusqu'à ce que cette personne soit de retour pour tester de nouvelles choses avec moi – CheeseConQueso

+0

Ces problèmes n'ont rien à voir avec ce code mais avec des options "en-têtes précompilés" dans votre projet. –

10

Les flux C++ fonctionnent avec les flux de console ou de fichier. Windows travaille sur un paradigme plus ou moins complètement différent, donc le contexte de cout n'est pas vraiment bon pour travailler avec ça. Vous pourriez probablement complètement écraser quelque chose qui finirait plus ou moins de travail, et à la recherche plus ou moins similaire à cette syntaxe, mais ce n'est pas vraiment la peine quand vous pouvez faire:

MessageBox(NULL, message, "", MB_OK); 

Voir les pleins docs MessageBox pour plus d'informations.

+0

ouais c'est ce que j'ai suggéré à cette personne, mais ils veulent cout faire partie de l'épreuve pour une raison obscure – CheeseConQueso

+0

Ils veulent Cout spécifiquement, ou ils veulent un flux similaire à cout? – Bill

+0

im 90% sûr qu'ils veulent Cout spécifiquement. c'est un instructeur et il va probablement le faire par le livre. ils ne veulent pas que les étudiants puissent accéder à l'invite de commande. – CheeseConQueso

3

Pas moyen de toute façon.

Le c dans cout est synonyme de console, donc vous n'avez probablement pas de chance. Si c'est juste la syntaxe que vous cherchez à copier, alors vous pouvez écrire votre propre classe de flux qui crée une boîte de message sous le capot et l'affiche.

+0

c'est ce que je lui ai dit ... cout = console – CheeseConQueso

+3

Il veut seulement la syntaxe cout-like, pas cout lui-même. Un fichier std :: ostringstream peut être utilisé pour créer la chaîne à transmettre à l'objet windows. Selon la réponse de Stephen Newell. – Clifford

+0

@Clifford, oui, je comprends qu'il pourrait seulement vouloir la syntaxe de flux. C'est pourquoi j'ai mentionné l'utilisation de sa propre classe de flux qui appelle la fonctionnalité de boîte de message sous le capot. peut-être que je n'étais pas assez clair .... – Glen

6

En incluant sstream, vous pouvez utiliser std::ostringstream et construire un message en utilisant la bibliothèque iostream. Vous pouvez ensuite appeler .str().c_str() et obtenir un char * pour passer à MessageBox.

1

Une boîte de message Windows peut-elle être affichée en utilisant la syntaxe cout?

Vous ne pouvez pas le faire avec std::cout. std::cout ne promet même pas de gérer les caractères Unicode/wide (voir std::wcout), bien que Windows cout n'a aucun problème avec les caractères larges.

Vous pouvez facilement le faire avec la même syntaxe ; c'est-à-dire, vous pouvez facilement écrire une bibliothèque qui surcharge operator<< pour afficher les boîtes de dialogue. Essayer de transmettre toutes les informations à la boîte de dialogue de cette façon serait très difficile (comment diriez-vous quels boutons montrer, ce que ces boutons devraient faire quand ils sont pressés, où ces boutons devraient être, et la taille et la position du fenêtre elle-même?).

Vous pouvez regarder quelque chose comme ncurses. La syntaxe est différente, mais j'ai un sentiment que c'est ce que votre collègue recherche.

6

Face à cela dans le passé, je l'ai utilisé un stringstream avec un manipulateur qui affiche le contenu actuel du stringstream en utilisant 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; 
} 

Pour l'utiliser, la syntaxe semble une bonne quantité comme en utilisant cout, mais avec MessageBox en remplacement de std::endl. Par exemple:

std::ostringstream stm; 
stm << " blah blah blah. Value: " << 1213.1231 << MessageBox; 

Modifier: principalement pour fnieto. Dans ce cas, le downcast vraiment est nécessaire. La raison est assez simple: un introducteur typique reçoit et renvoie une référence à un ostream:

std::ostream &operator<<(std::ostream &os, T const &t) { 
    // code here to insert t into os, then return os; 
} 

Cela prend l'objet stringstream d'origine et en silence (et en toute sécurité), il jette à simple ostream. C'est très bien en soi, et fonctionne bien pour la plupart des inserters et des manipulateurs, car ils interagissent uniquement avec l'interface ostream eux-mêmes.

Ce manipulateur, cependant, est un peu différent - il utilise le membre str(), que ostream ne définit pas du tout. Pour notre appel à str() pour résoudre et compiler, nous devons convertir le ostream & en un , ainsi le compilateur est conscient que l'objet que nous travaillons aura vraiment un membre str().

Pour éliminer le downcast, nous n'aurions vraiment qu'un seul choix: rendre son paramètre . Cela fonctionne aussi longtemps que nous ne opérateurs concaténés:

my_stream << x; 
my_stream << MessageBox; 

mais en essayant de enchaînez les manquerions:

// should be equivalent: 
my_stream << x << MessageBox; 

Pire encore, le message d'erreur du compilateur va probablement essayer de dire quelque chose d'utilisateur sur std::basic_ostream<char>::str(), ce qui n'est pas du tout mentionné dans le code de l'utilisateur. Pire encore, la plupart des gens sont suffisamment habitués à enchaîner ou ne pas donner des résultats identiques qu'il leur faudrait probablement un certain temps pour comprendre pourquoi le code fonctionnait parfois bien, et d'autres fois échouaient à compiler, avec un message d'erreur complètement indéchiffrable.

+1

+1 pour le manipulateur aproach –

Questions connexes