| 
									
										
										
										
											2020-04-22 10:52:17 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (C) 2018 Sony Interactive Entertainment Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  * are met: | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |  *    notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |  *    documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 
					
						
							|  |  |  |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
					
						
							|  |  |  |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR | 
					
						
							|  |  |  |  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
					
						
							|  |  |  |  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
					
						
							|  |  |  |  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
					
						
							|  |  |  |  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 
					
						
							|  |  |  |  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "stdafx.h"
 | 
					
						
							|  |  |  | #include "Common.h"
 | 
					
						
							|  |  |  | #include "MainWindow.h"
 | 
					
						
							|  |  |  | #include "PlaywrightLibResource.h"
 | 
					
						
							|  |  |  | #include "WebKitBrowserWindow.h"
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace WebCore { | 
					
						
							|  |  |  | float deviceScaleFactorForWindow(HWND); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const wchar_t* kPlaywrightRegistryKey = L"Software\\WebKit\\Playwright"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static constexpr int kToolbarImageSize = 24; | 
					
						
							|  |  |  | static constexpr int kToolbarURLBarIndex = 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static WNDPROC DefEditProc = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM); | 
					
						
							|  |  |  | static INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::wstring MainWindow::s_windowClass; | 
					
						
							|  |  |  | size_t MainWindow::s_numInstances; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::s_headless = false; | 
					
						
							|  |  |  | bool MainWindow::s_noStartupWindow = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::configure(bool headless, bool noStartupWindow) { | 
					
						
							|  |  |  |     s_headless = headless; | 
					
						
							|  |  |  |     s_noStartupWindow = noStartupWindow; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::wstring loadString(int id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     constexpr size_t length = 100; | 
					
						
							|  |  |  |     wchar_t buff[length]; | 
					
						
							|  |  |  |     LoadString(hInst, id, buff, length); | 
					
						
							|  |  |  |     return buff; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::registerClass(HINSTANCE hInstance) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static bool initialized = false; | 
					
						
							|  |  |  |     if (initialized) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     initialized = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s_windowClass = loadString(IDC_PLAYWRIGHT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WNDCLASSEX wcex; | 
					
						
							|  |  |  |     wcex.cbSize = sizeof(WNDCLASSEX); | 
					
						
							|  |  |  |     wcex.style          = CS_HREDRAW | CS_VREDRAW; | 
					
						
							|  |  |  |     wcex.lpfnWndProc    = WndProc; | 
					
						
							|  |  |  |     wcex.cbClsExtra     = 0; | 
					
						
							|  |  |  |     wcex.cbWndExtra     = 0; | 
					
						
							|  |  |  |     wcex.hInstance      = hInstance; | 
					
						
							|  |  |  |     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PLAYWRIGHT)); | 
					
						
							|  |  |  |     wcex.hCursor        = LoadCursor(0, IDC_ARROW); | 
					
						
							|  |  |  |     wcex.hbrBackground  = 0; | 
					
						
							|  |  |  |     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_PLAYWRIGHT); | 
					
						
							|  |  |  |     wcex.lpszClassName  = s_windowClass.c_str(); | 
					
						
							|  |  |  |     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_PLAYWRIGHT)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RegisterClassEx(&wcex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::isInstance(HWND hwnd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     wchar_t buff[64]; | 
					
						
							|  |  |  |     if (!GetClassName(hwnd, buff, _countof(buff))) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return s_windowClass == buff; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MainWindow::MainWindow() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     s_numInstances++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MainWindow::~MainWindow() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     s_numInstances--; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::createToolbar(HINSTANCE hInstance) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_hToolbarWnd = CreateWindowEx(0, TOOLBARCLASSNAME, nullptr,  | 
					
						
							|  |  |  |         WS_CHILD | WS_BORDER | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TOOLTIPS, 0, 0, 0, 0,  | 
					
						
							|  |  |  |         m_hMainWnd, nullptr, hInstance, nullptr); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     if (!m_hToolbarWnd) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const int ImageListID = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HIMAGELIST hImageList; | 
					
						
							|  |  |  |     hImageList = ImageList_LoadImage(hInstance, MAKEINTRESOURCE(IDB_TOOLBAR), kToolbarImageSize, 0, CLR_DEFAULT, IMAGE_BITMAP, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_SETIMAGELIST, ImageListID, reinterpret_cast<LPARAM>(hImageList)); | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const DWORD buttonStyles = BTNS_AUTOSIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TBBUTTON tbButtons[] = { | 
					
						
							|  |  |  |         { MAKELONG(0, ImageListID), IDM_HISTORY_BACKWARD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Back" }, | 
					
						
							|  |  |  |         { MAKELONG(1, ImageListID), IDM_HISTORY_FORWARD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Forward"}, | 
					
						
							|  |  |  |         { MAKELONG(2, ImageListID), IDM_RELOAD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Reload"}, | 
					
						
							|  |  |  |         { 0, 0, TBSTATE_ENABLED, BTNS_SEP, { }, 0, 0}, // URL bar
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_ADDBUTTONS, _countof(tbButtons), reinterpret_cast<LPARAM>(&tbButtons)); | 
					
						
							|  |  |  |     ShowWindow(m_hToolbarWnd, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DefEditProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC)); | 
					
						
							|  |  |  |     SetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(EditProc)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::resizeToolbar(int parentWidth) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; | 
					
						
							|  |  |  |     info.cx = parentWidth - m_toolbarItemsWidth; | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast<LPARAM>(&info)); | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RECT rect; | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_GETITEMRECT, kToolbarURLBarIndex, reinterpret_cast<LPARAM>(&rect)); | 
					
						
							|  |  |  |     MoveWindow(m_hURLBarWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::rescaleToolbar() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const float scaleFactor = WebCore::deviceScaleFactorForWindow(m_hMainWnd); | 
					
						
							|  |  |  |     const int scaledImageSize = kToolbarImageSize * scaleFactor; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     info.cx = 0; | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast<LPARAM>(&info)); | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int numItems = SendMessage(m_hToolbarWnd, TB_BUTTONCOUNT, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RECT rect; | 
					
						
							|  |  |  |     SendMessage(m_hToolbarWnd, TB_GETITEMRECT, numItems-1, reinterpret_cast<LPARAM>(&rect)); | 
					
						
							|  |  |  |     m_toolbarItemsWidth = rect.right; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 10:30:25 -07:00
										 |  |  | bool MainWindow::init(HINSTANCE hInstance, WKPageConfigurationRef conf) | 
					
						
							| 
									
										
										
										
											2020-04-22 10:52:17 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     auto prefs = adoptWK(WKPreferencesCreate()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-05 10:30:25 -07:00
										 |  |  |     WKPageConfigurationSetPreferences(conf, prefs.get()); | 
					
						
							| 
									
										
										
										
											2020-04-22 10:52:17 -07:00
										 |  |  |     WKPreferencesSetMediaCapabilitiesEnabled(prefs.get(), false); | 
					
						
							|  |  |  |     WKPreferencesSetDeveloperExtrasEnabled(prefs.get(), true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_configuration = conf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     registerClass(hInstance); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto title = loadString(IDS_APP_TITLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_hMainWnd = CreateWindowExW(s_headless ? WS_EX_NOACTIVATE : 0, s_windowClass.c_str(), title.c_str(), | 
					
						
							|  |  |  |         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!m_hMainWnd) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!s_headless) { | 
					
						
							|  |  |  |       createToolbar(hInstance); | 
					
						
							|  |  |  |       if (!m_hToolbarWnd) | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_browserWindow.reset(new WebKitBrowserWindow(*this, m_hMainWnd, conf)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateDeviceScaleFactor(); | 
					
						
							|  |  |  |     resizeSubViews(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s_headless) { | 
					
						
							|  |  |  |         SetMenu(m_hMainWnd, NULL); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         SetFocus(m_hURLBarWnd); | 
					
						
							|  |  |  |         ShowWindow(m_hMainWnd, SW_SHOW); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::resizeSubViews() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     RECT rcClient; | 
					
						
							|  |  |  |     GetClientRect(m_hMainWnd, &rcClient); | 
					
						
							|  |  |  |     if (s_headless) { | 
					
						
							|  |  |  |         MoveWindow(m_browserWindow->hwnd(), 0, 0, rcClient.right, rcClient.bottom, true); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resizeToolbar(rcClient.right); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RECT rect; | 
					
						
							|  |  |  |     GetWindowRect(m_hToolbarWnd, &rect); | 
					
						
							|  |  |  |     POINT toolbarBottom = { 0, rect.bottom }; | 
					
						
							|  |  |  |     ScreenToClient(m_hMainWnd, &toolbarBottom); | 
					
						
							|  |  |  |     auto height = toolbarBottom.y; | 
					
						
							|  |  |  |     MoveWindow(m_browserWindow->hwnd(), 0, height, rcClient.right, rcClient.bottom - height, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     LRESULT result = 0; | 
					
						
							|  |  |  |     MainWindow* thisWindow = reinterpret_cast<MainWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); | 
					
						
							|  |  |  |     if (!thisWindow && message != WM_CREATE) | 
					
						
							|  |  |  |         return DefWindowProc(hWnd, message, wParam, lParam); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (message) { | 
					
						
							|  |  |  |     case WM_ACTIVATE: | 
					
						
							|  |  |  |         switch (LOWORD(wParam)) { | 
					
						
							|  |  |  |         case WA_ACTIVE: | 
					
						
							|  |  |  |         case WA_CLICKACTIVE: | 
					
						
							|  |  |  |             SetFocus(thisWindow->browserWindow()->hwnd()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WM_CREATE: | 
					
						
							|  |  |  |         SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams)); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WM_APPCOMMAND: { | 
					
						
							|  |  |  |         auto cmd = GET_APPCOMMAND_LPARAM(lParam); | 
					
						
							|  |  |  |         switch (cmd) { | 
					
						
							|  |  |  |         case APPCOMMAND_BROWSER_BACKWARD: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->navigateForwardOrBackward(false); | 
					
						
							|  |  |  |             result = 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case APPCOMMAND_BROWSER_FORWARD: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->navigateForwardOrBackward(true); | 
					
						
							|  |  |  |             result = 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case APPCOMMAND_BROWSER_REFRESH: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->reload(); | 
					
						
							|  |  |  |             result = 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case APPCOMMAND_BROWSER_STOP: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case WM_COMMAND: { | 
					
						
							|  |  |  |         int wmId = LOWORD(wParam); | 
					
						
							|  |  |  |         int wmEvent = HIWORD(wParam); | 
					
						
							|  |  |  |         switch (wmEvent) { | 
					
						
							|  |  |  |         case 0: // Menu or BN_CLICKED
 | 
					
						
							|  |  |  |         case 1: // Accelerator
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return DefWindowProc(hWnd, message, wParam, lParam); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Parse the menu selections:
 | 
					
						
							|  |  |  |         switch (wmId) { | 
					
						
							|  |  |  |         case IDC_URL_BAR: | 
					
						
							|  |  |  |             thisWindow->onURLBarEnter(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_NEW_WINDOW: { | 
					
						
							|  |  |  |             auto* newWindow = new MainWindow(); | 
					
						
							|  |  |  |             newWindow->init(hInst, thisWindow->m_configuration.get()); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         case IDM_CLOSE_WINDOW: | 
					
						
							|  |  |  |             PostMessage(hWnd, WM_CLOSE, 0, 0); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_ABOUT: | 
					
						
							|  |  |  |             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_WEB_INSPECTOR: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->launchInspector(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_HISTORY_BACKWARD: | 
					
						
							|  |  |  |         case IDM_HISTORY_FORWARD: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->navigateForwardOrBackward(wmId == IDM_HISTORY_FORWARD); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_ACTUAL_SIZE: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->resetZoom(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_RELOAD: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->reload(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_ZOOM_IN: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->zoomIn(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IDM_ZOOM_OUT: | 
					
						
							|  |  |  |             thisWindow->browserWindow()->zoomOut(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             if (!thisWindow->toggleMenuItem(wmId)) | 
					
						
							|  |  |  |                 return DefWindowProc(hWnd, message, wParam, lParam); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-05-13 22:54:43 -07:00
										 |  |  |     case WM_NCDESTROY: | 
					
						
							| 
									
										
										
										
											2020-04-22 10:52:17 -07:00
										 |  |  |         SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); | 
					
						
							|  |  |  |         delete thisWindow; | 
					
						
							|  |  |  |         if (s_noStartupWindow || s_numInstances > 0) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         PostQuitMessage(0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WM_SIZE: | 
					
						
							|  |  |  |         thisWindow->resizeSubViews(); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WM_DPICHANGED: { | 
					
						
							|  |  |  |         thisWindow->updateDeviceScaleFactor(); | 
					
						
							|  |  |  |         auto& rect = *reinterpret_cast<RECT*>(lParam); | 
					
						
							|  |  |  |         SetWindowPos(hWnd, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return DefWindowProc(hWnd, message, wParam, lParam); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool menuItemIsChecked(const MENUITEMINFO& info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return info.fState & MFS_CHECKED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::toggleMenuItem(UINT menuID) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s_headless) | 
					
						
							|  |  |  |         return (INT_PTR)FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HMENU menu = ::GetMenu(hwnd()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MENUITEMINFO info = { }; | 
					
						
							|  |  |  |     info.cbSize = sizeof(info); | 
					
						
							|  |  |  |     info.fMask = MIIM_STATE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!::GetMenuItemInfo(menu, menuID, FALSE, &info)) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BOOL newState = !menuItemIsChecked(info); | 
					
						
							|  |  |  |     info.fState = (newState) ? MFS_CHECKED : MFS_UNCHECKED; | 
					
						
							|  |  |  |     ::SetMenuItemInfo(menu, menuID, FALSE, &info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (message) { | 
					
						
							|  |  |  |     case WM_SETFOCUS: | 
					
						
							|  |  |  |         PostMessage(hWnd, EM_SETSEL, 0, -1); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case WM_CHAR: | 
					
						
							|  |  |  |         if (wParam == 13) { | 
					
						
							|  |  |  |             // Enter Key
 | 
					
						
							|  |  |  |             ::PostMessage(GetParent(hWnd), static_cast<UINT>(WM_COMMAND), MAKELPARAM(IDC_URL_BAR, 0), 0); | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return CallWindowProc(DefEditProc, hWnd, message, wParam, lParam); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Message handler for about box.
 | 
					
						
							|  |  |  | INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     UNREFERENCED_PARAMETER(lParam); | 
					
						
							|  |  |  |     switch (message) { | 
					
						
							|  |  |  |     case WM_INITDIALOG: | 
					
						
							|  |  |  |         return (INT_PTR)TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case WM_COMMAND: | 
					
						
							|  |  |  |         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { | 
					
						
							|  |  |  |             EndDialog(hDlg, LOWORD(wParam)); | 
					
						
							|  |  |  |             return (INT_PTR)TRUE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return (INT_PTR)FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::loadURL(std::wstring url) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (::PathFileExists(url.c_str()) || ::PathIsUNC(url.c_str())) { | 
					
						
							|  |  |  |         wchar_t fileURL[INTERNET_MAX_URL_LENGTH]; | 
					
						
							|  |  |  |         DWORD fileURLLength = _countof(fileURL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (SUCCEEDED(::UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0))) | 
					
						
							|  |  |  |             url = fileURL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (url.find(L"://") == url.npos && url.find(L"about:blank") == url.npos) | 
					
						
							|  |  |  |         url = L"http://" + url; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (FAILED(m_browserWindow->loadURL(_bstr_t(url.c_str())))) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!s_headless) | 
					
						
							|  |  |  |         SetFocus(m_browserWindow->hwnd()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::onURLBarEnter() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s_headless) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     wchar_t url[INTERNET_MAX_URL_LENGTH]; | 
					
						
							|  |  |  |     GetWindowText(m_hURLBarWnd, url, INTERNET_MAX_URL_LENGTH); | 
					
						
							|  |  |  |     loadURL(url); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::updateDeviceScaleFactor() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s_headless) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     if (m_hURLBarFont) | 
					
						
							|  |  |  |         ::DeleteObject(m_hURLBarFont); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rescaleToolbar(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RECT rect; | 
					
						
							|  |  |  |     GetClientRect(m_hToolbarWnd, &rect); | 
					
						
							|  |  |  |     int fontHeight = 20; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_hURLBarFont = ::CreateFont(fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, | 
					
						
							|  |  |  |         OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FF_DONTCARE, L"Tahoma"); | 
					
						
							|  |  |  |     ::SendMessage(m_hURLBarWnd, static_cast<UINT>(WM_SETFONT), reinterpret_cast<WPARAM>(m_hURLBarFont), TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::activeURLChanged(std::wstring url) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s_headless) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     SetWindowText(m_hURLBarWnd, url.c_str()); | 
					
						
							|  |  |  | } |