Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update projects to use latest WebView2 1.0.2526 prerelease #242

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions SampleApps/WebView2APISample/AppWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@
#include "ScenarioDOMContentLoaded.h"
#include "ScenarioDragDrop.h"
#include "ScenarioExtensionsManagement.h"
#include "ScenarioFileSystemHandleShare.h"
#include "ScenarioIFrameDevicePermission.h"
#include "ScenarioNavigateWithWebResourceRequest.h"
#include "ScenarioNonClientRegionSupport.h"
#include "ScenarioNotificationReceived.h"
#include "ScenarioPermissionManagement.h"
#include "ScenarioFileSystemHandleShare.h"
#include "ScenarioSaveAs.h"
#include "ScenarioSharedBuffer.h"
#include "ScenarioSharedWorkerWRR.h"
#include "ScenarioVirtualHostMappingForPopUpWindow.h"
Expand Down Expand Up @@ -1334,11 +1335,11 @@ void AppWindow::InitializeWebView()
CHECK_FAILURE(options6->put_AreBrowserExtensionsEnabled(TRUE));
}

Microsoft::WRL::ComPtr<ICoreWebView2ExperimentalEnvironmentOptions2> exp_options2;
if (options.As(&exp_options2) == S_OK)
Microsoft::WRL::ComPtr<ICoreWebView2EnvironmentOptions8> options8;
if (options.As(&options8) == S_OK)
{
COREWEBVIEW2_SCROLLBAR_STYLE style = COREWEBVIEW2_SCROLLBAR_STYLE_FLUENT_OVERLAY;
CHECK_FAILURE(exp_options2->put_ScrollBarStyle(style));
CHECK_FAILURE(options8->put_ScrollBarStyle(style));
}

HRESULT hr = CreateCoreWebView2EnvironmentWithOptions(
Expand Down Expand Up @@ -1609,6 +1610,8 @@ HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(
}
NewComponent<ScenarioPermissionManagement>(this);
NewComponent<ScenarioNotificationReceived>(this);
NewComponent<ScenarioSaveAs>(this);

// We have a few of our own event handlers to register here as well
RegisterEventHandlers();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ ScenarioFileSystemHandleShare::ScenarioFileSystemHandleShare(AppWindow* appWindo
ScenarioFileSystemHandleShare::~ScenarioFileSystemHandleShare()
{
CHECK_FAILURE(m_webView->remove_WebMessageReceived(m_navigationCompletedToken));
}
}
235 changes: 235 additions & 0 deletions SampleApps/WebView2APISample/ScenarioSaveAs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "stdafx.h"

#include "ScenarioSaveAs.h"

#include "App.h"
#include "AppWindow.h"
#include "CheckFailure.h"
#include "Shlwapi.h"
#include "TextInputDialog.h"
#include "resource.h"

using namespace Microsoft::WRL;

ScenarioSaveAs::ScenarioSaveAs(AppWindow* appWindow)
: m_appWindow(appWindow), m_webView(appWindow->GetWebView())
{
if (m_webView)
{
m_webView2Experimental25 = m_webView.try_query<ICoreWebView2Experimental25>();
}
}

std::initializer_list<COREWEBVIEW2_SAVE_AS_KIND> saveAsKind{
COREWEBVIEW2_SAVE_AS_KIND_DEFAULT, COREWEBVIEW2_SAVE_AS_KIND_HTML_ONLY,
COREWEBVIEW2_SAVE_AS_KIND_SINGLE_FILE, COREWEBVIEW2_SAVE_AS_KIND_COMPLETE};
// Sync with COREWEBVIEW2_SAVE_AS_KIND.
std::array<std::wstring, 4> saveAsKindString{
L"DEFAULT", L"HTML_ONLY", L"SIGNLE_FILE", L"COMPLETE"};
// Sync with COREWEBVIEW2_SAVE_AS_UI_RESULTS.
std::array<std::wstring, 5> saveAsUIResultString{
L"SUCCESS", L"INVALID_PATH", L"FILE_ALREADY_EXISTS", L"KIND_NOT_SUPPORTED", L"CANCELLED"};

//! [ToggleSilent]
// Turn on/off Silent SaveAs, which won't show the system default save as dialog.
// This example hides the default save as dialog and shows a customized dialog.
bool ScenarioSaveAs::ToggleSilent()
{
if (!m_webView2Experimental25)
return false;
m_silentSaveAs = !m_silentSaveAs;
if (m_silentSaveAs && m_saveAsUIShowingToken.value == 0)
{
// Register a handler for the `SaveAsUIShowing` event.
m_webView2Experimental25->add_SaveAsUIShowing(
Callback<ICoreWebView2ExperimentalSaveAsUIShowingEventHandler>(
[this](
ICoreWebView2* sender,
ICoreWebView2ExperimentalSaveAsUIShowingEventArgs* args) -> HRESULT
{
// Hide the system default save as dialog.
CHECK_FAILURE(args->put_SuppressDefaultDialog(TRUE));

auto showCustomizedDialog = [this, args = wil::make_com_ptr(args)]
{
// Preview the content mime type, optional.
wil::unique_cotaskmem_string mimeType;
CHECK_FAILURE(args->get_ContentMimeType(&mimeType));

SaveAsDialog dialog(m_appWindow->GetMainWindow(), saveAsKind);
if (dialog.confirmed)
{
// Set the SaveAsFilePath, Kind, AllowReplace for the event
// args from this customized dialog inputs, optional. If nothing
// needs to input, the event args will provide default values.
CHECK_FAILURE(args->put_SaveAsFilePath(dialog.path.c_str()));
CHECK_FAILURE(args->put_Kind(dialog.selectedKind));
CHECK_FAILURE(args->put_AllowReplace(dialog.allowReplace));

BOOL allowReplace;
CHECK_FAILURE(args->get_AllowReplace(&allowReplace));
wil::unique_cotaskmem_string path;
CHECK_FAILURE(args->get_SaveAsFilePath(&path));
COREWEBVIEW2_SAVE_AS_KIND selectedKind;
CHECK_FAILURE(args->get_Kind(&selectedKind));

// Preview silent save as event args inputs, optional.
MessageBox(
m_appWindow->GetMainWindow(),
(std::wstring(L"Content Mime Type: ") + mimeType.get() + L"\n" +
L"Fullpath: " + path.get() + L"\n" + L"Allow Replace: " +
(allowReplace ? L"true" : L"false") + L"\n" +
L"Selected Save As Kind: " + saveAsKindString[selectedKind])
.c_str(),
L"Silent Save As Parameters Preview", MB_OK);
}
else
{
// Save As cancelled from this customized dialog.
CHECK_FAILURE(args->put_Cancel(TRUE));
}
};

wil::com_ptr<ICoreWebView2Deferral> deferral;
CHECK_FAILURE(args->GetDeferral(&deferral));

m_appWindow->RunAsync(
[deferral, showCustomizedDialog]()
{
showCustomizedDialog();
CHECK_FAILURE(deferral->Complete());
});
return S_OK;
})
.Get(),
&m_saveAsUIShowingToken);
}
else
{
// Unregister the handler for the `SaveAsUIShowing` event.
m_webView2Experimental25->remove_SaveAsUIShowing(m_saveAsUIShowingToken);
m_saveAsUIShowingToken.value = 0;
}
MessageBox(
m_appWindow->GetMainWindow(),
(m_silentSaveAs ? L"Silent Save As Enabled" : L"Silent Save As Disabled"), L"Info",
MB_OK);
return true;
}
//! [ToggleSilent]

//! [ProgrammaticSaveAs]
// Call ShowSaveAsUI method to trigger the programmatic save as.
bool ScenarioSaveAs::ProgrammaticSaveAs()
{
if (!m_webView2Experimental25)
return false;
m_webView2Experimental25->ShowSaveAsUI(
Callback<ICoreWebView2ExperimentalShowSaveAsUICompletedHandler>(
[this](HRESULT errorCode, COREWEBVIEW2_SAVE_AS_UI_RESULT result) -> HRESULT
{
// Show ShowSaveAsUI returned result, optional.
MessageBox(
m_appWindow->GetMainWindow(),
(L"ShowSaveAsUI " + saveAsUIResultString[result]).c_str(), L"Info", MB_OK);
return S_OK;
})
.Get());
return true;
}
//! [ProgrammaticSaveAs]

bool ScenarioSaveAs::HandleWindowMessage(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* result)
{
if (message == WM_COMMAND)
{
switch (LOWORD(wParam))
{
case IDM_SCENARIO_SAVE_AS_TOGGLE_SILENT:
{
return ToggleSilent();
}
case IDM_SCENARIO_SAVE_AS_PROGRAMMATIC:
{
return ProgrammaticSaveAs();
}
}
}
return false;
}

ScenarioSaveAs::~ScenarioSaveAs()
{
if (m_webView2Experimental25)
{
m_webView2Experimental25->remove_SaveAsUIShowing(m_saveAsUIShowingToken);
}
}

static INT_PTR CALLBACK DlgProcStatic(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
auto self = (SaveAsDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
switch (message)
{
case WM_INITDIALOG:
{
self = (SaveAsDialog*)lParam;
SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)self);
HWND hwndList = GetDlgItem(hDlg, IDC_SAVE_AS_KIND);
for (COREWEBVIEW2_SAVE_AS_KIND kind : self->kinds)
{
SendMessage(hwndList, CB_ADDSTRING, kind, (LPARAM)saveAsKindString[kind].c_str());
SendMessage(hwndList, CB_SETITEMDATA, kind, (LPARAM)kind);
}
SendMessage(hwndList, CB_SETCURSEL, 0, 0);
return (INT_PTR)TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDOK)
{
HWND hwndList = GetDlgItem(hDlg, IDC_SAVE_AS_KIND);

wchar_t path[MAX_PATH] = {};
int length = GetWindowTextLength(GetDlgItem(hDlg, IDC_EDIT_SAVE_AS_DIRECTORY)) +
GetWindowTextLength(GetDlgItem(hDlg, IDC_EDIT_SAVE_AS_FILENAME));
wchar_t directory[MAX_PATH] = {};
GetDlgItemText(hDlg, IDC_EDIT_SAVE_AS_DIRECTORY, directory, length + 1);
wchar_t filename[MAX_PATH] = {};
GetDlgItemText(hDlg, IDC_EDIT_SAVE_AS_FILENAME, filename, length + 1);
PathCombineW(path, directory, filename);
self->path = path;

self->allowReplace = IsDlgButtonChecked(hDlg, IDC_CHECK_SAVE_AS_ALLOW_REPLACE);

int index = (int)SendMessage(hwndList, CB_GETCURSEL, 0, 0);
self->selectedKind =
(COREWEBVIEW2_SAVE_AS_KIND)SendMessage(hwndList, CB_GETITEMDATA, index, 0);

self->confirmed = true;
}
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
case WM_NCDESTROY:
SetWindowLongPtr(hDlg, GWLP_USERDATA, NULL);
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}

SaveAsDialog::SaveAsDialog(HWND parent, std::initializer_list<COREWEBVIEW2_SAVE_AS_KIND> kinds)
: kinds(kinds)
{
DialogBoxParam(
g_hInstance, MAKEINTRESOURCE(IDD_SAVE_CONTENT_AS), parent, DlgProcStatic, (LPARAM)this);
}
39 changes: 39 additions & 0 deletions SampleApps/WebView2APISample/ScenarioSaveAs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "stdafx.h"

#include <string>

#include "AppWindow.h"
#include "ComponentBase.h"

class ScenarioSaveAs : public ComponentBase
{
public:
ScenarioSaveAs(AppWindow* appWindow);
bool ProgrammaticSaveAs();
bool ToggleSilent();
bool HandleWindowMessage(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* result) override;

private:
~ScenarioSaveAs() override;
AppWindow* m_appWindow = nullptr;
wil::com_ptr<ICoreWebView2> m_webView;
wil::com_ptr<ICoreWebView2Experimental25> m_webView2Experimental25;
EventRegistrationToken m_saveAsUIShowingToken = {};
bool m_silentSaveAs = false;
};

struct SaveAsDialog
{
SaveAsDialog(HWND parent, std::initializer_list<COREWEBVIEW2_SAVE_AS_KIND> kinds);

std::initializer_list<COREWEBVIEW2_SAVE_AS_KIND> kinds;
std::wstring path;
bool allowReplace = false;
COREWEBVIEW2_SAVE_AS_KIND selectedKind = COREWEBVIEW2_SAVE_AS_KIND_DEFAULT;
bool confirmed = false;
};
16 changes: 0 additions & 16 deletions SampleApps/WebView2APISample/ScenarioSaveAsStaging.cpp

This file was deleted.

10 changes: 0 additions & 10 deletions SampleApps/WebView2APISample/ScenarioSaveAsStaging.h

This file was deleted.

4 changes: 2 additions & 2 deletions SampleApps/WebView2APISample/ViewComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ ViewComponent::ViewComponent(
// the html be the WebView2 logo. We do this by making
// the background color transparent so the WebView2 logo in the AppWindow
// shows through.
COREWEBVIEW2_COLOR transparentColor = { 0, 255, 255, 255 };
COREWEBVIEW2_COLOR transparentColor = {0, 0, 0, 0};
wil::com_ptr<ICoreWebView2Controller2> controller2 =
m_controller.query<ICoreWebView2Controller2>();
// Save the previous background color to restore when navigating away.
Expand Down Expand Up @@ -261,7 +261,7 @@ bool ViewComponent::HandleWindowMessage(
SetBackgroundColor(RGB(0, 0, 255), false);
return true;
case IDM_BACKGROUNDCOLOR_TRANSPARENT:
SetBackgroundColor(RGB(255, 255, 255), true);
SetBackgroundColor(RGB(0, 0, 0), true);
return true;
case IDM_ZOOM_05:
SetZoomFactor(0.5f);
Expand Down
Loading
Loading