|
|
#include "stdafx.h"
#include "Lava.h"
#include "NcContainer.h"
#include "MsgHelp.h"
/***************************************************************************\
***************************************************************************** * * API Implementation * ***************************************************************************** \***************************************************************************/
//------------------------------------------------------------------------------
NcContainer * GetNcContainer(DuVisual * pgad) { DuContainer * pcon = pgad->GetContainer(); AssertReadPtr(pcon);
NcContainer * pconHWND = CastNcContainer(pcon); return pconHWND; }
/***************************************************************************\
* * GdCreateNcRootGadget (Public) * * GdCreateNcRootGadget() creates a new RootGadget for an existing HWND's * non-client area. * \***************************************************************************/
HRESULT GdCreateNcRootGadget( IN HWND hwndContainer, // Window to be hosted inside
IN CREATE_INFO * pci, // Creation information
OUT DuRootGadget ** ppgadNew) // New Root Gadget
{ HRESULT hr;
//
// Build a new container and top gadget
//
NcContainer * pconNew; hr = NcContainer::Build(hwndContainer, &pconNew); if (FAILED(hr)) { return hr; }
hr = DuRootGadget::Build(pconNew, FALSE, pci, ppgadNew); if (FAILED(hr)) { pconNew->xwUnlock(); return hr; }
//
// Don't setup an initial brush when using Non-Client
//
return S_OK; }
/***************************************************************************\
***************************************************************************** * * class NcContainer * ***************************************************************************** \***************************************************************************/
//------------------------------------------------------------------------------
NcContainer::NcContainer() { m_hwndOwner = NULL; }
//------------------------------------------------------------------------------
NcContainer::~NcContainer() { //
// Need to destroy the gadget tree before this class is destructed since
// it may need to make calls to the container during its destruction. If
// we don't do this here, it may end up calling pure-virtual's on the base
// class.
//
xwDestroyGadget(); }
//------------------------------------------------------------------------------
HRESULT NcContainer::Build(HWND hwnd, NcContainer ** ppconNew) { // Check parameters
if (!ValidateHWnd(hwnd)) { return E_INVALIDARG; }
// Create a new container
NcContainer * pconNew = ClientNew(NcContainer); if (pconNew == NULL) { return E_OUTOFMEMORY; }
pconNew->m_hwndOwner = hwnd;
RECT rcWin; GetWindowRect(hwnd, &rcWin); pconNew->m_sizePxl.cx = rcWin.right - rcWin.left; pconNew->m_sizePxl.cy = rcWin.bottom - rcWin.top;
*ppconNew = pconNew; return S_OK; }
//------------------------------------------------------------------------------
void NcContainer::OnInvalidate(const RECT * prcInvalidContainerPxl) { UNREFERENCED_PARAMETER(prcInvalidContainerPxl); }
//------------------------------------------------------------------------------
void NcContainer::OnGetRect(RECT * prcDesktopPxl) { GetWindowRect(m_hwndOwner, prcDesktopPxl); }
//------------------------------------------------------------------------------
void NcContainer::OnStartCapture() { }
//------------------------------------------------------------------------------
void NcContainer::OnEndCapture() { }
//------------------------------------------------------------------------------
BOOL NcContainer::OnTrackMouseLeave() { return FALSE; }
//------------------------------------------------------------------------------
void NcContainer::OnSetFocus() { if (GetFocus() != m_hwndOwner) { //
// Setting focus is a little more complicated than pure HWND's. This is
// because Gadgets greatly simplify several things
//
// 1. SetFocus
// 2. Setup caret, if any
//
Trace("NcContainer::OnSetFocus()\n"); SetFocus(m_hwndOwner); } }
//------------------------------------------------------------------------------
void NcContainer::OnRescanMouse(POINT * pptContainerPxl) { // Trace("%p OnRescanMouse\n", GetTickCount());
POINT ptCursor; if (!GetCursorPos(&ptCursor)) { ptCursor.x = -20000; ptCursor.y = -20000; }
ScreenToClient(m_hwndOwner, &ptCursor); *pptContainerPxl = ptCursor; }
//------------------------------------------------------------------------------
BOOL NcContainer::xdHandleMessage(UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT * pr, UINT nMsgFlags) { UNREFERENCED_PARAMETER(nMsgFlags);
if (m_pgadRoot == NULL) { return FALSE; // If don't have a root, there is nothing to handle.
}
POINT ptContainerPxl;
*pr = 0;
Trace("NcContainer::HandleMessage: msg: 0x%x\n", nMsg);
switch (nMsg) { case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_NCLBUTTONDBLCLK: case WM_NCRBUTTONDBLCLK: case WM_NCMBUTTONDBLCLK: case WM_NCLBUTTONUP: case WM_NCRBUTTONUP: case WM_NCMBUTTONUP: ptContainerPxl.x = GET_X_LPARAM(lParam); ptContainerPxl.y = GET_Y_LPARAM(lParam);
if ((GetCapture() == m_hwndOwner) && (ChildWindowFromPointEx(m_hwndOwner, ptContainerPxl, CWP_SKIPINVISIBLE) != m_hwndOwner)) { ReleaseCapture(); }
{ GMSG_MOUSECLICK msg; nMsg += WM_LBUTTONDOWN - WM_NCLBUTTONDOWN;
GdConvertMouseClickMessage(&msg, nMsg, wParam);
ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { return m_pgadRoot->xdHandleMouseMessage(&msg, ptContainerPxl); } break; }
case WM_NCMOUSEMOVE: ptContainerPxl.x = GET_X_LPARAM(lParam); ptContainerPxl.y = GET_Y_LPARAM(lParam);
if ((GetCapture() == m_hwndOwner) && (ChildWindowFromPointEx(m_hwndOwner, ptContainerPxl, CWP_SKIPINVISIBLE) != m_hwndOwner)) { ReleaseCapture(); }
{ GMSG_MOUSE msg; nMsg += WM_LBUTTONDOWN - WM_NCLBUTTONDOWN;
GdConvertMouseMessage(&msg, nMsg, wParam);
ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { return m_pgadRoot->xdHandleMouseMessage(&msg, ptContainerPxl); } break; }
case WM_CAPTURECHANGED: if (m_hwndOwner != (HWND) lParam) { ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { m_pgadRoot->xdHandleMouseLostCapture(); } } break;
case WM_SETFOCUS: { ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { return m_pgadRoot->xdHandleKeyboardFocus(GSC_SET); } break; }
case WM_KILLFOCUS: { ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { return m_pgadRoot->xdHandleKeyboardFocus(GSC_LOST); } break; }
case WM_CHAR: case WM_KEYDOWN: case WM_KEYUP: case WM_SYSCHAR: case WM_SYSKEYDOWN: case WM_SYSKEYUP: { Trace("NcContainer::xdHandleMessage(Keyboard=0x%x)\n", nMsg); } break;
case WM_NCACTIVATE: { ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { m_pgadRoot->xdHandleActivate(wParam ? GSC_LOST : GSC_SET); } break; } // Fall through to WM_NCPAINT
case WM_NCPAINT: if ((!m_fManualDraw) && (m_pgadRoot != NULL)) { // HDC hdc = GetDCEx(m_hwndOwner, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN);
HDC hdc = GetWindowDC(m_hwndOwner); RECT rcInvalid; { ContextLock cl; if (cl.LockNL(ContextLock::edNone)) { m_pgadRoot->GetLogRect(&rcInvalid, SGR_CLIENT); m_pgadRoot->xrDrawTree(NULL, hdc, &rcInvalid, 0); } } ReleaseDC(m_hwndOwner, hdc); return TRUE; } break;
case WM_WINDOWPOSCHANGED: { WINDOWPOS * pwp = (WINDOWPOS *) lParam; if (!TestFlag(pwp->flags, SWP_NOSIZE)) { RECT rcWin; GetWindowRect(m_hwndOwner, &rcWin); ContextLock cl; if (cl.LockNL(ContextLock::edDefer)) { VerifyHR(m_pgadRoot->xdSetLogRect(0, 0, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top, SGR_SIZE)); } break; } } break;
case WM_GETROOTGADGET: if (m_pgadRoot != NULL) { *pr = (LRESULT) m_pgadRoot->GetHandle(); return TRUE; } break; }
return FALSE; }
|