2

I've been following a DirectInput tutorial and am having trouble printing a list of DirectInput device product names to a Windows console.

I'm using VS19's C++ compiler and am compiling with UNICODE defined. Since tszProductName is of type TCHAR which resolves to WCHAR I followed this stack overflow answer to allow the windows console to print unicode while also avoiding mixing wcout with cout in the same program.

Before I made those changes nothing was printed. Now the console prints '쳌' repeatedly for each device name. I tried switching from Unicode to Multibyte and going back to cout to no avail. Here is the code in question.

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma comment (lib,"dinput8.lib")
#pragma comment (lib,"dxguid.lib")

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <locale.h>
#include <clocale>
#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

IDirectInput8* dev;
std::vector<LPDIRECTINPUTDEVICE8> gameControllers;

BOOL CALLBACK enumGameControllers(LPCDIDEVICEINSTANCE devInst, LPVOID pvRef) {
    LPDIRECTINPUTDEVICE8 gameController;

    if (FAILED(dev->CreateDevice(devInst->guidInstance, &gameController, NULL)))
        return DIENUM_CONTINUE;
    else {
        gameControllers.push_back(gameController);
        return DIENUM_CONTINUE;
    }
}

int wmain(int argc, wchar_t* argv[]) {    
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    char* a = setlocale(LC_ALL, "en-US.UTF8");
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);

    CONSOLE_FONT_INFOEX fontInfo;
    fontInfo.cbSize = sizeof(fontInfo);
    fontInfo.FontFamily = 20;
    fontInfo.FontWeight = 400;
    fontInfo.nFont = 0;
    const wchar_t myFont[] = L"Lucida Console";
    fontInfo.dwFontSize = { 8, 16 };
    std::copy(myFont, myFont + _countof(myFont), fontInfo.FaceName);

    SetCurrentConsoleFontEx(hConsole, false, &fontInfo);
    
    if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dev, NULL))) {
        std::wcout << L"Critical error: Unable to create the main DirectInput 8 COM object!\n";
        return 1;
    }

    if (FAILED(dev->EnumDevices(DI8DEVCLASS_GAMECTRL, &enumGameControllers, NULL, DIEDFL_ATTACHEDONLY))) {
        std::wcout << L"Critical error: Unable to enumerate input devices!\n";
        return 1;
    }

    if (gameControllers.empty()) {
        std::wcout << L"No peripherals found\n";
        return 1;
    }

    int count = 1;
    std::wcout << L"Number of devices: " << gameControllers.size() << std::endl;   
    for (LPDIRECTINPUTDEVICE8 i : gameControllers) {
        DIDEVICEINSTANCE deviceInfo;
        i->GetDeviceInfo(&deviceInfo);
        std::wcout << L"Device Number " << count << L": ";
        
        std::wcout << deviceInfo.tszProductName << std::endl;

        if (FAILED(i->SetCooperativeLevel(GetConsoleWindow(), DISCL_BACKGROUND | DISCL_EXCLUSIVE))) {
            std::wcout << L"Cooperative level could not be set\n";
            return 1;
        }
        ++count;
    }
    return 0;
}

Thanks in advance for any suggestions and/or solutions.

Sencillo
  • 21
  • 1

1 Answers1

1
    DIDEVICEINSTANCE deviceInfo;
    i->GetDeviceInfo(&deviceInfo);

Problems with this code are that:

Change to the following, instead.

    DIDEVICEINSTANCE deviceInfo = { sizeof(DIDEVICEINSTANCE) };
    if(i->GetDeviceInfo(&deviceInfo) != DI_OK) { /* call failed, handle error */ }
dxiv
  • 16,984
  • 2
  • 27
  • 49