LRESULT DesktopNotificationController::Toast::WndProc()

in shell/browser/notifications/win/win32_desktop_notifications/toast.cc [246:357]


LRESULT DesktopNotificationController::Toast::WndProc(HWND hwnd,
                                                      UINT message,
                                                      WPARAM wparam,
                                                      LPARAM lparam) {
  switch (message) {
    case WM_CREATE: {
      auto*& cs = reinterpret_cast<const CREATESTRUCT*&>(lparam);
      auto* data =
          static_cast<shared_ptr<NotificationData>*>(cs->lpCreateParams);
      auto* inst = new Toast(hwnd, data);
      SetWindowLongPtr(hwnd, 0, (LONG_PTR)inst);
    } break;

    case WM_NCDESTROY:
      delete Get(hwnd);
      SetWindowLongPtr(hwnd, 0, 0);
      return 0;

    case WM_DESTROY:
      if (Get(hwnd)->uia_) {
        // free UI Automation resources associated with this window
        UiaReturnRawElementProvider(hwnd, 0, 0, nullptr);
      }
      break;

    case WM_MOUSEACTIVATE:
      return MA_NOACTIVATE;

    case WM_TIMER: {
      if (wparam == TimerID_AutoDismiss) {
        auto* inst = Get(hwnd);

        Notification notification(inst->data_);
        inst->data_->controller->OnNotificationDismissed(notification);

        inst->AutoDismiss();
      }
    }
      return 0;

    case WM_LBUTTONDOWN: {
      auto* inst = Get(hwnd);

      inst->Dismiss();

      Notification notification(inst->data_);
      if (inst->is_close_hot_)
        inst->data_->controller->OnNotificationDismissed(notification);
      else
        inst->data_->controller->OnNotificationClicked(notification);
    }
      return 0;

    case WM_MOUSEMOVE: {
      auto* inst = Get(hwnd);
      if (!inst->is_highlighted_) {
        inst->is_highlighted_ = true;

        TRACKMOUSEEVENT tme = {sizeof(tme), TME_LEAVE, hwnd};
        TrackMouseEvent(&tme);
      }

      POINT cursor = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
      inst->is_close_hot_ =
          (PtInRect(&inst->close_button_rect_, cursor) != FALSE);

      if (!inst->is_non_interactive_)
        inst->CancelDismiss();

      inst->UpdateContents();
    }
      return 0;

    case WM_MOUSELEAVE: {
      auto* inst = Get(hwnd);
      inst->is_highlighted_ = false;
      inst->is_close_hot_ = false;
      inst->UpdateContents();

      if (!inst->ease_out_active_ && inst->ease_in_pos_ == 1.0f)
        inst->ScheduleDismissal();

      // Make sure stack collapse happens if needed
      inst->data_->controller->StartAnimation();
    }
      return 0;

    case WM_WINDOWPOSCHANGED: {
      auto*& wp = reinterpret_cast<WINDOWPOS*&>(lparam);
      if (wp->flags & SWP_HIDEWINDOW) {
        if (!IsWindowVisible(hwnd))
          Get(hwnd)->is_highlighted_ = false;
      }
    } break;

    case WM_GETOBJECT:
      if (lparam == UiaRootObjectId) {
        auto* inst = Get(hwnd);
        if (!inst->uia_) {
          inst->uia_ = new UIAutomationInterface(inst);
          inst->uia_->AddRef();
        }
        // don't return the interface if it's being disconnected
        if (!inst->uia_->IsDetached()) {
          return UiaReturnRawElementProvider(hwnd, wparam, lparam, inst->uia_);
        }
      }
      break;
  }

  return DefWindowProc(hwnd, message, wparam, lparam);
}