Windows Runtime Library (WRL) and C++/MFC

Michael Sabo 26 Reputation points
2021-07-29T22:24:22.96+00:00

What's the best thread for a strange error in WRL?
Who are able to debugging the method OnLayout() on website Tablet mode

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,636 questions
{count} votes

Accepted answer
  1. RLWA32 43,306 Reputation points
    2021-08-11T10:05:46.367+00:00

    Using the sample code provided I reproduced the assertion.

    It seems that when the RoInitializeWrapper class is used within the CheckTabletMode method the runtime wants the MTA to exist. After making the following addition for the MTA the CheckTabletMode method no longer asserted with error 0x80070776.

    I used this helper class to create/destroy the MTA and used it within the CheckTabletMode method.

    class CMTA {
    public:
        CO_MTA_USAGE_COOKIE cookie{};
        HRESULT m_hr;
        CMTA() : m_hr(CoIncrementMTAUsage(&cookie)) { }
        ~CMTA() { if (SUCCEEDED(m_hr)) CoDecrementMTAUsage(cookie); }
        operator HRESULT() const { return m_hr; }
    };
    

    I also inserted a function to output the type of COM apartment that the thread was in after the RoInitializeWrapper object was instantiated.

    void QueryApartmentType()
    {
        APTTYPE aType{};
        APTTYPEQUALIFIER aQual{};
        CString strApt, strQual;
    
        HRESULT hr = CoGetApartmentType(&aType, &aQual);
        _ASSERT(SUCCEEDED(hr));
    
        switch (aType)
        {
        case APTTYPE_CURRENT:
            strApt = _T("Current thread");
            break;
        case APTTYPE_STA:
            strApt = _T("STA");
            break;
        case APTTYPE_MTA:
            strApt = _T("MTA");
            break;
        case APTTYPE_NA:
            strApt = _T("NA");
            break;
        case APTTYPE_MAINSTA:
            strApt = _T("Main STA");
            break;
        }
    
        switch (aQual)
        {
        case APTTYPEQUALIFIER_NONE:
            strQual = _T("None");
            break;
        case APTTYPEQUALIFIER_IMPLICIT_MTA:
            strQual = _T("Implicit MTA");
            break;
        case APTTYPEQUALIFIER_NA_ON_MTA:
            strQual = _T("NA on MTA");
            break;
        case APTTYPEQUALIFIER_NA_ON_STA:
            strQual = _T("NA on STA");
            break;
        case APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA:
            strQual = _T("NA on Implicit MTA");
            break;
        case APTTYPEQUALIFIER_NA_ON_MAINSTA:
            strQual = _T("NA on Main STA");
            break;
        case APTTYPEQUALIFIER_APPLICATION_STA:
            strQual = _T("Application STA");
            break;
        case APTTYPEQUALIFIER_RESERVED_1:
            strQual = _T("Reserved");
            break;
        }
    
        TRACE(_T("Apartment type : %s, Apartment type qualifier : %s\n"), strApt, strQual);
    }
    

    This is where the above were inserted in the CheckTabletMode method -

    bool CSampleDlg::CheckTabletMode(const bool bMultithreaded, const HWND hWnd)
    {
        //
        // COM-Initialisierung
        //
    
        CMTA mta; // Create the MTA
        _ASSERT(SUCCEEDED(mta));
    
        RO_INIT_TYPE com_thread_initialization = RO_INIT_SINGLETHREADED;
        if (bMultithreaded)
            com_thread_initialization = RO_INIT_MULTITHREADED;
    
        RoInitializeWrapper initialize(com_thread_initialization);
        _ASSERT(SUCCEEDED(initialize));
        if (FAILED(initialize))
        {
            SetLastError(0x1);
            return false;
        }
    
        // What Apartment is this thread in
        QueryApartmentType();
    

1 additional answer

Sort by: Most helpful
  1. Jeanine Zhang-MSFT 9,431 Reputation points Microsoft Vendor
    2021-08-09T08:05:25.66+00:00

    Hi,

    I suggest you could try to use ComPtr::GetAddressOf instead of &.

    For example:

    HRESULT hr = GetActivationFactory(  
        HStringReference(RuntimeClass_Windows_UI_ViewManagement_UIViewSettings).Get(),   
        uiViewSettingsInterop.GetAddressOf());  
    

    GetAddressOf - Retrieves the address of the ptr_ data member, which contains a pointer to the interface represented by this ComPtr.

    Operator& - Releases the interface associated with this ComPtr object and then retrieves the address of the ComPtr object.

    Best Regards,

    Jeanine


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.