Logo Search packages:      
Sourcecode: blender version File versions

LRESULT WINAPI GHOST_SystemWin32::s_wndProc ( HWND  hwnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
) [static, protected]

Windows call back routine for our window class.

Definition at line 517 of file GHOST_SystemWin32.cpp.

References GHOST_Window::getCursorShape(), GHOST_Window::getCursorVisibility(), GHOST_ISystem::getSystem(), GHOST_WindowWin32::loadCursor(), GHOST_WindowWin32::lostMouseCapture(), m_seperateLeftRight, m_seperateLeftRightInitialized, processButtonEvent(), processCursorEvent(), processKeyEvent(), processModifierKeys(), processWheelEvent(), processWindowEvent(), GHOST_System::pushEvent(), and GHOST_WindowWin32::registerMouseClickEvent().

Referenced by init().

{
      GHOST_Event* event = 0;
      LRESULT lResult;
      GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
      GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized")

      if (hwnd) {
            GHOST_WindowWin32* window = (GHOST_WindowWin32*)::GetWindowLong(hwnd, GWL_USERDATA);
            if (window) {
                  switch (msg) {
                        ////////////////////////////////////////////////////////////////////////
                        // Keyboard events, processed
                        ////////////////////////////////////////////////////////////////////////
                        case WM_KEYDOWN:
                              /* The WM_KEYDOWN message is posted to the window with the keyboard focus when a 
                               * nonsystem key is pressed. A nonsystem key is a key that is pressed when the alt
                               * key is not pressed. 
                               */
                        case WM_SYSKEYDOWN:
                              /* The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when 
                               * the user presses the F10 key (which activates the menu bar) or holds down the 
                               * alt key and then presses another key. It also occurs when no window currently 
                               * has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the 
                               * active window. The window that receives the message can distinguish between these 
                               * two contexts by checking the context code in the lKeyData parameter. 
                               */
                              switch (wParam) {
                                    case VK_SHIFT:
                                    case VK_CONTROL:
                                    case VK_MENU:
                                          if (!system->m_seperateLeftRightInitialized) {
                                                // Check whether this system supports seperate left and right keys
                                                switch (wParam) {
                                                      case VK_SHIFT:
                                                            system->m_seperateLeftRight = 
                                                                  (HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
                                                                  (HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
                                                                  true : false;
                                                            break;
                                                      case VK_CONTROL:
                                                            system->m_seperateLeftRight = 
                                                                  (HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
                                                                  (HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
                                                                  true : false;
                                                            break;
                                                      case VK_MENU:
                                                            system->m_seperateLeftRight = 
                                                                  (HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
                                                                  (HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
                                                                  true : false;
                                                            break;
                                                }
                                                system->m_seperateLeftRightInitialized = true;
                                          }
                                          system->processModifierKeys(window);
                                          // Bypass call to DefWindowProc
                                          return 0;
                                    default:
                                          event = processKeyEvent(window, true, wParam, lParam);
                                          if (!event) {
                                                GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
                                                GHOST_PRINT(msg)
                                                GHOST_PRINT(" key ignored\n")
                                          }
                                          break;
                                    }
                              break;

                        case WM_KEYUP:
                        case WM_SYSKEYUP:
                              switch (wParam) {
                                    case VK_SHIFT:
                                    case VK_CONTROL:
                                    case VK_MENU:
                                          system->processModifierKeys(window);
                                          // Bypass call to DefWindowProc
                                          return 0;
                                    default:
                                          event = processKeyEvent(window, false, wParam, lParam);
                                          if (!event) {
                                                GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
                                                GHOST_PRINT(msg)
                                                GHOST_PRINT(" key ignored\n")
                                          }
                                          break;
                              }
                              break;

                        ////////////////////////////////////////////////////////////////////////
                        // Keyboard events, ignored
                        ////////////////////////////////////////////////////////////////////////
                        case WM_CHAR:
                              /* The WM_CHAR message is posted to the window with the keyboard focus when 
                               * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR 
                               * contains the character code of the key that was pressed. 
                               */
                        case WM_DEADCHAR:
                              /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
                               * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR 
                               * specifies a character code generated by a dead key. A dead key is a key that 
                               * generates a character, such as the umlaut (double-dot), that is combined with 
                               * another character to form a composite character. For example, the umlaut-O 
                               * character () is generated by typing the dead key for the umlaut character, and 
                               * then typing the O key.
                               */
                        case WM_SYSDEADCHAR:
                              /* The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when 
                               * a WM_SYSKEYDOWN message is translated by the TranslateMessage function. 
                               * WM_SYSDEADCHAR specifies the character code of a system dead key - that is, 
                               * a dead key that is pressed while holding down the alt key. 
                               */
                              break;

                        ////////////////////////////////////////////////////////////////////////
                        // Mouse events, processed
                        ////////////////////////////////////////////////////////////////////////
                        case WM_LBUTTONDOWN:
                              window->registerMouseClickEvent(true);
                              event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
                              break;
                        case WM_MBUTTONDOWN:
                              window->registerMouseClickEvent(true);
                              event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
                              break;
                        case WM_RBUTTONDOWN:
                              window->registerMouseClickEvent(true);
                              event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
                              break;
                        case WM_LBUTTONUP:
                              window->registerMouseClickEvent(false);
                              event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
                              break;
                        case WM_MBUTTONUP:
                              window->registerMouseClickEvent(false);
                              event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
                              break;
                        case WM_RBUTTONUP:
                              window->registerMouseClickEvent(false);
                              event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
                              break;
                        case WM_MOUSEMOVE:
                              event = processCursorEvent(GHOST_kEventCursorMove, window);
                              break;
                        case WM_MOUSEWHEEL:
                              /* The WM_MOUSEWHEEL message is sent to the focus window 
                               * when the mouse wheel is rotated. The DefWindowProc 
                               * function propagates the message to the window's parent.
                               * There should be no internal forwarding of the message, 
                               * since DefWindowProc propagates it up the parent chain 
                               * until it finds a window that processes it.
                               */
                              event = processWheelEvent(window, wParam, lParam);
                              break;
                        case WM_SETCURSOR:
                              /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
                               * to move within a window and mouse input is not captured.
                               * This means we have to set the cursor shape every time the mouse moves!
                               * The DefWindowProc function uses this message to set the cursor to an 
                               * arrow if it is not in the client area.
                               */
                              if (LOWORD(lParam) == HTCLIENT) {
                                    // Load the current cursor
                                    window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
                                    // Bypass call to DefWindowProc
                                    return 0;
                              } 
                              else {
                                    // Outside of client area show standard cursor
                                    window->loadCursor(true, GHOST_kStandardCursorDefault);
                              }
                              break;

                        ////////////////////////////////////////////////////////////////////////
                        // Mouse events, ignored
                        ////////////////////////////////////////////////////////////////////////
                        case WM_NCMOUSEMOVE:
                              /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved 
                               * within the nonclient area of the window. This message is posted to the window 
                               * that contains the cursor. If a window has captured the mouse, this message is not posted.
                               */
                        case WM_NCHITTEST:
                              /* The WM_NCHITTEST message is sent to a window when the cursor moves, or 
                               * when a mouse button is pressed or released. If the mouse is not captured, 
                               * the message is sent to the window beneath the cursor. Otherwise, the message 
                               * is sent to the window that has captured the mouse. 
                               */
                              break;

                        ////////////////////////////////////////////////////////////////////////
                        // Window events, processed
                        ////////////////////////////////////////////////////////////////////////
                        case WM_CLOSE:
                              /* The WM_CLOSE message is sent as a signal that a window or an application should terminate. */
                              event = processWindowEvent(GHOST_kEventWindowClose, window);
                              break;
                        case WM_ACTIVATE:
                              /* The WM_ACTIVATE message is sent to both the window being activated and the window being 
                               * deactivated. If the windows use the same input queue, the message is sent synchronously, 
                               * first to the window procedure of the top-level window being deactivated, then to the window
                               * procedure of the top-level window being activated. If the windows use different input queues,
                               * the message is sent asynchronously, so the window is activated immediately. 
                               */
                              event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
                              break;
                        case WM_PAINT:
                              /* An application sends the WM_PAINT message when the system or another application 
                               * makes a request to paint a portion of an application's window. The message is sent
                               * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage 
                               * function when the application obtains a WM_PAINT message by using the GetMessage or 
                               * PeekMessage function. 
                               */
                              event = processWindowEvent(GHOST_kEventWindowUpdate, window);
                              ::ValidateRect(hwnd, NULL);
                              break;
                        case WM_SIZE:
                              /* The WM_SIZE message is sent to a window after its size has changed.
                               * The WM_SIZE and WM_MOVE messages are not sent if an application handles the 
                               * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
                               * to perform any move or size change processing during the WM_WINDOWPOSCHANGED 
                               * message without calling DefWindowProc.
                               */
                              event = processWindowEvent(GHOST_kEventWindowSize, window);
                        case WM_CAPTURECHANGED:
                              window->lostMouseCapture();
                              break;

                        ////////////////////////////////////////////////////////////////////////
                        // Window events, ignored
                        ////////////////////////////////////////////////////////////////////////
                        case WM_WINDOWPOSCHANGED:
                              /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place
                               * in the Z order has changed as a result of a call to the SetWindowPos function or 
                               * another window-management function.
                               * The WM_SIZE and WM_MOVE messages are not sent if an application handles the 
                               * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
                               * to perform any move or size change processing during the WM_WINDOWPOSCHANGED 
                               * message without calling DefWindowProc.
                               */
                        case WM_MOVE:
                              /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the 
                               * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
                               * to perform any move or size change processing during the WM_WINDOWPOSCHANGED 
                               * message without calling DefWindowProc. 
                               */
                        case WM_ERASEBKGND:
                              /* An application sends the WM_ERASEBKGND message when the window background must be 
                               * erased (for example, when a window is resized). The message is sent to prepare an 
                               * invalidated portion of a window for painting. 
                               */
                        case WM_NCPAINT:
                              /* An application sends the WM_NCPAINT message to a window when its frame must be painted. */
                        case WM_NCACTIVATE:
                              /* The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed 
                               * to indicate an active or inactive state. 
                               */
                        case WM_DESTROY:
                              /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window 
                               * procedure of the window being destroyed after the window is removed from the screen.   
                               * This message is sent first to the window being destroyed and then to the child windows 
                               * (if any) as they are destroyed. During the processing of the message, it can be assumed 
                               * that all child windows still exist. 
                               */
                        case WM_NCDESTROY:
                              /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The 
                               * DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
                               * message. WM_DESTROY is used to free the allocated memory object associated with the window. 
                               */
                        case WM_KILLFOCUS:
                              /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. */
                        case WM_SHOWWINDOW:
                              /* The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. */
                        case WM_WINDOWPOSCHANGING:
                              /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in 
                               * the Z order is about to change as a result of a call to the SetWindowPos function or 
                               * another window-management function. 
                               */
                        case WM_SETFOCUS:
                              /* The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. */
                        case WM_MOVING:
                              /* The WM_MOVING message is sent to a window that the user is moving. By processing 
                               * this message, an application can monitor the size and position of the drag rectangle
                               * and, if needed, change its size or position.
                               */
                        case WM_ENTERSIZEMOVE:
                              /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving 
                               * or sizing modal loop. The window enters the moving or sizing modal loop when the user 
                               * clicks the window's title bar or sizing border, or when the window passes the 
                               * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the 
                               * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when 
                               * DefWindowProc returns. 
                               */
                              break;
                              
                        ////////////////////////////////////////////////////////////////////////
                        // Other events
                        ////////////////////////////////////////////////////////////////////////
                        case WM_GETTEXT:
                              /* An application sends a WM_GETTEXT message to copy the text that 
                               * corresponds to a window into a buffer provided by the caller. 
                               */
                        case WM_ACTIVATEAPP:
                              /* The WM_ACTIVATEAPP message is sent when a window belonging to a 
                               * different application than the active window is about to be activated.
                               * The message is sent to the application whose window is being activated
                               * and to the application whose window is being deactivated. 
                               */
                        case WM_TIMER:
                              /* The WIN32 docs say:
                               * The WM_TIMER message is posted to the installing thread's message queue
                               * when a timer expires. You can process the message by providing a WM_TIMER
                               * case in the window procedure. Otherwise, the default window procedure will
                               * call the TimerProc callback function specified in the call to the SetTimer
                               * function used to install the timer. 
                               *
                               * In GHOST, we let DefWindowProc call the timer callback.
                               */
                              break;
                  }
            }
            else {
                  // Event found for a window before the pointer to the class has been set.
                  GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n")
                  /* These are events we typically miss at this point:
                     WM_GETMINMAXINFO     0x24
                     WM_NCCREATE                0x81
                     WM_NCCALCSIZE        0x83
                     WM_CREATE                  0x01
                     We let DefWindowProc do the work.
                  */
            }
      }
      else {
            // Events without valid hwnd
            GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n")
      }

      if (event) {
            system->pushEvent(event);
            lResult = 0;
      }
      else {
            lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
      }
      return lResult;
}


Generated by  Doxygen 1.6.0   Back to index