首页 > 代码库 > juce中真正的窗口过程

juce中真正的窗口过程


技术分享
函数所在的具体位置。
    LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            //==============================================================================
            case WM_NCHITTEST:
                if ((styleFlags & windowIgnoresMouseClicks) != 0)
                    return HTTRANSPARENT;

                if (! hasTitleBar())
                    return HTCLIENT;

                break;

            //==============================================================================
            case WM_PAINT:
                handlePaintMessage();
                return 0;

            case WM_NCPAINT:
                if (wParam != 1) // (1 = a repaint of the entire NC region)
                    handlePaintMessage(); // this must be done, even with native titlebars, or there are rendering artifacts.

                if (hasTitleBar())
                    break; // let the DefWindowProc handle drawing the frame.

                return 0;

            case WM_ERASEBKGND:
            case WM_NCCALCSIZE:
                if (hasTitleBar())
                    break;

                return 1;

            //==============================================================================
            case WM_MOUSEMOVE:          doMouseMove (getPointFromLParam (lParam)); return 0;
            case WM_MOUSELEAVE:         doMouseExit(); return 0;

            case WM_LBUTTONDOWN:
            case WM_MBUTTONDOWN:
            case WM_RBUTTONDOWN:        doMouseDown (getPointFromLParam (lParam), wParam); return 0;

            case WM_LBUTTONUP:
            case WM_MBUTTONUP:
            case WM_RBUTTONUP:          doMouseUp (getPointFromLParam (lParam), wParam); return 0;

            case 0x020A: /* WM_MOUSEWHEEL */   doMouseWheel (wParam, true);  return 0;
            case 0x020E: /* WM_MOUSEHWHEEL */  doMouseWheel (wParam, false); return 0;

            case WM_CAPTURECHANGED:     doCaptureChanged(); return 0;

            case WM_NCMOUSEMOVE:
                if (hasTitleBar())
                    break;

                return 0;

            case WM_TOUCH:
                if (getTouchInputInfo != nullptr)
                    return doTouchEvent ((int) wParam, (HTOUCHINPUT) lParam);

                break;

            case 0x119: /* WM_GESTURE */
                if (doGestureEvent (lParam))
                    return 0;

                break;

            //==============================================================================
            case WM_SIZING:                return handleSizeConstraining (*(RECT*) lParam, wParam);
            case WM_WINDOWPOSCHANGING:     return handlePositionChanging (*(WINDOWPOS*) lParam);

            case WM_WINDOWPOSCHANGED:
                if (handlePositionChanged())
                    return 0;

                break;

            //==============================================================================
            case WM_KEYDOWN:
            case WM_SYSKEYDOWN:
                if (doKeyDown (wParam))
                    return 0;

                forwardMessageToParent (message, wParam, lParam);
                break;

            case WM_KEYUP:
            case WM_SYSKEYUP:
                if (doKeyUp (wParam))
                    return 0;

                forwardMessageToParent (message, wParam, lParam);
                break;

            case WM_CHAR:
                if (doKeyChar ((int) wParam, lParam))
                    return 0;

                forwardMessageToParent (message, wParam, lParam);
                break;

            case WM_APPCOMMAND:
                if (doAppCommand (lParam))
                    return TRUE;

                break;

            case WM_MENUCHAR: // triggered when alt+something is pressed
                return MNC_CLOSE << 16; // (avoids making the default system beep)

            //==============================================================================
            case WM_SETFOCUS:
                updateKeyModifiers();
                handleFocusGain();
                break;

            case WM_KILLFOCUS:
                if (hasCreatedCaret)
                {
                    hasCreatedCaret = false;
                    DestroyCaret();
                }

                handleFocusLoss();
                break;

            case WM_ACTIVATEAPP:
                // Windows does weird things to process priority when you swap apps,
                // so this forces an update when the app is brought to the front
                if (wParam != FALSE)
                    juce_repeatLastProcessPriority();
                else
                    Desktop::getInstance().setKioskModeComponent (nullptr); // turn kiosk mode off if we lose focus

                juce_checkCurrentlyFocusedTopLevelWindow();
                modifiersAtLastCallback = -1;
                return 0;

            case WM_ACTIVATE:
                if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE)
                {
                    handleAppActivation (wParam);
                    return 0;
                }

                break;

            case WM_NCACTIVATE:
                // while a temporary window is being shown, prevent Windows from deactivating the
                // title bars of our main windows.
                if (wParam == 0 && ! shouldDeactivateTitleBar)
                    wParam = TRUE; // change this and let it get passed to the DefWindowProc.

                break;

            case WM_MOUSEACTIVATE:
                if (! component.getMouseClickGrabsKeyboardFocus())
                    return MA_NOACTIVATE;

                break;

            case WM_SHOWWINDOW:
                if (wParam != 0)
                {
                    component.setVisible (true);
                    handleBroughtToFront();
                }

                break;

            case WM_CLOSE:
                if (! component.isCurrentlyBlockedByAnotherModalComponent())
                    handleUserClosingWindow();

                return 0;

            case WM_QUERYENDSESSION:
                if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
                {
                    app->systemRequestedQuit();
                    return MessageManager::getInstance()->hasStopMessageBeenSent();
                }
                return TRUE;

            case WM_POWERBROADCAST:
                handlePowerBroadcast (wParam);
                break;

            case WM_SYNCPAINT:
                return 0;

            case WM_DISPLAYCHANGE:
                InvalidateRect (h, 0, 0);
                // intentional fall-through...
            case WM_SETTINGCHANGE:  // note the fall-through in the previous case!
                doSettingChange();
                break;

            case 0x2e0: // WM_DPICHANGED
                handleDPIChange();
                break;

            case WM_INITMENU:
                initialiseSysMenu ((HMENU) wParam);
                break;

            case WM_SYSCOMMAND:
                switch (wParam & 0xfff0)
                {
                case SC_CLOSE:
                    if (sendInputAttemptWhenModalMessage())
                        return 0;

                    if (hasTitleBar())
                    {
                        PostMessage (h, WM_CLOSE, 0, 0);
                        return 0;
                    }
                    break;

                case SC_KEYMENU:
                    // (NB mustn‘t call sendInputAttemptWhenModalMessage() here because of very obscure
                    // situations that can arise if a modal loop is started from an alt-key keypress).
                    if (hasTitleBar() && h == GetCapture())
                        ReleaseCapture();

                    break;

                case SC_MAXIMIZE:
                    if (! sendInputAttemptWhenModalMessage())
                        setFullScreen (true);

                    return 0;

                case SC_MINIMIZE:
                    if (sendInputAttemptWhenModalMessage())
                        return 0;

                    if (! hasTitleBar())
                    {
                        setMinimised (true);
                        return 0;
                    }
                    break;

                case SC_RESTORE:
                    if (sendInputAttemptWhenModalMessage())
                        return 0;

                    if (hasTitleBar())
                    {
                        if (isFullScreen())
                        {
                            setFullScreen (false);
                            return 0;
                        }
                    }
                    else
                    {
                        if (isMinimised())
                            setMinimised (false);
                        else if (isFullScreen())
                            setFullScreen (false);

                        return 0;
                    }
                    break;
                }

                break;

            case WM_NCLBUTTONDOWN:
                handleLeftClickInNCArea (wParam);
                break;

            case WM_NCRBUTTONDOWN:
            case WM_NCMBUTTONDOWN:
                sendInputAttemptWhenModalMessage();
                break;

            case WM_IME_SETCONTEXT:
                imeHandler.handleSetContext (h, wParam == TRUE);
                lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
                break;

            case WM_IME_STARTCOMPOSITION:  imeHandler.handleStartComposition (*this); return 0;
            case WM_IME_ENDCOMPOSITION:      imeHandler.handleEndComposition (*this, h); break;
            case WM_IME_COMPOSITION:            imeHandler.handleComposition (*this, h, lParam); return 0;

            case WM_GETDLGCODE:
                return DLGC_WANTALLKEYS;

            default:
                break;
        }

        return DefWindowProcW (h, message, wParam, lParam);
    }

看看是在什么地方被调用
  1. static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3. if (HWNDComponentPeer* const peer = getOwnerOfWindow (h))
  4. {
  5. jassert (isValidPeer (peer));
  6. return peer->peerWindowProc (h, message, wParam, lParam);
  7. }
  8. return DefWindowProcW (h, message, wParam, lParam);
  9. }
这个又在什么地方被调用?
  1. class WindowClassHolder : private DeletedAtShutdown
  2. {
  3. public:
  4. WindowClassHolder()
  5. {
  6. // this name has to be different for each app/dll instance because otherwise poor old Windows can
  7. // get a bit confused (even despite it not being a process-global window class).
  8. String windowClassName ("JUCE_");
  9. windowClassName << String::toHexString (Time::currentTimeMillis());
  10. HINSTANCE moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle();
  11. TCHAR moduleFile [1024] = { 0 };
  12. GetModuleFileName (moduleHandle, moduleFile, 1024);
  13. WORD iconNum = 0;
  14. WNDCLASSEX wcex = { 0 };
  15. wcex.cbSize = sizeof (wcex);
  16. wcex.style = CS_OWNDC;
  17. wcex.lpfnWndProc = (WNDPROC) windowProc;
  18. wcex.lpszClassName = windowClassName.toWideCharPointer();
  19. wcex.cbWndExtra = 32;
  20. wcex.hInstance = moduleHandle;
  21. wcex.hIcon = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
  22. iconNum = 1;
  23. wcex.hIconSm = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
  24. atom = RegisterClassEx (&wcex);
  25. jassert (atom != 0);
  26. isEventBlockedByModalComps = checkEventBlockedByModalComps;
  27. }
最终是在这里被调用:WindowClassHolder::getInstance()->getWindowClassName(),
  1. hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->getWindowClassName(),
  2. L"", type, 0, 0, 0, 0, parentToAddTo, 0,
  3. (HINSTANCE) Process::getCurrentModuleInstanceHandle(), 0);
这个创建函数又在下面被调用。
  1. static void* createWindowCallback (void* userData)
  2. {
  3. static_cast<HWNDComponentPeer*> (userData)->createWindow();
  4. return nullptr;
  5. }

  1. //==============================================================================
  2. HWNDComponentPeer (Component& comp, const int windowStyleFlags, HWND parent, bool nonRepainting)
  3. : ComponentPeer (comp, windowStyleFlags),
  4. dontRepaint (nonRepainting),
  5. parentToAddTo (parent),
  6. currentRenderingEngine (softwareRenderingEngine),
  7. lastPaintTime (0),
  8. lastMagnifySize (0),
  9. fullScreen (false),
  10. isDragging (false),
  11. isMouseOver (false),
  12. hasCreatedCaret (false),
  13. constrainerIsResizing (false),
  14. currentWindowIcon (0),
  15. dropTarget (nullptr),
  16. updateLayeredWindowAlpha (255)
  17. {
  18. callFunctionIfNotLocked (&createWindowCallback, this);
  19. setTitle (component.getName());
  20. if ((windowStyleFlags & windowHasDropShadow) != 0
  21. && Desktop::canUseSemiTransparentWindows()
  22. && ((! hasTitleBar()) || SystemStats::getOperatingSystemType() < SystemStats::WinVista))
  23. {
  24. shadower = component.getLookAndFeel().createDropShadowerForComponent (&component);
  25. if (shadower != nullptr)
  26. shadower->setOwner (&component);
  27. }
  28. }
这个构造函数又在下边这里被调用,真是一层接一层啊
ModifierKeys HWNDComponentPeer::currentModifiers;
ModifierKeys HWNDComponentPeer::modifiersAtLastCallback;
 
ComponentPeer* Component::createNewPeer (int styleFlags, void* parentHWND)
{
return new HWNDComponentPeer (*this, styleFlags, (HWND) parentHWND, false);
}
 
ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& component, void* parentHWND)
{
return new HWNDComponentPeer (component, ComponentPeer::windowIgnoresMouseClicks,
(HWND) parentHWND, true);
}
声明HWNDComponentPeer的时候创建了窗口并且关联了窗口过程,这样键盘鼠标消息才能到得了。在窗口过程中处理了相关的消息。下边这里调用了createpeer.
  1. //==============================================================================
  2. void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
  3. {
  4. // if component methods are being called from threads other than the message
  5. // thread, you‘ll need to use a MessageManagerLock object to make sure it‘s thread-safe.
  6. ASSERT_MESSAGE_MANAGER_IS_LOCKED
  7. if (isOpaque())
  8. styleWanted &= ~ComponentPeer::windowIsSemiTransparent;
  9. else
  10. styleWanted |= ComponentPeer::windowIsSemiTransparent;
  11. // don‘t use getPeer(), so that we only get the peer that‘s specifically
  12. // for this comp, and not for one of its parents.
  13. ComponentPeer* peer = ComponentPeer::getPeerFor (this);
  14. if (peer == nullptr || styleWanted != peer->getStyleFlags())
  15. {
  16. const WeakReference<Component> safePointer (this);
  17. #if JUCE_LINUX
  18. // it‘s wise to give the component a non-zero size before
  19. // putting it on the desktop, as X windows get confused by this, and
  20. // a (1, 1) minimum size is enforced here.
  21. setSize (jmax (1, getWidth()),
  22. jmax (1, getHeight()));
  23. #endif
  24. const Point<int> topLeft (getScreenPosition());
  25. bool wasFullscreen = false;
  26. bool wasMinimised = false;
  27. ComponentBoundsConstrainer* currentConstrainer = nullptr;
  28. Rectangle<int> oldNonFullScreenBounds;
  29. int oldRenderingEngine = -1;
  30. if (peer != nullptr)
  31. {
  32. ScopedPointer<ComponentPeer> oldPeerToDelete (peer);
  33. wasFullscreen = peer->isFullScreen();
  34. wasMinimised = peer->isMinimised();
  35. currentConstrainer = peer->getConstrainer();
  36. oldNonFullScreenBounds = peer->getNonFullScreenBounds();
  37. oldRenderingEngine = peer->getCurrentRenderingEngine();
  38. flags.hasHeavyweightPeerFlag = false;
  39. Desktop::getInstance().removeDesktopComponent (this);
  40. internalHierarchyChanged(); // give comps a chance to react to the peer change before the old peer is deleted.
  41. if (safePointer == nullptr)
  42. return;
  43. setTopLeftPosition (topLeft);
  44. }
  45. if (parentComponent != nullptr)
  46. parentComponent->removeChildComponent (this);
  47. if (safePointer != nullptr)
  48. {
  49. flags.hasHeavyweightPeerFlag = true;
  50. peer = createNewPeer (styleWanted, nativeWindowToAttachTo);
  51. Desktop::getInstance().addDesktopComponent (this);
  52. bounds.setPosition (topLeft);
  53. peer->updateBounds();
  54. if (oldRenderingEngine >= 0)
  55. peer->setCurrentRenderingEngine (oldRenderingEngine);
  56. peer->setVisible (isVisible());
  57. peer = ComponentPeer::getPeerFor (this);
  58. if (peer == nullptr)
  59. return;
  60. if (wasFullscreen)
  61. {
  62. peer->setFullScreen (true);
  63. peer->setNonFullScreenBounds (oldNonFullScreenBounds);
  64. }
  65. if (wasMinimised)
  66. peer->setMinimised (true);
  67. #if JUCE_WINDOWS
  68. if (isAlwaysOnTop())
  69. peer->setAlwaysOnTop (true);
  70. #endif
  71. peer->setConstrainer (currentConstrainer);
  72. repaint();
  73. internalHierarchyChanged();
  74. }
  75. }
  76. }




来自为知笔记(Wiz)


juce中真正的窗口过程