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);
}
看看是在什么地方被调用
static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam){if (HWNDComponentPeer* const peer = getOwnerOfWindow (h)){jassert (isValidPeer (peer));return peer->peerWindowProc (h, message, wParam, lParam);}return DefWindowProcW (h, message, wParam, lParam);}
这个又在什么地方被调用?
class WindowClassHolder : private DeletedAtShutdown{public:WindowClassHolder(){// this name has to be different for each app/dll instance because otherwise poor old Windows can// get a bit confused (even despite it not being a process-global window class).String windowClassName ("JUCE_");windowClassName << String::toHexString (Time::currentTimeMillis());HINSTANCE moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle();TCHAR moduleFile [1024] = { 0 };GetModuleFileName (moduleHandle, moduleFile, 1024);WORD iconNum = 0;WNDCLASSEX wcex = { 0 };wcex.cbSize = sizeof (wcex);wcex.style = CS_OWNDC;wcex.lpfnWndProc = (WNDPROC) windowProc;wcex.lpszClassName = windowClassName.toWideCharPointer();wcex.cbWndExtra = 32;wcex.hInstance = moduleHandle;wcex.hIcon = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);iconNum = 1;wcex.hIconSm = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);atom = RegisterClassEx (&wcex);jassert (atom != 0);isEventBlockedByModalComps = checkEventBlockedByModalComps;}
最终是在这里被调用:WindowClassHolder::getInstance()->getWindowClassName(),
hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->getWindowClassName(),L"", type, 0, 0, 0, 0, parentToAddTo, 0,(HINSTANCE) Process::getCurrentModuleInstanceHandle(), 0);
这个创建函数又在下面被调用。
static void* createWindowCallback (void* userData){static_cast<HWNDComponentPeer*> (userData)->createWindow();return nullptr;}
//==============================================================================HWNDComponentPeer (Component& comp, const int windowStyleFlags, HWND parent, bool nonRepainting): ComponentPeer (comp, windowStyleFlags),dontRepaint (nonRepainting),parentToAddTo (parent),currentRenderingEngine (softwareRenderingEngine),lastPaintTime (0),lastMagnifySize (0),fullScreen (false),isDragging (false),isMouseOver (false),hasCreatedCaret (false),constrainerIsResizing (false),currentWindowIcon (0),dropTarget (nullptr),updateLayeredWindowAlpha (255){callFunctionIfNotLocked (&createWindowCallback, this);setTitle (component.getName());if ((windowStyleFlags & windowHasDropShadow) != 0&& Desktop::canUseSemiTransparentWindows()&& ((! hasTitleBar()) || SystemStats::getOperatingSystemType() < SystemStats::WinVista)){shadower = component.getLookAndFeel().createDropShadowerForComponent (&component);if (shadower != nullptr)shadower->setOwner (&component);}}
这个构造函数又在下边这里被调用,真是一层接一层啊
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.
//==============================================================================void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo){// if component methods are being called from threads other than the message// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.ASSERT_MESSAGE_MANAGER_IS_LOCKEDif (isOpaque())styleWanted &= ~ComponentPeer::windowIsSemiTransparent;elsestyleWanted |= ComponentPeer::windowIsSemiTransparent;// don't use getPeer(), so that we only get the peer that's specifically// for this comp, and not for one of its parents.ComponentPeer* peer = ComponentPeer::getPeerFor (this);if (peer == nullptr || styleWanted != peer->getStyleFlags()){const WeakReference<Component> safePointer (this);#if JUCE_LINUX// it's wise to give the component a non-zero size before// putting it on the desktop, as X windows get confused by this, and// a (1, 1) minimum size is enforced here.setSize (jmax (1, getWidth()),jmax (1, getHeight()));#endifconst Point<int> topLeft (getScreenPosition());bool wasFullscreen = false;bool wasMinimised = false;ComponentBoundsConstrainer* currentConstrainer = nullptr;Rectangle<int> oldNonFullScreenBounds;int oldRenderingEngine = -1;if (peer != nullptr){ScopedPointer<ComponentPeer> oldPeerToDelete (peer);wasFullscreen = peer->isFullScreen();wasMinimised = peer->isMinimised();currentConstrainer = peer->getConstrainer();oldNonFullScreenBounds = peer->getNonFullScreenBounds();oldRenderingEngine = peer->getCurrentRenderingEngine();flags.hasHeavyweightPeerFlag = false;Desktop::getInstance().removeDesktopComponent (this);internalHierarchyChanged(); // give comps a chance to react to the peer change before the old peer is deleted.if (safePointer == nullptr)return;setTopLeftPosition (topLeft);}if (parentComponent != nullptr)parentComponent->removeChildComponent (this);if (safePointer != nullptr){flags.hasHeavyweightPeerFlag = true;peer = createNewPeer (styleWanted, nativeWindowToAttachTo);Desktop::getInstance().addDesktopComponent (this);bounds.setPosition (topLeft);peer->updateBounds();if (oldRenderingEngine >= 0)peer->setCurrentRenderingEngine (oldRenderingEngine);peer->setVisible (isVisible());peer = ComponentPeer::getPeerFor (this);if (peer == nullptr)return;if (wasFullscreen){peer->setFullScreen (true);peer->setNonFullScreenBounds (oldNonFullScreenBounds);}if (wasMinimised)peer->setMinimised (true);#if JUCE_WINDOWSif (isAlwaysOnTop())peer->setAlwaysOnTop (true);#endifpeer->setConstrainer (currentConstrainer);repaint();internalHierarchyChanged();}}}

浙公网安备 33010602011771号