0
\$\begingroup\$

I'm trying to display a game in the console window using a screen buffer but cannot compile it.

I have this simple code:

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

int main() {
  const int width = 120, height = 40;

  wchar_t* screen = new wchar_t[width * height];
  HANDLE console = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
  SetConsoleActiveScreenBuffer(console);
  DWORD bytesWritten = 0;

  while (true) {
    for (int i = 0; i < width * height; i++) screen[i] = L' ';
    wsprintf(&screen[width + 5], L"Testing");

    WriteConsoleOutputCharacter(console, screen, width * height, {0, 0}, &bytesWritten);
    Sleep(1000 / 30);
  }

  return 0;
}

It won't compile, getting two errors:

test.cpp:16:44: error: cannot convert 'wchar_t*' to 'LPSTR {aka char*}' for argument '1' to 'int wsprintfA(LPSTR, LPCSTR, ...)'

and

test.cpp:18:87: error: cannot convert 'wchar_t*' to 'LPCSTR {aka const char*}' for argument '2' to 'BOOL WriteConsoleOutputCharacterA(HANDLE, LPCSTR, DWORD, COORD, PDWORD)'

How can I get this working and how to do it even better?

I'm using g++ 6.3.0 to compile.

Thanks!

\$\endgroup\$
  • 1
    \$\begingroup\$ The error messages are saying wsprintf() and WriteConsoleOutputCharacterA() take char* not wchar_t* arguments. What happens when you change the type of screen to char* (and change the call to new to use char)? \$\endgroup\$ – user1118321 Aug 5 '18 at 15:59
  • \$\begingroup\$ Also changed WriteConsoleOutputCharacter() to WriteConsoleOutputCharacterA() and now it compiles. But VS Code outputs two error messages: argument of type "char *" is incompatible with parameter of type "LPWSTR" (15, 14) and argument of type "const char *" is incompatible with parameter of type "LPCWSTR" (15, 34) for wsprintf() \$\endgroup\$ – Kerdo Aug 5 '18 at 16:02
  • 1
    \$\begingroup\$ For what it's worth, the docs for wsprintfA() say not to use it. In any event, you need to make your screen variable be the same type as the parameter of the function you're calling. If it takes a wchar_t*, then screen should be wchar_t*. If the function takes a char* then screen should be a char*. \$\endgroup\$ – user1118321 Aug 5 '18 at 16:07
  • \$\begingroup\$ Okay, gotcha. Just made myself a helper function: pastebin.com/LstCWUBt and it works perfectly! Thanks! \$\endgroup\$ – Kerdo Aug 5 '18 at 16:13
  • 1
    \$\begingroup\$ @Kerdo if you've solved your problem, feel free to post it as an answer. This will make it more searchable, so other users with similar problems can learn from your solution. \$\endgroup\$ – DMGregory Aug 5 '18 at 21:25
0
\$\begingroup\$

Changed WriteConsoleOutputCharacter() to WriteConsoleOutputCharacterA(), ditched wsprintf(), changed screen[] type from wchar_t* to char* and made my own helper function for displaying on the screen and now it works perfectly!

void toScreen(char*& screen, const int index, const char* text) {
  for (int i = 0; i < strlen(text); i++)
    screen[index + i] = text[i];
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Reasonable. There's nothing inherently wrong with wchar_t, and it's often better, but you need to use the *W functions instead of *A functions. Newer Windows functions (after Windows ME, so 21st century) often do not have *A variants. \$\endgroup\$ – MSalters Aug 6 '18 at 9:59
  • \$\begingroup\$ @MSalters there are a lot of things inherently wrong with wchar_t, but on Windows it is still your best bet indeed :p \$\endgroup\$ – Quentin Aug 9 '18 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.