interface ICoreWebView2Experimental2

Note

This reference is no longer being maintained. For the latest API reference, see WebView2 API Reference.

Note

This an experimental API that is shipped with our prerelease SDK. See WebView2 release notes.

interface ICoreWebView2Experimental2
  : public IUnknown

This is the ICoreWebView2 Experimental interface to support the DownloadStarting event.

Summary

Members Descriptions
add_DownloadStarting Add an event handler for the DownloadStarting event.
remove_DownloadStarting Remove an event handler previously added with add_DownloadStarting.

Applies to

Product Introduced
WebView2 Win32 N/A
WebView2 Win32 Prerelease 1.0.721

Members

add_DownloadStarting

Add an event handler for the DownloadStarting event.

public HRESULT add_DownloadStarting(ICoreWebView2ExperimentalDownloadStartingEventHandler * eventHandler, EventRegistrationToken * token)

This event is raised when a download has begun, blocking the default download dialog, but not blocking the progress of the download.

The host can choose to cancel a download, change the result file path, and hide the default download dialog. If the host chooses to cancel the download, the download is not saved, no dialog is shown, and the state is changed to COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED with interrupt reason COREWEBVIEW2_DOWNLOAD_INTERRUPT_REASON_USER_CANCELED. Otherwise, the download is saved to the default path after the event completes, and default download dialog is shown if the host did not choose to hide it. The host can change the visibility of the download dialog using the Handled property. If the event is not handled, downloads complete normally with the default dialog shown.

    // Register a handler for the `DownloadStarting` event.
    // This example hides the default download dialog and shows a dialog box instead.
    // The dialog box displays the default result file path and allows the user to specify a different path.
    // Selecting `OK` will save the download to the chosen path.
    // Selecting `CANCEL` will cancel the download.
    m_demoUri = L"https://demo.smartscreen.msft.net/";

    m_webViewExperimental2 = m_webView.try_query<ICoreWebView2Experimental2>();
    if (m_webViewExperimental2) {
        CHECK_FAILURE(m_webViewExperimental2->add_DownloadStarting(
            Callback<ICoreWebView2ExperimentalDownloadStartingEventHandler>(
                [this](
                    ICoreWebView2* sender,
                    ICoreWebView2ExperimentalDownloadStartingEventArgs* args) -> HRESULT
                {
                    // We avoid potential reentrancy from running a message loop in the download
                    // starting event handler by showing our download dialog via this lambda run
                    // asynchronously later outside of this event handler. Note that a long running
                    // synchronous UI prompt or other blocking item on the UI thread can potentially
                    // block the WebView2 from doing anything.
                    auto showDialog = [this, args]
                    {
                        // Hide the default download dialog.
                        CHECK_FAILURE(args->put_Handled(TRUE));

                        wil::com_ptr<ICoreWebView2ExperimentalDownloadOperation> download;
                        CHECK_FAILURE(args->get_DownloadOperation(&download));

                        INT64 totalBytesToReceive = 0;
                        CHECK_FAILURE(download->get_TotalBytesToReceive(&totalBytesToReceive));

                        wil::unique_cotaskmem_string uri;
                        CHECK_FAILURE(download->get_Uri(&uri));

                        wil::unique_cotaskmem_string mimeType;
                        CHECK_FAILURE(download->get_MimeType(&mimeType));

                        wil::unique_cotaskmem_string contentDisposition;
                        CHECK_FAILURE(download->get_ContentDisposition(&contentDisposition));

                        // Get the suggested path from the event args.
                        wil::unique_cotaskmem_string resultFilePath;
                        CHECK_FAILURE(args->get_ResultFilePath(&resultFilePath));

                        std::wstring prompt =
                            std::wstring(
                                L"Enter result file path or select `OK` to use default path. "
                                L"Select `Cancel` to cancel the download.");

                        std::wstring description = std::wstring(L"URI: ") + uri.get() + L"\r\n" +
                                                    L"Mime type: " + mimeType.get() + L"\r\n";
                        if (totalBytesToReceive >= 0)
                        {
                            description = description + L"Total bytes to receive: " +
                                          std::to_wstring(totalBytesToReceive) + L"\r\n";
                        }

                        TextInputDialog dialog(
                            m_appWindow->GetMainWindow(), L"Download Starting", prompt.c_str(),
                            description.c_str(), resultFilePath.get());
                        if (dialog.confirmed)
                        {
                            // If user selects `OK`, the download will complete normally.
                            // Result file path will be updated if a new one was provided.
                            CHECK_FAILURE(args->put_ResultFilePath(dialog.input.c_str()));
                            UpdateProgress(download.get());
                        }
                        else
                        {
                            // If user selects `Cancel`, the download will be canceled.
                            CHECK_FAILURE(args->put_Cancel(TRUE));
                        }
                    };

                    // Obtain a deferral for the event so that the CoreWebView2
                    // doesn't examine the properties we set on the event args until
                    // after we call the Complete method asynchronously later.
                    wil::com_ptr<ICoreWebView2Deferral> deferral;
                    CHECK_FAILURE(args->GetDeferral(&deferral));

                    // This function can be called to show the download dialog and
                    // complete the event at a later time, allowing the developer to
                    // perform async work before the event completes.
                    m_completeDeferredDownloadEvent = [showDialog, deferral] {
                        showDialog();
                        CHECK_FAILURE(deferral->Complete());
                    };

                    return S_OK;
                })
                .Get(),
            &m_downloadStartingToken));
    }

remove_DownloadStarting

Remove an event handler previously added with add_DownloadStarting.

public HRESULT remove_DownloadStarting(EventRegistrationToken token)