diff options
Diffstat (limited to 'Tools/MiniBrowser/win/BrowserWindow.cpp')
-rw-r--r-- | Tools/MiniBrowser/win/BrowserWindow.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/Tools/MiniBrowser/win/BrowserWindow.cpp b/Tools/MiniBrowser/win/BrowserWindow.cpp new file mode 100644 index 0000000..dc43a68 --- /dev/null +++ b/Tools/MiniBrowser/win/BrowserWindow.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "BrowserWindow.h" +#include "MiniBrowser.h" +#include "Resource.h" + +#include <assert.h> +#include <commctrl.h> +#include <shlwapi.h> +#include <vector> +#include <wininet.h> + +using namespace std; + +BrowserWindow::BrowserWindow() + : m_window(0) + , m_rebarWindow(0) + , m_comboBoxWindow(0) +{ +} + +LRESULT CALLBACK BrowserWindow::BrowserWindowWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) +{ + LONG_PTR longPtr = ::GetWindowLongPtr(window, 0); + + if (BrowserWindow* browserView = reinterpret_cast<BrowserWindow*>(longPtr)) + return browserView->wndProc(window, message, wParam, lParam); + + if (message == WM_CREATE) { + LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); + BrowserWindow* browserWindow = static_cast<BrowserWindow*>(createStruct->lpCreateParams); + browserWindow->m_window = window; + + ::SetWindowLongPtr(window, 0, (LONG_PTR)browserWindow); + + browserWindow->onCreate(createStruct); + return 0; + } + + return ::DefWindowProc(window, message, wParam, lParam); +} + +LRESULT BrowserWindow::wndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT lResult = 0; + bool handled = true; + + switch (message) { + case WM_ERASEBKGND: + lResult = 1; + break; + + case WM_COMMAND: + lResult = onCommand(LOWORD(wParam), handled); + break; + + case WM_SIZE: + onSize(LOWORD(lParam), HIWORD(lParam)); + break; + + case WM_DESTROY: + onDestroy(); + break; + + case WM_NCDESTROY: + onNCDestroy(); + break; + + default: + handled = false; + } + + if (!handled) + lResult = ::DefWindowProc(window, message, wParam, lParam); + + return lResult; +} + +void BrowserWindow::createWindow(int x, int y, int width, int height) +{ + assert(!m_window); + + // Register the class. + WNDCLASSEX windowClass = { 0 }; + windowClass.cbSize = sizeof(windowClass); + windowClass.style = 0; + windowClass.lpfnWndProc = BrowserWindowWndProc; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = sizeof(this); + windowClass.hInstance = MiniBrowser::shared().instance(); + windowClass.hIcon = 0; + windowClass.hCursor = ::LoadCursor(0, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); + windowClass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME); + windowClass.lpszClassName = L"MiniBrowser"; + windowClass.hIconSm = 0; + + ::RegisterClassEx(&windowClass); + + ::CreateWindowW(L"MiniBrowser", L"MiniBrowser", WS_OVERLAPPEDWINDOW, x, y, width, height, 0, 0, MiniBrowser::shared().instance(), this); +} + +void BrowserWindow::showWindow() +{ + assert(m_window); + + ::ShowWindow(m_window, SW_SHOWNORMAL); +} + +void BrowserWindow::goToURL(const std::wstring& url) +{ + m_browserView.goToURL(url); +} + +void BrowserWindow::onCreate(LPCREATESTRUCT createStruct) +{ + // Register our window. + MiniBrowser::shared().registerWindow(this); + + // Create the rebar control. + m_rebarWindow = ::CreateWindowEx(0, REBARCLASSNAME, 0, WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN | RBS_VARHEIGHT | RBS_BANDBORDERS, + 0, 0, 0, 0, m_window, 0, createStruct->hInstance, 0); + REBARINFO rebarInfo = { 0 }; + rebarInfo.cbSize = sizeof(rebarInfo); + rebarInfo.fMask = 0; + ::SendMessage(m_rebarWindow, RB_SETBARINFO, 0, (LPARAM)&rebarInfo); + + // Create the combo box control. + m_comboBoxWindow = ::CreateWindowEx(0, L"combobox", 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBS_AUTOHSCROLL | CBS_DROPDOWN, + 0, 0, 0, 0, m_rebarWindow, 0, createStruct->hInstance, 0); + SendMessage(m_comboBoxWindow, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0)); + + REBARBANDINFO bandInfo; + bandInfo.cbSize = sizeof(bandInfo); + bandInfo.fMask = RBBIM_STYLE | RBBIM_TEXT | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + bandInfo.fStyle = RBBS_CHILDEDGE | RBBS_GRIPPERALWAYS; + bandInfo.lpText = L"Address"; + bandInfo.hwndChild = m_comboBoxWindow; + + RECT comboBoxRect; + ::GetWindowRect(m_comboBoxWindow, &comboBoxRect); + bandInfo.cx = 100; + bandInfo.cxMinChild = comboBoxRect.right - comboBoxRect.left; + bandInfo.cyMinChild = comboBoxRect.bottom - comboBoxRect.top; + + // Add the band to the rebar. + int result = ::SendMessage(m_rebarWindow, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&bandInfo); + + // Create the browser view. + RECT webViewRect = { 0, 0, 0, 0}; + m_browserView.create(webViewRect, this); +} + +void BrowserWindow::onDestroy() +{ + MiniBrowser::shared().unregisterWindow(this); + + // FIXME: Should we close the browser view here? +} + +void BrowserWindow::onNCDestroy() +{ + delete this; +} + +void BrowserWindow::onSize(int width, int height) +{ + RECT rebarRect; + ::GetClientRect(m_rebarWindow, &rebarRect); + + // Resize the rebar. + ::MoveWindow(m_rebarWindow, 0, 0, width, rebarRect.bottom - rebarRect.top, true); + + RECT webViewRect; + webViewRect.top = rebarRect.bottom; + webViewRect.left = 0; + webViewRect.right = width; + webViewRect.bottom = height; + m_browserView.setFrame(webViewRect); +} + +LRESULT BrowserWindow::onCommand(int commandID, bool& handled) +{ + switch (commandID) { + case ID_FILE_NEW_WINDOW: + MiniBrowser::shared().createNewWindow(); + break; + case ID_FILE_CLOSE: + ::PostMessage(m_window, WM_CLOSE, 0, 0); + break; + case ID_DEBUG_SHOW_WEB_VIEW: { + HMENU menu = ::GetMenu(m_window); + bool shouldHide = ::GetMenuState(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND) & MF_CHECKED; + + ::CheckMenuItem(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND | (shouldHide ? MF_UNCHECKED : MF_CHECKED)); + + // Show or hide the web view. + HWND webViewWindow = WKViewGetWindow(m_browserView.webView()); + ::ShowWindow(webViewWindow, shouldHide ? SW_HIDE : SW_SHOW); + break; + } + default: + handled = false; + } + + return 0; +} + +bool BrowserWindow::handleMessage(const MSG* message) +{ + if (message->hwnd != m_comboBoxWindow && !::IsChild(m_comboBoxWindow, message->hwnd)) + return false; + + // Look for a WM_KEYDOWN message. + if (message->message != WM_KEYDOWN) + return false; + + // Look for the VK_RETURN key. + if (message->wParam != VK_RETURN) + return false; + + std::vector<WCHAR> buffer; + int textLength = ::GetWindowTextLength(m_comboBoxWindow); + + buffer.resize(textLength + 1); + ::GetWindowText(m_comboBoxWindow, &buffer[0], buffer.size()); + + std::wstring url(&buffer[0], buffer.size() - 1); + + if (url.find(L"http://")) + url = L"http://" + url; + + m_browserView.goToURL(url); + + // We handled this message. + return true; +} |