Ejemplo n.º 1
0
    Window::Window(const String& windowname, size_t width, size_t height, bool fullscreen)
        : NonCopyable(), EventEmitter(), RenderingTarget()
    {
    	setName(windowname);
        m_title       = windowname;
        m_rect.width  = width;
        m_rect.height = height;
        m_rect.x      = 0;
        m_rect.y      = 0;
        m_fullscreen  = fullscreen;
        m_cursorShown = true;
        m_status      = StatusNull;

        documentEvent(WindowCreatedEvent::Hash,   "Window is created. There are no garantee that the window has been showed or drawned. This event is sended after \"create\" has been called.");
        documentEvent(WindowDestroyedEvent::Hash, "Window is destroyed. This event is sended after \"destroy\" has been called.");
        documentEvent(WindowMovedEvent::Hash,     "Window has been moved. Event field \"Position\" contains the new position of the window.");
        documentEvent(WindowSizedEvent::Hash,     "Window has been resized. Event field \"Size\" contains the new size of the window.");
        documentEvent(WindowClosingEvent::Hash,   "Window is closing.");
        documentEvent(WindowShowedEvent::Hash,    "Window is showed. There is no garantee that the function \"show\" is a success.");
        documentEvent(WindowHideEvent::Hash,      "Window is hidden. There is no garantee that the function \"hide\" is a success.");
    }
LRESULT CALLBACK
nsWindowUtil::WindowProc(HWND hwnd,
                         UINT uMsg,
                         WPARAM wParam,
                         LPARAM lParam)
{
  bool handled = true;
  WNDPROC proc;
  nsWindowUtil* self =
    (nsWindowUtil*)GetProp(hwnd, S_PROPINST);

  if (self && self->mOldProc && self->mDOMWindow) {
    proc = self->mOldProc;
  } else {
    // property not found - we don't exist anymore
    // use the original window proc
    proc = (WNDPROC)GetProp(hwnd, S_PROPPROC);
    if (!proc)
      // can't find the right process... skip over to the default
      // (this will, at the minimum, totally break the app)
      proc = DefWindowProc;
    handled = false;
  }
 
  /*
   * For this next section, including all the switches, we are simply
   * collecting messages we feel are important to collect.  Once we collect
   * all the windows messages that may be important to us, then these messages
   * are dispatched as DOM events to the window.
   */

  nsAutoString typeArg;

  POINT clientPos = { 0, 0};
  POINT screenPos = { 0, 0};

  if (handled) {
    switch (uMsg) {
      case WM_NCLBUTTONDOWN:
        switch(wParam) {
          // these are the min, max, and close buttons for
          case HTMINBUTTON:
            typeArg = NS_LITERAL_STRING("minimizing");
            break;
          case HTMAXBUTTON:
            typeArg = NS_LITERAL_STRING("maximizing");
            break;
          case HTCLOSE:
            typeArg = NS_LITERAL_STRING("closing");
            break;
          default:
            handled = false;
        }
        clientPos.x = screenPos.x = LOWORD(lParam);
        clientPos.y = screenPos.y = LOWORD(lParam);
        ::ClientToScreen(hwnd, &screenPos);
        break;
      case WM_ACTIVATE:
        switch (LOWORD(wParam)) {
          case WA_ACTIVE:
          case WA_CLICKACTIVE:
            // window is being activated
            typeArg = NS_LITERAL_STRING("activating");
            break;
          default:
            handled = false;
        }
        break;
      case WM_SIZE:
        switch (wParam) {
          case SIZE_MINIMIZED:
            typeArg = NS_LITERAL_STRING("minimizing");
            break;
          default:
            // for some reason this message is received with wParam ==
            // SIZE_MAXIMIZED when the browser is shutting down, and calling
            // Restore() results in the maximized window being "restored"
            // (returned to non-maximized) size. This size is preserved
            // after restarting, which is annoying, so I'm commenting it out
            // until someone can prove that this is actually useful.
            //
            // we're resizing, but not minimized, so some part must be visible
            //typeArg = NS_LITERAL_STRING("activating");
            break;
        }
        break;
      case WM_SYSCOMMAND:
        switch (wParam) {
          case SC_CLOSE:
            //The user has clicked on the top left window icon and selected close...
            //Or the user typed Alt+F4.
            typeArg = NS_LITERAL_STRING("closing");
            break;
          default:
            handled = false;
        }
    		break;
      default:
        handled = false;
        break;
    }
  }
  
  PRBool ctrlArg = PR_FALSE;
  PRBool altArg = PR_FALSE;
  PRBool shiftArg = PR_FALSE;

  if (handled) {
    // check modifier key states
    if (::GetKeyState(VK_CONTROL) & 0x8000)
      ctrlArg = PR_TRUE;
    if (::GetKeyState(VK_MENU) & 0x8000)
      altArg = PR_TRUE;
    if (::GetKeyState(VK_SHIFT) & 0x8000)
      shiftArg = PR_TRUE;
    
    // dispatch the event
    PRBool ret = TRUE;
    nsresult rv;
    
    nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(self->mDOMWindow, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMDocument> document;
    rv = self->mDOMWindow->GetDocument(getter_AddRefs(document));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMDocumentEvent> documentEvent(do_QueryInterface(document, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMDocumentView> documentView(do_QueryInterface(document, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMAbstractView> abstractView;
    rv = documentView->GetDefaultView(getter_AddRefs(abstractView));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMEvent> event;
    rv = documentEvent->CreateEvent(NS_LITERAL_STRING("mouseevent"), getter_AddRefs(event));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mouseEvent->InitMouseEvent(typeArg, PR_TRUE, PR_TRUE, abstractView,
      1, screenPos.x, screenPos.y, clientPos.x, clientPos.y, ctrlArg, altArg,
      shiftArg, PR_FALSE, 0, nsnull);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = eventTarget->DispatchEvent(mouseEvent, &ret);
    NS_ENSURE_SUCCESS(rv, rv);

    if (!ret)
      // event was hooked
      return FALSE;
  }
  
  return CallWindowProc(proc, hwnd, uMsg, wParam, lParam);
}