Using WinRT/CPP with QT 6.x.x.
-
Thanks for the help.
I was able to compile it but apparently i could not used the "/await:strict" compiler switch. Something to do with experimental coroutines? Probably old libraries.What I have done is the following:
CONFIG += c++20 QMAKE_CXXFLAGS += "/Zc:__cplusplus" "/Zc:twoPhase-" DEFINES += _SILENCE_CLANG_COROUTINE_MESSAGE #this is needed as apparently the coroutine include is experimental/unsupported? win32:LIBS += -lwindowsapp
Apparently it might be the Qt's intellisense that is stating that there's "no member named 'wait_for' in namespace winrt::impl".
Now, trying to actually use the functions is not working right...
Apparently "a function that returns 'auto' cannot be used before it is defined" is happening.And trying to use this example, is resulting in a bit of errors...
I'll see about running some msvc build tools updates...
-
I'm on the latest VS2022 and Windows SDK and that example, slightly modified, compiles ok:
.pro
QT += core gui widgets CONFIG += c++20 QMAKE_CXXFLAGS += /await:strict SOURCES += main.cpp LIBS += -lwindowsapp
main.cpp
#include <winrt/Windows.Foundation.Collections.h> #include <winrt/Windows.Gaming.Input.h> using namespace winrt; using namespace Windows::Gaming::Input; int main() { std::vector<RawGameController> myRawGameControllers; for (auto const& rawGameController : RawGameController::RawGameControllers()) { auto it{ std::find(begin(myRawGameControllers), end(myRawGameControllers), rawGameController) }; if (it == end(myRawGameControllers)) { myRawGameControllers.push_back(rawGameController); } } }
Note that I'm not using any coroutines here, so the await switch is not necessary in this case.
Also no devices are found for me, but I think you need to have a winrt window (or any window) for that. For console apps the older XInput api is recommended instead. -
Using VS 2019, though i believe i've updated my libraries...
Here's the errors:
And here's the compilers that im using for MSVC with Qt 6.3.0:
I had removed an old sdk (and apparently only installed the win 11 sdk XP) but the win 11 sdk says it's version 10.0.22000.0, gonna install the "latest" win 10 sdk, which it's version is 10.0.20348.0.
-
Hi Chris, thanks for the explanation of the COM fighting, indeed it would be easier if Qt allowed different COM apartment flavors.
I also tried that sample, I installed VS2019 16.11.13 and on Windows 10 21H2 Build 19044.1645. I have not installed any special SDK, just Visual Studio and Qt 6.3.0. It copied it the C++/WinRT example verbatim (but I hat to remove that line with "..." :-)
it compiled cleanly for me, I reused the mainwindow.cpp from my sample above and replaced it with this:#include "mainwindow.h" #include "ui_mainwindow.h" #include "qtimer.h" #include "qdebug.h" #pragma comment(lib, "windowsapp") #include <winrt/Windows.Foundation.Collections.h> #include <concrt.h> #include <winrt/Windows.Gaming.Input.h> using namespace winrt; using namespace Windows::Gaming::Input; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); std::vector<RawGameController> myRawGameControllers; concurrency::critical_section myLock{}; for (auto const& rawGameController : RawGameController::RawGameControllers()) { // Test whether the raw game controller is already in myRawGameControllers; if it isn't, add it. concurrency::critical_section::scoped_lock lock{ myLock }; auto it{ std::find(begin(myRawGameControllers), end(myRawGameControllers), rawGameController) }; if (it == end(myRawGameControllers)) { // This code assumes that you're interested in all raw game controllers. myRawGameControllers.push_back(rawGameController); } } QTimer::singleShot(10,[] { qApp->quit(); }); } MainWindow::~MainWindow() { delete ui; }
So to make it compile. check that you have updated your Visual Studio 2019.
And also I have no controllers to test with. Perhaps you have any Game Controller stuff or example using a mouse or keyboard we can try? -
@alatnet Make sure you have
#include <winrt/Windows.Foundation.Collections.h>
. The example is missing it and that's where the begin/end functions are. -
@alatnet Make sure you have
#include <winrt/Windows.Foundation.Collections.h>
. The example is missing it and that's where the begin/end functions are.@Chris-Kawa Yes, nice catch!
(I happened to have that #include from the sample above, in mainwindow.h, that's why it compiled ok for me.) -
yep, that got me compiling with no issues!
Added "#include <winrt/Windows.Foundation.Collections.h>".Now, i have a controller connected, via bluetooth (ps4 controller), and it's outputting some strange stuff when i use:
for (RawGameController c : myRawGameControllers){ qDebug() << "- " << c.DisplayName(); }
which is:
onecoreuap\xbox\devices\api\winrt\pnpapiwrapper.cpp(385)\Windows.Gaming.Input.dll!00007FFC5E04974A: (caller: 00007FFC5E04D528) ReturnHr(1) tid(1784) 8685C003 onecoreuap\xbox\devices\api\winrt\pnpapiwrapper.cpp(385)\Windows.Gaming.Input.dll!00007FFC5E04974A: (caller: 00007FFC5E04D528) ReturnHr(2) tid(1784) 8685C003 onecoreuap\xbox\devices\api\winrt\pnpapiwrapper.cpp(385)\Windows.Gaming.Input.dll!00007FFC5E04974A: (caller: 00007FFC5E04D528) ReturnHr(3) tid(1784) 8685C003 onecoreuap\xbox\devices\api\winrt\pnpapiwrapper.cpp(385)\Windows.Gaming.Input.dll!00007FFC5E04974A: (caller: 00007FFC5E04D528) ReturnHr(4) tid(1784) 8685C003 onecoreuap\xbox\devices\api\winrt\pnpapiwrapper.cpp(385)\Windows.Gaming.Input.dll!00007FFC5E04974A: (caller: 00007FFC5E04D528) ReturnHr(5) tid(1784) 8685C003 ... mincore\com\oleaut32\dispatch\ups.cpp(2122)\OLEAUT32.dll!00007FFC6A509DD6: (caller: 00007FFC6A5091E9) ReturnHr(1) tid(5f44) 8002801D Library not registered.
Note: i am doing test code with it being in the main function and after the QApplication a(argc, argv);.
Edit: did test it in my direct input code where i stuck it in a section of code that queried a list of devices, same thing. -
Hi, haven't got any game controllers so I cannot test, but it looks like you're getting exceptions thrown. Just guessing but maybe it's a permissions thing, perhaps you need to run as an Administrator and make sure you've enabled developer mode.
Edit: update: also see this StackOverflow post
-
ok, got it working!
Added "-lOLEAUT32" to win32:LIBS and added the following to the separate QThreads run function (whenever i used them) and the main function:winrt::uninit_apartment(); winrt::init_apartment();
So to condense all of this into one post (for those who are also trying to do what im doing):
.pro:CONFIG += c++20 QMAKE_CXXFLAGS += /await:strict win32:LIBS += -lwindowsapp -lOLEAUT32
main.cpp:
#include <winrt/base.h> int main(int argc, char *argv[]) { QApplication a(argc, argv); winrt::uninit_apartment(); winrt::init_apartment(); return a.exec(); }
QThread derived classes:
#include <winrt/base.h> class DerivedThread : public QThread { public: DerivedThread (QThread* parent = nullptr) : QThread(parent) {} public: void run(){ winrt::uninit_apartment(); winrt::init_apartment(); exec(); } };
Those alone should get everything up and running to be able to use functions (aside from specific things like things requiring other things [looking at you collections...])
Now to create some qobject classes and get test out actual inputs!
Thank you all for your help!Oh! Almost forgot this tidbit, make sure your build tools/sdk's are up to date!
EDIT: Looks like derived threads dont need to have the unint/init_appartment functions.