Skip to content

Commit

Permalink
Merge pull request #242 from MicrosoftEdge/smoketest/1.0.2526-testing
Browse files Browse the repository at this point in the history
Update projects to use latest WebView2 1.0.2526 prerelease
  • Loading branch information
tochukwuIbeEkeocha authored Apr 22, 2024
2 parents 928fe12 + 2b0d774 commit bce5a77
Show file tree
Hide file tree
Showing 17 changed files with 647 additions and 222 deletions.
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

0 comments on commit bce5a77

Please sign in to comment.