Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How can I use WINRT c++ APIs in at Qt WINRT app?
Forum Updated to NodeBB v4.3 + New Features

How can I use WINRT c++ APIs in at Qt WINRT app?

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
13 Posts 4 Posters 6.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Chris KawaC Chris Kawa

    Well, depending on the approach it's either smooth ride or a horror show. Here's a "world of pain" type example that gets current date using WRL and puts it on a Qt's label:

    #include <QApplication>
    #include <QLabel>
    
    #include <wrl/client.h>
    #include <wrl/wrappers/corewrappers.h>
    #include <windows.globalization.h>
    #include <windows.globalization.datetimeformatting.h>
    
    namespace WRL     = Microsoft::WRL;
    namespace Wrap    = Microsoft::WRL::Wrappers;
    namespace Fnd     = Windows::Foundation;
    namespace ABIFnd  = ABI::Windows::Foundation;
    namespace ABIGlob = ABI::Windows::Globalization;
    
    auto format = L"{year.full}-{month.integer(2)}-{day.integer(2)}";
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QLabel lbl;
        lbl.setAlignment(Qt::AlignCenter);
        lbl.show();
    
        //Qt initializes COM for us so we don't need to call RoInitialize
    
        WRL::ComPtr<ABIGlob::ICalendar> calendar;
        Wrap::HStringReference calendarClassId(RuntimeClass_Windows_Globalization_Calendar);
        if (SUCCEEDED(Fnd::ActivateInstance(calendarClassId.Get(), calendar.GetAddressOf())))
        {
           ABIFnd::DateTime dateTime;
           if (SUCCEEDED(calendar->GetDateTime(&dateTime)))
           {
               WRL::ComPtr<ABIGlob::DateTimeFormatting::IDateTimeFormatterFactory> dateTimeFormatterFactory;
               Wrap::HStringReference dateTimeFormatterId(RuntimeClass_Windows_Globalization_DateTimeFormatting_DateTimeFormatter);
               if (SUCCEEDED(Fnd::GetActivationFactory(dateTimeFormatterId.Get(), dateTimeFormatterFactory.GetAddressOf())))
               {
                   WRL::ComPtr<ABIGlob::DateTimeFormatting::IDateTimeFormatter> dateTimeFormatter;
                   Wrap::HStringReference dateTimeFormat(format);
                   if (SUCCEEDED(dateTimeFormatterFactory->CreateDateTimeFormatter(dateTimeFormat.Get(), dateTimeFormatter.GetAddressOf())))
                   {
                       Wrap::HString formattedDateTime;
                       if (SUCCEEDED(dateTimeFormatter->Format(dateTime, formattedDateTime.GetAddressOf())))
                       {
                           uint buff_len;
                           auto buff = formattedDateTime.GetRawBuffer(&buff_len);
    
                           lbl.setText(QString::fromWCharArray(buff, buff_len));
                       }
                   }
               }
           }
        }
    
        return a.exec();
    }
    

    And yes, before you manage to say "H O L Y    F U U U ..."  this is exactly the same as:

    #include <QApplication>
    #include <QLabel>
    #include <QDate>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QLabel lbl(QDate::currentDate().toString("yyyy-MM-dd"));
        lbl.setAlignment(Qt::AlignCenter);
        lbl.show();
    
        return a.exec();
    }
    

    To spare yourself from going absolutely insane you might want to look into wrapper libraries like Modern.

    R Offline
    R Offline
    Rad B
    wrote on last edited by Rad B
    #3

    @Chris-Kawa Thanks! I was actually hoping to use the HoloLens gestures as Qt has major problems with mouse and clicking on HoloLens. Or if Qt can be fixed I wouldn't have to.

    I need to make the mouse follow and make clicking work on HoloLens. Like before Tuesday, haha!

    M 1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by hskoglund
      #4

      Hi, thanks @Chris-Kawa for that example!

      Because I like to hurt myself I had to try it on my Windows 10 PC (worked fine).
      Just want to add, if you want to run it as well, you need to add:

      LIBS += -lruntimeobject
      

      to your .pro file.

      Edit: forgot to say: I tested with a vanilla Widgets app using the kit Desktop Qt 5.7.0 MSVC2015. However, if you instead select the Universal Windows Platform kit then that LIBS line above is not needed.

      1 Reply Last reply
      1
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #5

        As much as I hate language extensions it would probably be easier to use C++/CX. It would make the example not much longer than that with Qt, but I can't seem to enable it.
        Passing /ZW and /AI <path to Platform.winmd> to the compiler (via QMAKE_CXXFLAGS in .pro file) should be enough AFAIK, but I get errors on as simple line as this:

        String^ foo = ref new String(L"Hello");
        

        error: C2664: 'long __winRT::__getActivationFactoryByPCWSTR(void *,Platform::Guid &,void **)': cannot convert argument 1 from 'const wchar_t []' to 'void *'
        Probably some switch still missing somewhere...

        1 Reply Last reply
        1
        • hskoglundH Offline
          hskoglundH Offline
          hskoglund
          wrote on last edited by
          #6

          Hmm, never tried those pesky extensions, but being curious, I tried to reproduce your error but no luck :-( Maybe you're not on Windows 10 and MSVC2015?

          I got it to run with your example above, by adding #include <qdebug.h> and these lines just before return a.exec(); at the end:

          using namespace Platform;
          String^ foo = ref new String(L"Hello");
          qDebug() << QString::fromWCharArray(foo->Data());
          

          I tested both the 5.7.0 Desktop MSVC2015 32-bit and the Universal Windows Platform kit.

          And yeah, those /ZW and /AI switches (no space between /AI and dirname!) have to be in the .pro file:
          QMAKE_CXXFLAGS += /ZW /AI\"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages\"

          1 Reply Last reply
          2
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #7

            @hskoglund said:

            Maybe you're not on Windows 10 and MSVC2015?

            I'm on Win10 and MSVC2015 with Qt5.7UWP. Yeah, sorry, I mixed up my tests. The string alone works indeed, but try this full example and you should see the errors:

            #include <QApplication>
            #include <QLabel>
            
            using namespace Platform;
            using namespace Windows::Globalization;
            using namespace Windows::Globalization::DateTimeFormatting;
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
            
                auto calendar = ref new Calendar();
                auto dateTime = calendar->GetDateTime();
                String^ format = L"{year.full}-{month.integer(2)}-{day.integer(2)}";
                auto dateTimeFormatter = ref new DateTimeFormatter(format);
                auto formatted = dateTimeFormatter->Format(dateTime);
            
                QLabel lbl(QString::fromWCharArray(formatted->Data()));
                lbl.setAlignment(Qt::AlignCenter);
                lbl.show();
            
                return a.exec();
            }
            
            R 1 Reply Last reply
            0
            • Chris KawaC Chris Kawa

              @hskoglund said:

              Maybe you're not on Windows 10 and MSVC2015?

              I'm on Win10 and MSVC2015 with Qt5.7UWP. Yeah, sorry, I mixed up my tests. The string alone works indeed, but try this full example and you should see the errors:

              #include <QApplication>
              #include <QLabel>
              
              using namespace Platform;
              using namespace Windows::Globalization;
              using namespace Windows::Globalization::DateTimeFormatting;
              
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
              
                  auto calendar = ref new Calendar();
                  auto dateTime = calendar->GetDateTime();
                  String^ format = L"{year.full}-{month.integer(2)}-{day.integer(2)}";
                  auto dateTimeFormatter = ref new DateTimeFormatter(format);
                  auto formatted = dateTimeFormatter->Format(dateTime);
              
                  QLabel lbl(QString::fromWCharArray(formatted->Data()));
                  lbl.setAlignment(Qt::AlignCenter);
                  lbl.show();
              
                  return a.exec();
              }
              
              R Offline
              R Offline
              Rad B
              wrote on last edited by Rad B
              #8

              @Chris-Kawa @hskoglund

              Great information, Thanks!

              Unfortunately I don't think UWP HoloLens Gestures will work as it is 3D based and with a UWP app that's tough if not impossible. Well it would take some time and I have to have this project done before Tuesday. Probably not going to be possible.

              Unless either of you know how to do this:
              So the UWP apps are run in a container. Not sure if it is a Windows App Container or not but I want to be able to access the raw mouse & keyboard from the container level.

              Thanks so much for your help!

              1 Reply Last reply
              0
              • hskoglundH Offline
                hskoglundH Offline
                hskoglund
                wrote on last edited by hskoglund
                #9

                @Rad-B: Hi, I know games need to do this, and since some of them are UWP apps, raw mouse and keyboard access should be possible, for an example see stackoverflow

                @Chris-Kawa: Indeed this time I got the errors (2 of them):
                C:\Projects\untitled\main.cpp:23: error: C2664: 'long __winRT::__getActivationFactoryByPCWSTR(void *,Platform::Guid &,void **)': cannot convert argument 1 from 'const wchar_t [31]' to 'void *'

                Googling a bit it seems this interesting error has struck more people than you (i.e you have not forgotten any switch or something similar).

                So in conclusion I think this is a Monday morning bug and, while waiting for Microsoft to fix it (perhaps in Update 3?) you can always resort to a kludge, insert these fine lines of code just before int main(...:

                HRESULT __stdcall GetActivationFactoryByPCWSTR(void*,Guid&, void**);
                namespace __winRT
                {
                    HRESULT __stdcall __getActivationFactoryByPCWSTR(const void* str, ::Platform::Guid& pGuid, void** ppActivationFactory)
                    {
                        return GetActivationFactoryByPCWSTR(const_cast<void*>(str), pGuid, ppActivationFactory);
                    }
                }
                

                This will cast away that const problem for you :-)

                1 Reply Last reply
                1
                • Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by Chris Kawa
                  #10

                  @hskoglund Thanks for the workaround. I wonder how such a blatant bug could have slipped in :/

                  @Rad-B I don't have HoloLens so I can only speculate, but looking at the examples it doesn't seem to be that different from my calendar example, you just use the classes from the Windows::UI::Input::Spatial namespace. It seems the C++/CX is the easiest here, so you will probably have to use the workaround @hskoglund provided.
                  See here for some code examples (the SpatialInputHandler.h/.cpp files).

                  R 1 Reply Last reply
                  0
                  • Chris KawaC Chris Kawa

                    @hskoglund Thanks for the workaround. I wonder how such a blatant bug could have slipped in :/

                    @Rad-B I don't have HoloLens so I can only speculate, but looking at the examples it doesn't seem to be that different from my calendar example, you just use the classes from the Windows::UI::Input::Spatial namespace. It seems the C++/CX is the easiest here, so you will probably have to use the workaround @hskoglund provided.
                    See here for some code examples (the SpatialInputHandler.h/.cpp files).

                    R Offline
                    R Offline
                    Rad B
                    wrote on last edited by Rad B
                    #11

                    @Chris-Kawa @hskoglund How can I access Windows.UI.Core.CoreWindow?

                    namespace Windows::UI does not seem to work.

                    Thanks for both of your help!

                    1 Reply Last reply
                    0
                    • R Rad B

                      @Chris-Kawa Thanks! I was actually hoping to use the HoloLens gestures as Qt has major problems with mouse and clicking on HoloLens. Or if Qt can be fixed I wouldn't have to.

                      I need to make the mouse follow and make clicking work on HoloLens. Like before Tuesday, haha!

                      M Offline
                      M Offline
                      mkalinow
                      wrote on last edited by
                      #12

                      @Rad-B Sorry for being a bit late to the discussion, but input on Hololens should have been fixed by https://codereview.qt-project.org/#/c/170653/ . At least we got feedback on JIRA, that this resolves input problems...

                      1 Reply Last reply
                      2
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by Chris Kawa
                        #13

                        Hey, good news! After years of begging Microsoft released a WinRT C++ library that doesn't suck like WRL: C++/WinRT

                        It's actually kinda simple to use. Close to Qt if not for the long names and namespaces. I gave it a whirl with the calendar example:

                        #include <QApplication>
                        #include <QLabel>
                        #include "winrt/Windows.Globalization.h"
                        #include "winrt/Windows.Globalization.DateTimeFormatting.h"
                        
                        #pragma comment(lib, "windowsapp")
                        using namespace winrt::Windows::Globalization;
                        using namespace winrt::Windows::Globalization::DateTimeFormatting;
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                        
                            std::wstring formatted = DateTimeFormatter(L"{year.full}-{month.integer(2)}-{day.integer(2)}").Format(Calendar().GetDateTime());
                        
                            QLabel lbl(QString::fromWCharArray(formatted.c_str()));
                            lbl.setAlignment(Qt::AlignCenter);
                            lbl.show();
                        
                            return a.exec();
                        }
                        
                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved