Windows2003-3790/windows/advcore/duser/engine/lava/nccontainer.cpp
2020-09-30 16:53:55 +02:00

363 lines
9.5 KiB
C++

#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;
}