-3

I want to make a reusable function that I can reuse whenever I want to use a MessageBox but in the code below, there is an error saying:

  • identifier "Lmessage" is undefined

  • identifier "Ltitle" is undefined

  • 'Lmessage': undeclared identifier

  • 'Ltitle': undeclared identifier

#include <iostream>
#include <string>
#include <Windows.h>

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX

int takePrompt(int number, std::string message, std::string title) {
    return MessageBox(0, TEXT(message), TEXT(title), MB_YESNO);
}

int main() {
    if (takePrompt(0, "", "1") == IDYES) {
        MessageBox(0, TEXT(""), TEXT("1.1"), MB_ICONEXCLAMATION);
    } else {
        if (takePrompt(0, "", "2") == IDYES) {
            MessageBox(0, TEXT(""), TEXT("2"), MB_ICONEXCLAMATION);
        } else {
            while (takePrompt(0, "", "3") != IDNO) {
                if (takePrompt(0, "", "4") == IDYES) {
                    MessageBox(0, TEXT(""), TEXT("4.2"), MB_ICONEXCLAMATION);
                } else {
                    return 1;
                }
            }
        }
    }

    return 0;
}

I tried putting std::string title, message, but it did not solve the problem. I just want a reusable MessageBox that I can change and give value whenever I want to

1
  • TEXT is for string literals, not for variables. And Windows API being related to C is not familiar with C++ std::string. You can use std::string::c_str() to get a null terminated C string from the std::string, but if will work only for an ascii build, not a unicode one (or you can explicitly use MessageBoxA). You can make your takePrompt function accept parameters as expected by the Windows API, i.e. LPCTSTR for the strings. Commented Sep 7, 2024 at 12:43

2 Answers 2

1

Your are misusing TEXT here. You are giving it a variable, when it is a compile time macro that changes an ANSI constant character string into a wide one.

If your function expects 8 bits strings, you should not try to convert them to wide strings but directly use the ANSI version of MessageBox:

int takePrompt(int number, std::string message, std::string title) {
    return MessageBoxA(0, message.c_str(), title.c_str(), MB_YESNO);
}

But beware: this is a quick and dirty fix. It is fine if you are sure that your strings will never contain Unicode characters that are not representable in your ANSI locale...

Sign up to request clarification or add additional context in comments.

2 Comments

You are right. Fixed.
Calling the Unicode variants of APIs should be the default. Recommending the use of the ANSI variant (the "whatever" encoding) requires substantiation. The "UTF-8 Everywhere" mantra isn't.
1

The TEXT macro is roughly defined as

#ifdef UNICODE
  #define TEXT(quote) L##quote
#else
  #define TEXT(quote) quote
#endif

It is evaluated during pre-processing. In case the UNICODE preprocessor symbol is defined it applies the token pasting operator (##) that literally concatenates L and whatever quote expands to. It works for string literals but not with other symbols (like variable names). That's why you're getting those errors.

To fix the issue you'll have to do the following:

  • Remove all occurrences of TEXT.
  • Replace std::string with std::wstring.
  • Explicitly call the wide-character version of any API calls (e.g., MessageBoxW in place of the generic-text mapping macro MessageBox).
  • Pass the result of calling c_str to the API calls.
  • Use wide-character string literals throughout (e.g., L"" in place of "").
  • Forget that you ever knew that TEXT was a thing. It's a vestigial holdover from the times when targeting (pre-UnicoWS) Win9x was a real requirement.

1 Comment

"Replace std::string with std::wstring... Explicitly call the wide-character version of any API calls (e.g., MessageBoxW in place of the generic-text mapping macro MessageBox)" - or, keep using std::string, but use the narrow-character version of the APIs, like MessageBoxA().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.