LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc()

in libcef/browser/native/browser_platform_delegate_native_win.cc [549:654]


LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd,
                                                              UINT message,
                                                              WPARAM wParam,
                                                              LPARAM lParam) {
  CefBrowserPlatformDelegateNativeWin* platform_delegate = nullptr;
  CefBrowserHostBase* browser = nullptr;

  if (message != WM_NCCREATE) {
    platform_delegate = static_cast<CefBrowserPlatformDelegateNativeWin*>(
        gfx::GetWindowUserData(hwnd));
    if (platform_delegate) {
      browser = platform_delegate->browser_;
    }
  }

  switch (message) {
    case WM_CLOSE:
      if (browser && !browser->TryCloseBrowser()) {
        // Cancel the close.
        return 0;
      }

      // Allow the close.
      break;

    case WM_NCCREATE: {
      CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
      platform_delegate =
          reinterpret_cast<CefBrowserPlatformDelegateNativeWin*>(
              cs->lpCreateParams);
      DCHECK(platform_delegate);
      // Associate |platform_delegate| with the window handle.
      gfx::SetWindowUserData(hwnd, platform_delegate);
      platform_delegate->window_info_.window = hwnd;

      if (platform_delegate->has_frame_ &&
          base::win::IsProcessPerMonitorDpiAware()) {
        // This call gets Windows to scale the non-client area when
        // WM_DPICHANGED is fired on Windows versions >= 10.0.14393.0.
        static auto enable_non_client_dpi_scaling_func = []() {
          return reinterpret_cast<decltype(::EnableNonClientDpiScaling)*>(
              GetProcAddress(GetModuleHandle(L"user32.dll"),
                             "EnableNonClientDpiScaling"));
        }();
        platform_delegate->called_enable_non_client_dpi_scaling_ =
            !!(enable_non_client_dpi_scaling_func &&
               enable_non_client_dpi_scaling_func(hwnd));
      }
    } break;

    case WM_NCDESTROY:
      if (platform_delegate) {
        // Clear the user data pointer.
        gfx::SetWindowUserData(hwnd, NULL);

        // Force the browser to be destroyed. This will result in a call to
        // BrowserDestroyed() that will release the reference added in
        // CreateHostWindow().
        static_cast<AlloyBrowserHostImpl*>(browser)->WindowDestroyed();
      }
      break;

    case WM_SIZE:
      if (platform_delegate && platform_delegate->window_widget_) {
        // Pass window resize events to the HWND for the DesktopNativeWidgetAura
        // root window. Passing size 0x0 (wParam == SIZE_MINIMIZED, for example)
        // will cause the widget to be hidden which reduces resource usage.
        RECT rc;
        GetClientRect(hwnd, &rc);
        SetWindowPos(HWNDForWidget(platform_delegate->window_widget_), NULL,
                     rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
                     SWP_NOZORDER);
      }
      return 0;

    case WM_MOVING:
    case WM_MOVE:
      if (browser)
        browser->NotifyMoveOrResizeStarted();
      return 0;

    case WM_SETFOCUS:
      // Selecting "Close window" from the task bar menu may send a focus
      // notification even though the window is currently disabled (e.g. while
      // a modal JS dialog is displayed).
      if (browser && ::IsWindowEnabled(hwnd))
        browser->SetFocus(true);
      return 0;

    case WM_ERASEBKGND:
      return 0;

    case WM_DPICHANGED:
      if (platform_delegate && platform_delegate->has_frame_) {
        // Suggested size and position of the current window scaled for the
        // new DPI.
        const RECT* rect = reinterpret_cast<RECT*>(lParam);
        SetWindowPos(platform_delegate->GetHostWindowHandle(), NULL, rect->left,
                     rect->top, rect->right - rect->left,
                     rect->bottom - rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
      }
      break;
  }

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