|
35 | 35 | #include "ScenarioCustomDownloadExperience.h"
|
36 | 36 | #include "ScenarioCustomScheme.h"
|
37 | 37 | #include "ScenarioCustomSchemeNavigate.h"
|
| 38 | +#include "ScenarioDefaultBackgroundColor.h" |
38 | 39 | #include "ScenarioDOMContentLoaded.h"
|
39 | 40 | #include "ScenarioDragDrop.h"
|
| 41 | +#include "ScenarioDragDropOverride.h" |
40 | 42 | #include "ScenarioExtensionsManagement.h"
|
41 | 43 | #include "ScenarioFileSystemHandleShare.h"
|
42 | 44 | #include "ScenarioFileTypePolicy.h"
|
@@ -201,7 +203,7 @@ AppWindow::AppWindow(
|
201 | 203 | WCHAR szTitle[s_maxLoadString]; // The title bar text
|
202 | 204 | LoadStringW(g_hInstance, IDS_APP_TITLE, szTitle, s_maxLoadString);
|
203 | 205 | m_appTitle = szTitle;
|
204 |
| - DWORD windowStyle = WS_OVERLAPPEDWINDOW; |
| 206 | + DWORD windowStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; |
205 | 207 | if (userDataFolderParam.length() > 0)
|
206 | 208 | {
|
207 | 209 | m_userDataFolder = userDataFolderParam;
|
@@ -684,6 +686,43 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam)
|
684 | 686 | NewComponent<ScenarioFileTypePolicy>(this);
|
685 | 687 | return true;
|
686 | 688 | }
|
| 689 | + case IDM_START_FIND: |
| 690 | + { |
| 691 | + std::wstring searchTerm = L"webview"; // Replace with the actual term |
| 692 | + return Start(searchTerm); |
| 693 | + } |
| 694 | + case IDM_STOP_FIND: |
| 695 | + { |
| 696 | + return StopFind(); |
| 697 | + } |
| 698 | + case IDM_GET_MATCHES: |
| 699 | + { |
| 700 | + return GetMatchCount(); |
| 701 | + } |
| 702 | + case IDM_GET_ACTIVE_MATCH_INDEX: |
| 703 | + { |
| 704 | + return GetActiveMatchIndex(); |
| 705 | + } |
| 706 | + case IDC_FIND_TERM: |
| 707 | + { |
| 708 | + return FindTerm(); |
| 709 | + } |
| 710 | + case IDC_IS_CASE_SENSITIVE: |
| 711 | + { |
| 712 | + return IsCaseSensitive(); |
| 713 | + } |
| 714 | + case IDC_SHOULD_MATCH_WHOLE_WORD: |
| 715 | + { |
| 716 | + return ShouldMatchWord(); |
| 717 | + } |
| 718 | + case IDC_SHOULD_HIGHLIGHT_ALL_MATCHES: |
| 719 | + { |
| 720 | + return ShouldHighlightAllMatches(); |
| 721 | + } |
| 722 | + case IDC_SUPPRESS_DEFAULT_FIND_DIALOG: |
| 723 | + { |
| 724 | + return SuppressDefaultFindDialog(); |
| 725 | + } |
687 | 726 | }
|
688 | 727 | return false;
|
689 | 728 | }
|
@@ -1210,6 +1249,302 @@ bool AppWindow::PrintToPdfStream()
|
1210 | 1249 | }
|
1211 | 1250 | //! [PrintToPdfStream]
|
1212 | 1251 |
|
| 1252 | +//! [Start] |
| 1253 | +bool AppWindow::Start(const std::wstring& searchTerm) |
| 1254 | +{ |
| 1255 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1256 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1257 | + |
| 1258 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1259 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1260 | + SetupFindEventHandlers(webView2find); |
| 1261 | + |
| 1262 | + // Initialize find configuration/settings |
| 1263 | + if (!findOptions) |
| 1264 | + { |
| 1265 | + findOptions = SetDefaultFindOptions(); |
| 1266 | + } |
| 1267 | + |
| 1268 | + // Check if the search term has changed to determine if UI needs to be updated |
| 1269 | + if (m_findOnPageLastSearchTerm != searchTerm) |
| 1270 | + { |
| 1271 | + m_findOnPageLastSearchTerm = |
| 1272 | + searchTerm; // Update the last search term for future comparisons |
| 1273 | + } |
| 1274 | + |
| 1275 | + // Start the find operation |
| 1276 | + CHECK_FAILURE(webView2find->Start( |
| 1277 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1278 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1279 | + .Get())); |
| 1280 | + return true; |
| 1281 | +} |
| 1282 | +//! [Start] |
| 1283 | + |
| 1284 | +//! [FindNext] |
| 1285 | +bool AppWindow::FindNext() |
| 1286 | +{ |
| 1287 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1288 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1289 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1290 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1291 | + CHECK_FAILURE(webView2find->FindNext()); |
| 1292 | + |
| 1293 | + return true; |
| 1294 | +} |
| 1295 | +//! [FindNext] |
| 1296 | + |
| 1297 | +//! [FindPrevious] |
| 1298 | +bool AppWindow::FindPrevious() |
| 1299 | +{ |
| 1300 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1301 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1302 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1303 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1304 | + |
| 1305 | + CHECK_FAILURE(webView2find->FindPrevious()); |
| 1306 | + |
| 1307 | + return true; |
| 1308 | +} |
| 1309 | +//! [FindPrevious] |
| 1310 | + |
| 1311 | +//! [Stop] |
| 1312 | +bool AppWindow::StopFind() |
| 1313 | +{ |
| 1314 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1315 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1316 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1317 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1318 | + // Note, I am not 100% sure if this is the best way to remove the event handlers |
| 1319 | + // Because it would rely on the user clicking stopfind. Maybe put in destructor or when |
| 1320 | + // startfind completes? |
| 1321 | + CHECK_FAILURE(webView2find->remove_MatchCountChanged(m_matchCountChangedToken)); |
| 1322 | + CHECK_FAILURE(webView2find->remove_ActiveMatchIndexChanged(m_activeMatchIndexChangedToken)); |
| 1323 | + CHECK_FAILURE(webView2find->Stop()); |
| 1324 | + return true; |
| 1325 | +} |
| 1326 | +//! [Stop] |
| 1327 | + |
| 1328 | +//! [MatchCount] |
| 1329 | +bool AppWindow::GetMatchCount() |
| 1330 | +{ |
| 1331 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1332 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1333 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1334 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1335 | + int32_t matchCount; |
| 1336 | + CHECK_FAILURE(webView2find->get_MatchCount(&matchCount)); |
| 1337 | + |
| 1338 | + std::wstring matchCountStr = L"Match Count: " + std::to_wstring(matchCount); |
| 1339 | + MessageBox(m_mainWindow, matchCountStr.c_str(), L"Find Operation", MB_OK); |
| 1340 | + |
| 1341 | + return true; |
| 1342 | +} |
| 1343 | +//! [MatchCount] |
| 1344 | + |
| 1345 | +//! [ActiveMatchIndex] |
| 1346 | +bool AppWindow::GetActiveMatchIndex() |
| 1347 | +{ |
| 1348 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1349 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1350 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1351 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1352 | + int32_t activeMatchIndex; |
| 1353 | + CHECK_FAILURE(webView2find->get_ActiveMatchIndex(&activeMatchIndex)); |
| 1354 | + |
| 1355 | + std::wstring activeMatchIndexStr = |
| 1356 | + L"Active Match Index: " + std::to_wstring(activeMatchIndex); |
| 1357 | + MessageBox(m_mainWindow, activeMatchIndexStr.c_str(), L"Find Operation", MB_OK); |
| 1358 | + |
| 1359 | + return true; |
| 1360 | +} |
| 1361 | +//! [ActiveMatchIndex] |
| 1362 | + |
| 1363 | +//! [IsCaseSensitive] |
| 1364 | +bool AppWindow::IsCaseSensitive() |
| 1365 | +{ |
| 1366 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1367 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1368 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1369 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1370 | + |
| 1371 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1372 | + CHECK_FEATURE_RETURN(m_env18); |
| 1373 | + CHECK_FAILURE(webView2find->Stop()); |
| 1374 | + |
| 1375 | + if (!findOptions) |
| 1376 | + { |
| 1377 | + findOptions = SetDefaultFindOptions(); |
| 1378 | + } |
| 1379 | + BOOL caseSensitive; |
| 1380 | + findOptions->get_IsCaseSensitive(&caseSensitive); |
| 1381 | + CHECK_FAILURE(findOptions->put_IsCaseSensitive(!caseSensitive)); |
| 1382 | + |
| 1383 | + CHECK_FAILURE(webView2find->Start( |
| 1384 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1385 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1386 | + .Get())); |
| 1387 | + return true; |
| 1388 | +} |
| 1389 | +//! [IsCaseSensitive] |
| 1390 | + |
| 1391 | +//! [ShouldHighlightAllMatches] |
| 1392 | +bool AppWindow::ShouldHighlightAllMatches() |
| 1393 | +{ |
| 1394 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1395 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1396 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1397 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1398 | + |
| 1399 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1400 | + CHECK_FEATURE_RETURN(m_env18); |
| 1401 | + CHECK_FAILURE(webView2find->Stop()); |
| 1402 | + |
| 1403 | + if (!findOptions) |
| 1404 | + { |
| 1405 | + findOptions = SetDefaultFindOptions(); |
| 1406 | + } |
| 1407 | + BOOL shouldHighlightAllMatches; |
| 1408 | + CHECK_FAILURE(findOptions->get_ShouldHighlightAllMatches(&shouldHighlightAllMatches)); |
| 1409 | + CHECK_FAILURE(findOptions->put_ShouldHighlightAllMatches(!shouldHighlightAllMatches)); |
| 1410 | + CHECK_FAILURE(webView2find->Start( |
| 1411 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1412 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1413 | + .Get())); |
| 1414 | + return true; |
| 1415 | +} |
| 1416 | +//! [ShouldHighlightAllMatches] |
| 1417 | + |
| 1418 | +//! [ShouldMatchWord] |
| 1419 | +bool AppWindow::ShouldMatchWord() |
| 1420 | +{ |
| 1421 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1422 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1423 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1424 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1425 | + |
| 1426 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1427 | + CHECK_FEATURE_RETURN(m_env18); |
| 1428 | + CHECK_FAILURE(webView2find->Stop()); |
| 1429 | + |
| 1430 | + if (!findOptions) |
| 1431 | + { |
| 1432 | + findOptions = SetDefaultFindOptions(); |
| 1433 | + } |
| 1434 | + BOOL shouldMatchWord; |
| 1435 | + findOptions->get_ShouldMatchWord(&shouldMatchWord); |
| 1436 | + CHECK_FAILURE(findOptions->put_ShouldMatchWord(!shouldMatchWord)); |
| 1437 | + CHECK_FAILURE(webView2find->Start( |
| 1438 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1439 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1440 | + .Get())); |
| 1441 | + return true; |
| 1442 | +} |
| 1443 | +//! [ShouldMatchWord] |
| 1444 | + |
| 1445 | +//! [SuppressDefaultFindDialog] |
| 1446 | +bool AppWindow::SuppressDefaultFindDialog() |
| 1447 | +{ |
| 1448 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1449 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1450 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1451 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1452 | + |
| 1453 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1454 | + CHECK_FEATURE_RETURN(m_env18); |
| 1455 | + CHECK_FAILURE(webView2find->Stop()); |
| 1456 | + |
| 1457 | + if (!findOptions) |
| 1458 | + { |
| 1459 | + findOptions = SetDefaultFindOptions(); |
| 1460 | + } |
| 1461 | + BOOL suppressDefaultDialog; |
| 1462 | + findOptions->get_SuppressDefaultFindDialog(&suppressDefaultDialog); |
| 1463 | + CHECK_FAILURE(findOptions->put_SuppressDefaultFindDialog(!suppressDefaultDialog)); |
| 1464 | + CHECK_FAILURE(webView2find->Stop()); |
| 1465 | + CHECK_FAILURE(webView2find->Start( |
| 1466 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1467 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1468 | + .Get())); |
| 1469 | + return true; |
| 1470 | +} |
| 1471 | +//! [SuppressDefaultFindDialog] |
| 1472 | + |
| 1473 | +//! [FindTerm] |
| 1474 | +bool AppWindow::FindTerm() |
| 1475 | +{ |
| 1476 | + auto webView2Experimental29 = m_webView.try_query<ICoreWebView2Experimental29>(); |
| 1477 | + CHECK_FEATURE_RETURN(webView2Experimental29); |
| 1478 | + wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find; |
| 1479 | + CHECK_FAILURE(webView2Experimental29->get_Find(&webView2find)); |
| 1480 | + |
| 1481 | + TextInputDialog dialog( |
| 1482 | + GetMainWindow(), L"Find on Page Term", L"Find on Page Term:", L"Enter Find Term"); |
| 1483 | + |
| 1484 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1485 | + CHECK_FEATURE_RETURN(m_env18); |
| 1486 | + CHECK_FAILURE(webView2find->Stop()); |
| 1487 | + |
| 1488 | + if (!findOptions) |
| 1489 | + { |
| 1490 | + findOptions = SetDefaultFindOptions(); |
| 1491 | + } |
| 1492 | + CHECK_FAILURE(findOptions->put_FindTerm(dialog.input.c_str())); |
| 1493 | + CHECK_FAILURE(webView2find->Start( |
| 1494 | + findOptions.get(), Callback<ICoreWebView2ExperimentalFindStartCompletedHandler>( |
| 1495 | + [this](HRESULT result) -> HRESULT { return S_OK; }) |
| 1496 | + .Get())); |
| 1497 | + return true; |
| 1498 | +} |
| 1499 | +//! [FindTerm] |
| 1500 | + |
| 1501 | +wil::com_ptr<ICoreWebView2ExperimentalFindOptions> AppWindow::SetDefaultFindOptions() |
| 1502 | +{ |
| 1503 | + auto m_env18 = m_webViewEnvironment.try_query<ICoreWebView2ExperimentalEnvironment18>(); |
| 1504 | + |
| 1505 | + // Initialize find configuration/settings |
| 1506 | + wil::com_ptr<ICoreWebView2ExperimentalFindOptions> findOptions; |
| 1507 | + CHECK_FAILURE(m_env18->CreateFindOptions(&findOptions)); |
| 1508 | + CHECK_FAILURE(findOptions->put_FindTerm(L"Webview2")); |
| 1509 | + CHECK_FAILURE(findOptions->put_IsCaseSensitive(false)); |
| 1510 | + CHECK_FAILURE(findOptions->put_ShouldMatchWord(false)); |
| 1511 | + CHECK_FAILURE(findOptions->put_SuppressDefaultFindDialog(false)); |
| 1512 | + CHECK_FAILURE(findOptions->put_ShouldHighlightAllMatches(true)); |
| 1513 | + |
| 1514 | + return findOptions; |
| 1515 | +} |
| 1516 | + |
| 1517 | +void AppWindow::SetupFindEventHandlers(wil::com_ptr<ICoreWebView2ExperimentalFind> webView2find) |
| 1518 | +{ |
| 1519 | + CHECK_FAILURE(webView2find->add_MatchCountChanged( |
| 1520 | + Callback<ICoreWebView2ExperimentalFindMatchCountChangedEventHandler>( |
| 1521 | + [this](ICoreWebView2ExperimentalFind* sender, IUnknown* args) -> HRESULT |
| 1522 | + { |
| 1523 | + int matchCount = 0; |
| 1524 | + if (sender) |
| 1525 | + { |
| 1526 | + CHECK_FAILURE(sender->get_MatchCount(&matchCount)); |
| 1527 | + } |
| 1528 | + return S_OK; |
| 1529 | + }) |
| 1530 | + .Get(), |
| 1531 | + &m_matchCountChangedToken)); |
| 1532 | + |
| 1533 | + CHECK_FAILURE(webView2find->add_ActiveMatchIndexChanged( |
| 1534 | + Callback<ICoreWebView2ExperimentalFindActiveMatchIndexChangedEventHandler>( |
| 1535 | + [this](ICoreWebView2ExperimentalFind* sender, IUnknown* args) -> HRESULT |
| 1536 | + { |
| 1537 | + int activeIndex = -1; |
| 1538 | + if (sender) |
| 1539 | + { |
| 1540 | + CHECK_FAILURE(sender->get_ActiveMatchIndex(&activeIndex)); |
| 1541 | + } |
| 1542 | + return S_OK; |
| 1543 | + }) |
| 1544 | + .Get(), |
| 1545 | + &m_activeMatchIndexChangedToken)); |
| 1546 | +} |
| 1547 | + |
1213 | 1548 | // Message handler for about dialog.
|
1214 | 1549 | INT_PTR CALLBACK AppWindow::About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
1215 | 1550 | {
|
@@ -1523,6 +1858,18 @@ HRESULT AppWindow::CreateControllerWithOptions()
|
1523 | 1858 | }
|
1524 | 1859 | //! [AllowHostInputProcessing]
|
1525 | 1860 |
|
| 1861 | + //! [DefaultBackgroundColor] |
| 1862 | + if (m_webviewOption.bg_color) |
| 1863 | + { |
| 1864 | + wil::com_ptr<ICoreWebView2ExperimentalControllerOptions3> experimentalControllerOptions3; |
| 1865 | + if (SUCCEEDED(options->QueryInterface(IID_PPV_ARGS(&experimentalControllerOptions3)))) |
| 1866 | + { |
| 1867 | + CHECK_FAILURE( |
| 1868 | + experimentalControllerOptions3->put_DefaultBackgroundColor(*m_webviewOption.bg_color)); |
| 1869 | + } |
| 1870 | + } |
| 1871 | + //! [DefaultBackgroundColor] |
| 1872 | + |
1526 | 1873 | if (m_dcompDevice || m_wincompCompositor)
|
1527 | 1874 | {
|
1528 | 1875 | //! [OnCreateCoreWebView2ControllerCompleted]
|
|
0 commit comments