如何在 MFC dialog-based 的 webviewWindow 组件初始化之外使用 "webviewWindow->Navigate()"?

How do you use "webviewWindow->Navigate()" from outside the initialization of the webviewWindow component in MFC dialog-based?

标题说明了一切。我承认我是 MFC 和 Webview2 的新手,但由于 Webview2 的“入门”部分,我已经有了一个显示 webview 的工作程序。但是我想通过函数调用让代码导航到不同的 url 来添加。这是我拥有的:

BOOL CMFCApplication1Dlg::OnInitDialog(){
    
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
    BOOL bNameValid;
    CString strAboutMenu;
    bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    ASSERT(bNameValid);
    if (!strAboutMenu.IsEmpty())
    {
        pSysMenu->AppendMenu(MF_SEPARATOR);
        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);         // Set big icon
SetIcon(m_hIcon, FALSE);        // Set small icon

// TODO: Add extra initialization here   

// this is where the WebView2 "Getting Started" code begins
HRESULT hresult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

// The main window class name.
static TCHAR szWindowClass[] = _T("DesktopApp");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("WebView sample");

// Pointer to WebViewController
static wil::com_ptr<ICoreWebView2Controller> webviewController;

// Pointer to WebView window
static wil::com_ptr<ICoreWebView2> webviewWindow;

HWND hWnd = GetSafeHwnd();
try {
    // Locate the browser and set up the environment for WebView
    CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
        Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
            [hWnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {

        // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
        env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
            [hWnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
            if (controller != nullptr) {
                webviewController = controller;
                webviewController->get_CoreWebView2(&webviewWindow);
            }

            // Add a few settings for the webview
            // The demo step is redundant since the values are the default settings
            ICoreWebView2Settings* Settings;
            webviewWindow->get_Settings(&Settings);
            Settings->put_IsScriptEnabled(TRUE);
            Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
            Settings->put_IsWebMessageEnabled(TRUE);

            // Resize WebView to fit the bounds of the parent window
            RECT bounds = { 0, 0, 1920, 1080 };
            webviewController->put_Bounds(bounds);

            // Schedule an async task to navigate to Bing
            webviewWindow->Navigate(L"https://www.bing.com/");

            // Step 4 - Navigation events


            // Step 5 - Scripting

            // Step 6 - Communication between host and web content

            return S_OK;
        }).Get());
        return S_OK;
    }).Get());
webviewWindow->Navigate(L"http://www.google.com");
}
catch (...) {
    MessageBoxW(L"can i bypass this null pointer? probably not", 0, MB_OK);
}

return TRUE;  // return TRUE  unless you set the focus to a control
}

当我发表评论时,所有这些都运行良好

webviewWindow->Navigate(L"http://www.google.com"); 

但问题是当我尝试导航到 google 块之外时定义了“webviewController”。 这是错误:

Exception thrown: read access violation.
webviewWindow.**m_ptr** was nullptr.

我查看了文档并四处寻找指南,但一无所获。

错误诊断表明,您正在尝试取消引用空指针。由于它方便地同时包含对象名称和原因,因此很明显您正试图在分配 webviewWindow 之前访问它。

webviewWindow 在这行代码中赋值给:

webviewController->get_CoreWebView2(&webviewWindow);

请注意,此代码位于作为 ICoreWebView2CreateCoreWebView2ControllerCompletedHandler 回调传递的匿名函数对象中。代码似乎是异步执行的,因此有可能在创建 WebView2 控件完成之前实际执行视觉上落后于创建代码的代码。

除此之外,与 WebView2 控件安全交互的最早时间来自其 ICoreWebView2CreateCoreWebView2ControllerCompletedHandler。如果您想导航到任何特定的 URL,您将不得不将该代码放入此回调中。如果有问题的代码是 运行 在非静态 class 成员中,您可以捕获 this 并在该实例上调用任何给定的 class 成员。