函数所在的具体位置。
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_LOCKED
if (isOpaque())
styleWanted &= ~ComponentPeer::windowIsSemiTransparent;
else
styleWanted |= 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()));
#endif
const 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_WINDOWS
if (isAlwaysOnTop())
peer->setAlwaysOnTop (true);
#endif
peer->setConstrainer (currentConstrainer);
repaint();
internalHierarchyChanged();
}
}
}