ukanth
ukanth

Reputation: 2968

How to write a generic alert message using win32?

I just want to expand this following method into something more generic, which should accept any kind of argument and display it using MessageBox():

void alert(char *item)
{
  MessageBox(NULL, item,  "Message", MB_OK | MB_ICONINFORMATION);
}

Can anyone help?

Upvotes: 1

Views: 15570

Answers (3)

Dewfy
Dewfy

Reputation: 23634

#include <sstream>
template<typename T>
void alert(T item)
{
//this accepts all types that supports operator << 
  std::ostringstream os;
  os << item;
  MessageBoxA(NULL, os.str().c_str(),  "Message", MB_OK | MB_ICONINFORMATION);
}

//now you need specialization for wide char
void alert(const wchar_t* item)
{

  MessageBoxW(NULL, item,  "Message", MB_OK | MB_ICONINFORMATION);
}

Upvotes: 4

Kirill V. Lyadvinsky
Kirill V. Lyadvinsky

Reputation: 99625

You could write something like the following:

template<typename T>
void alert(T item)
{
  MessageBox(NULL, boost::lexical_cast<std::string>(item).c_str(),  "Message", MB_OK | MB_ICONINFORMATION);
}

You should specialize boost::lexical_cast for any argument type you want since it supports limited range of types.


Another way is to use boost::format:

// helper class
class msg_helper_t {
public:
    msg_helper_t(const char* msg ) : fmt(msg) {}
    ~msg_helper_t() { 
        MessageBox(NULL, str( fmt ).c_str(),  "Message", MB_OK | MB_ICONINFORMATION); 
    }

    template <typename T>
    msg_helper_t& operator %(const T& value) {
        try {
            fmt % value;
        } catch ( std::exception e ) {
            // some exceptional actions
        }
        return *this;
    }
    template <>
    msg_helper_t& operator %(const CString& value) {
        try {
            fmt % value.GetString();
        } catch ( std::exception e ) {
            // some exceptional actions
        }
        return *this;
    }

protected:
    boost::format   fmt;
};

// our message function
msg_helper_t MyMsgBox(const char* msg) { return msg_helper_t( msg ); }

Later it could be used in the following way:

   MyMsgBox( "Hello with %d arguments: %s" ) % 2 % "some text";
   MyMsgBox( "%d" ) % 123456;
   MyMsgBox( "%f" ) % 10.5f;

Upvotes: 2

Nick Meyer
Nick Meyer

Reputation: 40332

Since C++ is statically typed, you'll probably need to do one of two things:

  1. Use a class hierarchy and have alert take a pointer/reference to a base class which contains some kind of virtual "toString()" function (the Java/.NET approach). The downside here is that alert() now only works for types in that class hierarchy.
  2. Overload the alert function for types that can't be directly converted to a string, with the downside that you have to duplicate code.

Also, you should make sure to use MessageBoxA if you're using ANSI strings, otherwise you should consider using TCHAR and MessageBox or wchar_t and MessageBoxW.

Upvotes: -1

Related Questions