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\$
5
  • 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\$ Aug 5, 2018 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, 2018 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\$ Aug 5, 2018 at 16:07
  • \$\begingroup\$ Okay, gotcha. Just made myself a helper function: pastebin.com/LstCWUBt and it works perfectly! Thanks! \$\endgroup\$
    – Kerdo
    Aug 5, 2018 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, 2018 at 21:25

1 Answer 1

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\$
3
  • 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, 2018 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, 2018 at 9:05
  • \$\begingroup\$ "strlen(text)" should be placed outside of the loop, otherwise the length will be calculated at EACH iteration, neither automatic compiler optimization helps. \$\endgroup\$
    – Gro
    Aug 24, 2019 at 6:47

Not the answer you're looking for? Browse other questions tagged .