Guy Joel McLean
Guy Joel McLean

Reputation: 1049

Cannot match the parameter list for MessageBox::Show

I'm attempting to display the Error message denoted by the code given to me by GetLastError() and formatted by FormatMessage() within a MessageBox. (Using C++/CLI)
However for some reason I just can't match the argument list of MessageBox::Show.
I'm attempting to replicate a solution provided by Doron Moraz in this forum thread: http://forums.codeguru.com/showthread.php?478858-GetLastError()-in-a-MessageBox()

However when I attempt to compile my code I get:

'System::Windows::Forms::MessageBox::Show' : none of the 21 overloads could convert all the argument types
1>          c:\program files (x86)\reference assemblies\microsoft\framework\.netframework\v4.0\system.windows.forms.dll: could be 'System::Windows::Forms::DialogResult System::Windows::Forms::MessageBox::Show(System::String ^,System::String ^,System::Windows::Forms::MessageBoxButtons,System::Windows::Forms::MessageBoxIcon)'
1>          c:\program files (x86)\reference assemblies\microsoft\framework\.netframework\v4.0\system.windows.forms.dll: or       'System::Windows::Forms::DialogResult System::Windows::Forms::MessageBox::Show(System::Windows::Forms::IWin32Window ^,System::String ^,System::String ^,System::Windows::Forms::MessageBoxButtons)'
1>          while trying to match the argument list '(int, LPCTSTR, const wchar_t [6], long)'

As you can see below my code is fairly similar to the solution provided at the link. only I get the above error. The question is, Why? (see my code below).

if((m_hglrc = wglCreateContext(m_hDC)) == NULL)//if the creation of a wgl context fails
                {
                    MessageBox::Show("wglCreateContext Failed");//let us know

                    void* lpBuffer; //create a buffer to hold our error message

                        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,               // It´s a system error
                        NULL,                                      // No string to be formatted needed
                        ::GetLastError(),                               // Hey Windows: Please explain this error!
                        MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),  // Do it in the standard language
                        (LPTSTR)&lpBuffer,                                 // Put the message here
                        0,                     // Number of bytes to store the message
                        NULL);

                    System::Windows::Forms::MessageBox::Show( NULL, (LPCTSTR)lpBuffer, _T("Error"),MB_OK|MB_ICONWARNING);

                    // Free the buffer.
                    if(lpBuffer)LocalFree(lpBuffer);


                    return 0;
                }

In case it's relevant, my includes are:

#pragma once

#include <Windows.h>
#include <GL/gl.h>
#include<tchar.h>

using namespace System::Windows::Forms;

Thanks in advance,
Guy

Upvotes: 0

Views: 1093

Answers (1)

David Yaw
David Yaw

Reputation: 27864

It looks like you've solved this by switching to the unmanaged API, but here's how you'd use the managed one.

If you're going to use the a managed API, you'll want to use managed objects. In your call to MessageBox::Show, you have several unmanaged objects. According to the error message, it interpreted your parameters like this:

MessageBox::Show( NULL, (LPCTSTR)lpBuffer, _T("Error"),MB_OK|MB_ICONWARNING);
// seen by compiler as: int, LPCTSTR, const wchar_t [6], long

Here's the method I think you're trying to call in the MessageBox class:

Show(IWin32Window^ owner, String^ text, String^ caption, 
    MessageBoxButtons buttons, MessageBoxIcon icon)
  • NULL is generally #defined as 0, which is an integer. To produce a proper null pointer in C++/CLI, you want to use nullptr.
  • Both lpBuffer and "Error" need to be managed string objects.
    • For lpBuffer, you can just do gcnew String(lpBuffer), and it'll invoke the proper constructor (the one that takes a wide or narrow character pointer).
    • For "Error", just remove the _T(). The compiler will figure out that you want a managed string object and will provide one containing "Error".
  • In the managed API, the buttons & icon are contained in separate enums. You're referencing the unmanaged integer values here. You'll want to replace this with separate parameters for MessageBoxButtons and MessageBoxIcon.

Once all that is done, here's the final call:

MessageBox::Show(nullptr, gcnew String(lpBuffer), "Error", 
    MessageBoxButtons::OK, MessageBoxIcon::Warning);

However, we can do a little better: If you're not going to pass in a owner window, don't call the API that has a owner window parameter, call the API that doesn't.

MessageBox::Show(gcnew String(lpBuffer), "Error", 
    MessageBoxButtons::OK, MessageBoxIcon::Warning);

Upvotes: 2

Related Questions