예제 #1
0
//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
                         LPARAM lParam) {
  static HWND backWnd = NULL, forwardWnd = NULL, reloadWnd = NULL,
      stopWnd = NULL, editWnd = NULL;
  static WNDPROC editWndOldProc = NULL;

  // Static members used for the find dialog.
  static FINDREPLACE fr;
  static WCHAR szFindWhat[80] = {0};
  static WCHAR szLastFindWhat[80] = {0};
  static bool findNext = false;
  static bool lastMatchCase = false;

  int wmId, wmEvent;
  PAINTSTRUCT ps;
  HDC hdc;

  if (hWnd == editWnd) {
    // Callback for the edit window
    switch (message) {
    case WM_CHAR:
      if (wParam == VK_RETURN && g_handler.get()) {
        // When the user hits the enter key load the URL
        CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
        wchar_t strPtr[MAX_URL_LENGTH+1] = {0};
        *((LPWORD)strPtr) = MAX_URL_LENGTH;
        LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
        if (strLen > 0) {
          strPtr[strLen] = 0;
          browser->GetMainFrame()->LoadURL(strPtr);
        }

        return 0;
      }
    }

    return (LRESULT)CallWindowProc(editWndOldProc, hWnd, message, wParam,
                                   lParam);
  } else if (message == uFindMsg) {
    // Find event.
    LPFINDREPLACE lpfr = (LPFINDREPLACE)lParam;

    if (lpfr->Flags & FR_DIALOGTERM) {
      // The find dialog box has been dismissed so invalidate the handle and
      // reset the search results.
      hFindDlg = NULL;
      if (g_handler.get()) {
        g_handler->GetBrowser()->GetHost()->StopFinding(true);
        szLastFindWhat[0] = 0;
        findNext = false;
      }
      return 0;
    }

    if ((lpfr->Flags & FR_FINDNEXT) && g_handler.get())  {
      // Search for the requested string.
      bool matchCase = (lpfr->Flags & FR_MATCHCASE?true:false);
      if (matchCase != lastMatchCase ||
          (matchCase && wcsncmp(szFindWhat, szLastFindWhat,
              sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0) ||
          (!matchCase && _wcsnicmp(szFindWhat, szLastFindWhat,
              sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0)) {
        // The search string has changed, so reset the search results.
        if (szLastFindWhat[0] != 0) {
          g_handler->GetBrowser()->GetHost()->StopFinding(true);
          findNext = false;
        }
        lastMatchCase = matchCase;
        wcscpy_s(szLastFindWhat, sizeof(szLastFindWhat)/sizeof(WCHAR),
            szFindWhat);
      }

      g_handler->GetBrowser()->GetHost()->Find(0, lpfr->lpstrFindWhat,
          (lpfr->Flags & FR_DOWN)?true:false, matchCase, findNext);
      if (!findNext)
        findNext = true;
    }

    return 0;
  } else {
    // Callback for the main window
    switch (message) {
    case WM_CREATE: {
      // Create the single static handler class instance
      g_handler = new ClientHandler();
      g_handler->SetMainHwnd(hWnd);

      // Create the child windows used for navigation
      RECT rect;
      int x = 0;

      GetClientRect(hWnd, &rect);

      backWnd = CreateWindow(L"BUTTON", L"Back",
                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                              | WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
                              hWnd, (HMENU) IDC_NAV_BACK, hInst, 0);
      x += BUTTON_WIDTH;

      forwardWnd = CreateWindow(L"BUTTON", L"Forward",
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                                | WS_DISABLED, x, 0, BUTTON_WIDTH,
                                URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_FORWARD,
                                hInst, 0);
      x += BUTTON_WIDTH;

      reloadWnd = CreateWindow(L"BUTTON", L"Reload",
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                                | WS_DISABLED, x, 0, BUTTON_WIDTH,
                                URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_RELOAD,
                                hInst, 0);
      x += BUTTON_WIDTH;

      stopWnd = CreateWindow(L"BUTTON", L"Stop",
                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                              | WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
                              hWnd, (HMENU) IDC_NAV_STOP, hInst, 0);
      x += BUTTON_WIDTH;

      editWnd = CreateWindow(L"EDIT", 0,
                              WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
                              ES_AUTOVSCROLL | ES_AUTOHSCROLL| WS_DISABLED,
                              x, 0, rect.right - BUTTON_WIDTH * 4,
                              URLBAR_HEIGHT, hWnd, 0, hInst, 0);

      // Assign the edit window's WNDPROC to this function so that we can
      // capture the enter key
      editWndOldProc =
          reinterpret_cast<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
      SetWindowLongPtr(editWnd, GWLP_WNDPROC,
          reinterpret_cast<LONG_PTR>(WndProc));
      g_handler->SetEditHwnd(editWnd);
      g_handler->SetButtonHwnds(backWnd, forwardWnd, reloadWnd, stopWnd);

      rect.top += URLBAR_HEIGHT;

      CefWindowInfo info;
      CefBrowserSettings settings;

      if (AppIsOffScreenRenderingEnabled()) {
        CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
        bool transparent =
            cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);

        CefRefPtr<OSRWindow> osr_window =
            OSRWindow::Create(&g_main_browser_provider, transparent);
        osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
        info.SetAsOffScreen(osr_window->hwnd());
        info.SetTransparentPainting(transparent ? TRUE : FALSE);
        g_handler->SetOSRHandler(osr_window.get());
      } else {
        // Initialize window info to the defaults for a child window.
        info.SetAsChild(hWnd, rect);
      }

      // Creat the new child browser window
      CefBrowserHost::CreateBrowser(info, g_handler.get(),
          g_handler->GetStartupURL(), settings, NULL);

      return 0;
    }

    case WM_COMMAND: {
      CefRefPtr<CefBrowser> browser;
      if (g_handler.get())
        browser = g_handler->GetBrowser();

      wmId    = LOWORD(wParam);
      wmEvent = HIWORD(wParam);
      // Parse the menu selections:
      switch (wmId) {
      case IDM_ABOUT:
        DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
        return 0;
      case IDM_EXIT:
        if (g_handler.get())
          g_handler->CloseAllBrowsers(false);
        return 0;
      case ID_WARN_CONSOLEMESSAGE:
        if (g_handler.get()) {
          std::wstringstream ss;
          ss << L"Console messages will be written to "
              << std::wstring(CefString(g_handler->GetLogFile()));
          MessageBox(hWnd, ss.str().c_str(), L"Console Messages",
              MB_OK | MB_ICONINFORMATION);
        }
        return 0;
      case ID_WARN_DOWNLOADCOMPLETE:
      case ID_WARN_DOWNLOADERROR:
        if (g_handler.get()) {
          std::wstringstream ss;
          ss << L"File \"" <<
              std::wstring(CefString(g_handler->GetLastDownloadFile())) <<
              L"\" ";

          if (wmId == ID_WARN_DOWNLOADCOMPLETE)
            ss << L"downloaded successfully.";
          else
            ss << L"failed to download.";

          MessageBox(hWnd, ss.str().c_str(), L"File Download",
              MB_OK | MB_ICONINFORMATION);
        }
        return 0;
      case ID_FIND:
        if (!hFindDlg) {
          // Create the find dialog.
          ZeroMemory(&fr, sizeof(fr));
          fr.lStructSize = sizeof(fr);
          fr.hwndOwner = hWnd;
          fr.lpstrFindWhat = szFindWhat;
          fr.wFindWhatLen = sizeof(szFindWhat);
          fr.Flags = FR_HIDEWHOLEWORD | FR_DOWN;

          hFindDlg = FindText(&fr);
        } else {
          // Give focus to the existing find dialog.
          ::SetFocus(hFindDlg);
        }
        return 0;
      case IDC_NAV_BACK:   // Back button
        if (browser.get())
          browser->GoBack();
        return 0;
      case IDC_NAV_FORWARD:  // Forward button
        if (browser.get())
          browser->GoForward();
        return 0;
      case IDC_NAV_RELOAD:  // Reload button
        if (browser.get())
          browser->Reload();
        return 0;
      case IDC_NAV_STOP:  // Stop button
        if (browser.get())
          browser->StopLoad();
        return 0;
      case ID_TESTS_GETSOURCE:  // Test the GetSource function
        if (browser.get())
          RunGetSourceTest(browser);
        return 0;
      case ID_TESTS_GETTEXT:  // Test the GetText function
        if (browser.get())
          RunGetTextTest(browser);
        return 0;
      case ID_TESTS_POPUP:  // Test a popup window
        if (browser.get())
          RunPopupTest(browser);
        return 0;
      case ID_TESTS_REQUEST:  // Test a request
        if (browser.get())
          RunRequestTest(browser);
        return 0;
      case ID_TESTS_PLUGIN_INFO:  // Test plugin info
        if (browser.get())
          RunPluginInfoTest(browser);
        return 0;
      case ID_TESTS_ZOOM_IN:
        if (browser.get())
          ModifyZoom(browser, 0.5);
        return 0;
      case ID_TESTS_ZOOM_OUT:
        if (browser.get())
          ModifyZoom(browser, -0.5);
        return 0;
      case ID_TESTS_ZOOM_RESET:
        if (browser.get())
          browser->GetHost()->SetZoomLevel(0.0);
        return 0;
      case ID_TESTS_TRACING_BEGIN:
        g_handler->BeginTracing();
        return 0;
      case ID_TESTS_TRACING_END:
        g_handler->EndTracing();
        return 0;
      case ID_TESTS_PRINT:
        if(browser.get())
          browser->GetHost()->Print();
        return 0;
      case ID_TESTS_OTHER_TESTS:
        if (browser.get())
          RunOtherTests(browser);
        return 0;
      }
      break;
    }

    case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      EndPaint(hWnd, &ps);
      return 0;

    case WM_SETFOCUS:
      if (g_handler.get() && g_handler->GetBrowser()) {
        if (AppIsOffScreenRenderingEnabled()) {
          // Give focus to the OSR window.
          CefRefPtr<OSRWindow> osr_window =
              static_cast<OSRWindow*>(g_handler->GetOSRHandler().get());
          if (osr_window)
            ::SetFocus(osr_window->hwnd());
        } else {
          // Give focus to the browser.
          g_handler->GetBrowser()->GetHost()->SetFocus(true);
        }
      }
      return 0;

    case WM_SIZE:
      // Minimizing resizes the window to 0x0 which causes our layout to go all
      // screwy, so we just ignore it.
      if (wParam != SIZE_MINIMIZED && g_handler.get() &&
          g_handler->GetBrowser()) {
        CefWindowHandle hwnd =
            g_handler->GetBrowser()->GetHost()->GetWindowHandle();
        if (hwnd) {
          // Resize the browser window and address bar to match the new frame
          // window size
          RECT rect;
          GetClientRect(hWnd, &rect);
          rect.top += URLBAR_HEIGHT;

          int urloffset = rect.left + BUTTON_WIDTH * 4;

          HDWP hdwp = BeginDeferWindowPos(1);
          hdwp = DeferWindowPos(hdwp, editWnd, NULL, urloffset,
            0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
          hdwp = DeferWindowPos(hdwp, hwnd, NULL,
            rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
            SWP_NOZORDER);
          EndDeferWindowPos(hdwp);
        }
      }
      break;

    case WM_ERASEBKGND:
      if (g_handler.get() && g_handler->GetBrowser()) {
        CefWindowHandle hwnd =
            g_handler->GetBrowser()->GetHost()->GetWindowHandle();
        if (hwnd) {
          // Dont erase the background if the browser window has been loaded
          // (this avoids flashing)
          return 0;
        }
      }
      break;

    case WM_ENTERMENULOOP:
      if (!wParam) {
        // Entering the menu loop for the application menu.
        CefSetOSModalLoop(true);
      }
      break;

    case WM_EXITMENULOOP:
      if (!wParam) {
        // Exiting the menu loop for the application menu.
        CefSetOSModalLoop(false);
      }
      break;

    case WM_CLOSE:
      if (g_handler.get() && !g_handler->IsClosing()) {
        CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
        if (browser.get()) {
          // Notify the browser window that we would like to close it. This
          // will result in a call to ClientHandler::DoClose() if the
          // JavaScript 'onbeforeunload' event handler allows it.
          browser->GetHost()->CloseBrowser(false);

          // Cancel the close.
          return 0;
        }
      }

      // Allow the close.
      break;

    case WM_DESTROY:
      // Quitting CEF is handled in ClientHandler::OnBeforeClose().
      return 0;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
  }
}
예제 #2
0
//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    // callback for the main window
    switch (message)
    {
    case WM_CREATE:
    {
        // create the single static handler class instance
        g_handler = new ClientHandler();
        g_handler->SetMainHwnd(hWnd);

        // create the child windows used for navigation
        RECT rect;
        GetClientRect(hWnd, &rect);

        CefWindowInfo info;
        CefBrowserSettings settings;
        settings.web_security = STATE_DISABLED;

        // initialize window info to the defaults for a child window.
        info.SetAsChild(hWnd, rect);

        // create the new child browser window
        CefBrowserHost::CreateBrowser(info, g_handler.get(), g_handler->GetStartupURL(), settings, NULL);

        // Todo: find a better solution for applying this e.g. with timeout in case showing of windows initially fails
        //ShowWindow(hWnd, SW_SHOWDEFAULT);
        //UpdateWindow(hWnd);
        SetTimer(hWnd, TIMER_SHOW_WINDW, 5000, NULL);

        return 0;
    }

    case WM_TIMER:
        if (wParam == TIMER_SHOW_WINDW)
        {
            HWND hWndMain = g_handler->GetMainHwnd();
            if (!IsWindowVisible(hWndMain))
            {
                ShowWindow(hWndMain, g_nCmdShow);
                UpdateWindow(hWndMain);
            }
            KillTimer(hWndMain, TIMER_SHOW_WINDW);
            return 0;
        }
        return 1;

    case WM_COMMAND:
    {
        CefRefPtr<CefBrowser> browser;
        if (g_handler.get())
            browser = g_handler->GetBrowser();

        int wmId = LOWORD(wParam);
        int wmEvent = HIWORD(wParam);

        // parse the menu selections
        if (g_mapMenuCommands.find(wmId) != g_mapMenuCommands.end())
        {
            String commandId = g_mapMenuCommands[wmId];
            if (g_handler.get())
            {
                CefRefPtr<CefListValue> args = CefListValue::Create();
                args->SetString(0, commandId);
                g_handler->GetClientExtensionHandler()->InvokeCallbacks(TEXT("onMenuCommand"), args);
            }

            return 0;
        }
        else
        {
            // handle other menu commands
            switch (wmId)
            {
            case IDM_EXIT:
                if (g_handler.get())
                    g_handler->CloseAllBrowsers(false);
                return 0;
            }
        }

        break;
    }

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        return 0;

    case WM_SETFOCUS:
        if (g_handler.get() && g_handler->GetBrowser())
        {
            // pass focus to the browser window
            CefWindowHandle hwnd = g_handler->GetBrowser()->GetHost()->GetWindowHandle();
            if (hwnd)
                PostMessage(hwnd, WM_SETFOCUS, wParam, NULL);
        }
        return 0;

    case WM_SIZE:
        // minimizing resizes the window to 0x0 which causes our layout to go all
        // screwy, so we just ignore it.
        if (wParam != SIZE_MINIMIZED && g_handler.get() && g_handler->GetBrowser())
        {
            CefWindowHandle hwnd = g_handler->GetBrowser()->GetHost()->GetWindowHandle();
            if (hwnd)
            {
                // resize the browser window and address bar to match the new frame window size
                RECT rect;
                GetClientRect(hWnd, &rect);

                HDWP hdwp = BeginDeferWindowPos(1);
                hdwp = DeferWindowPos(hdwp, hwnd, NULL,
                                      rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
                EndDeferWindowPos(hdwp);
            }
        }
        break;

    case WM_ERASEBKGND:
        if (g_handler.get() && g_handler->GetBrowser())
        {
            CefWindowHandle hwnd = g_handler->GetBrowser()->GetHost()->GetWindowHandle();
            if (hwnd)
            {
                // don't erase the background if the browser window has been loaded (this avoids flashing)
                return 1;
            }
        }
        break;

    case WM_ENTERMENULOOP:
        if (!wParam)
        {
            // entering the menu loop for the application menu
            CefSetOSModalLoop(true);
        }
        break;

    case WM_EXITMENULOOP:
        if (!wParam)
        {
            // Exiting the menu loop for the application menu.
            CefSetOSModalLoop(false);
        }
        break;

    case WM_CLOSE:
        if (g_handler.get() && !g_handler->IsClosing())
        {
            WINDOWPLACEMENT wpl;
            wpl.length = sizeof(WINDOWPLACEMENT);
            GetWindowPlacement(App::GetMainHwnd(), &wpl);
            Rect r;
            r.x = wpl.rcNormalPosition.left;
            r.y = wpl.rcNormalPosition.top;
            r.w = wpl.rcNormalPosition.right - wpl.rcNormalPosition.left;
            r.h = wpl.rcNormalPosition.bottom - wpl.rcNormalPosition.top;
            SaveWindowPlacement(&r, wpl.showCmd);

            g_handler->GetClientExtensionHandler()->InvokeCallbacks(TEXT("onAppTerminating"), CefListValue::Create());

            CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
            if (browser.get())
            {
                // Notify the browser window that we would like to close it. This
                // will result in a call to ClientHandler::DoClose() if the
                // JavaScript 'onbeforeunload' event handler allows it.
                browser->GetHost()->CloseBrowser(false);

                // cancel the close
                return 0;
            }
        }

        // allow the close
        break;

    case WM_DESTROY:
        // quitting CEF is handled in ClientHandler::OnBeforeClose().
        return 0;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}