void CResizableLayout::EnumAndClipChildWindow(HWND hWnd, CDC* pDC)
{
	// obtain window position
	CRect rect;
	::GetWindowRect(hWnd, &rect);
	GetResizableWnd()->ScreenToClient(&rect);
	pDC->DPtoLP(&rect);

	// use window region if any
	CRgn rgn;
	rgn.CreateRectRgn(0,0,0,0);
	if (COMPLEXREGION == ::GetWindowRgn(hWnd, rgn))
	{
		rgn.OffsetRgn(rect.TopLeft());
	}
	else
	{
		rgn.SetRectRgn(&rect);
	}

	// go clipping?
	if (LikesClipping(hWnd))
		pDC->SelectClipRgn(&rgn, RGN_DIFF);
	else
		pDC->SelectClipRgn(&rgn, RGN_OR);
}
void CResizableLayout::ClipChildWindow(const CResizableLayout::LayoutInfo& layout,
									   CRgn* pRegion)
{
	// obtain window position
	CRect rect;
	::GetWindowRect(layout.hWnd, &rect);
	::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2);

	// use window region if any
	CRgn rgn;
	rgn.CreateRectRgn(0,0,0,0);
	switch (::GetWindowRgn(layout.hWnd, rgn))
	{
	case COMPLEXREGION:
	case SIMPLEREGION:
		rgn.OffsetRgn(rect.TopLeft());
		break;

	default:
		rgn.SetRectRgn(&rect);
	}

	// get the clipping property
	BOOL bClipping = layout.properties.bAskClipping ?
		LikesClipping(layout) : layout.properties.bCachedLikesClipping;

	// modify region accordingly
	if (bClipping)
		pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF);
	else
		pRegion->CombineRgn(pRegion, &rgn, RGN_OR);
}
/*!
 *  This function is used to set the initial resize properties of a control
 *  in the layout, that are stored in the @c properties member of the
 *  related @c LAYOUTINFO structure.
 *  
 *  @param layout Reference to the @c LAYOUTINFO structure to be set
 *
 *  @remarks The various flags are used to specify whether the resize
 *           properties (clipping, refresh) can change at run-time, and a new
 *           call to the property querying functions is needed at every
 *           layout update, or they are static properties, and the cached
 *           value is used whenever necessary.
 *        @n The default implementation sends a registered message to the 
 *           control, giving it the opportunity to specify its resize
 *           properties, which takes precedence if the message is supported.
 *           It then sets the @a clipping property as static, calling
 *           @c LikesClipping only once, and the @a refresh property as
 *           dynamic, causing @c NeedsRefresh to be called every time.
 *        @n This should be right for most situations, as the need for
 *           @a refresh usually depends on the size fo a control, while the
 *           support for @a clipping is usually linked to the specific type
 *           of control, which is unlikely to change at run-time, but you can
 *           still override this function if a different beahvior is needed.
 *
 *  @sa LikesClipping NeedsRefresh LAYOUTINFO RESIZEPROPERTIES
 */
void CResizableLayout::InitResizeProperties(LAYOUTINFO &layout) const
{
	// check if custom window supports this library
	// (properties must be correctly set by the window)
	layout.bMsgSupport = Send_QueryProperties(layout.hWnd, &layout.properties);

	// default properties
	if (!layout.bMsgSupport)
	{
		// clipping property is assumed as static
		layout.properties.bAskClipping = FALSE;
		layout.properties.bCachedLikesClipping = LikesClipping(layout);
		// refresh property is assumed as dynamic
		layout.properties.bAskRefresh = TRUE;
	}
}
/*!
 *  @internal This function adds or removes a control window region
 *  to or from the specified clipping region, according to its layout
 *  properties.
 */
void CResizableLayout::ClipChildWindow(const LAYOUTINFO& layout,
									   CRgn* pRegion) const
{
	// obtain window position
	CRect rect;
	::GetWindowRect(layout.hWnd, &rect);
#if (_WIN32_WINNT >= 0x0501)
	//! @todo decide when to clip client only or non-client too (themes?)
	//! (leave disabled meanwhile, until I find a good solution)
	//! @note wizard97 with watermark bitmap and themes won't look good!
	// if (real_WIN32_WINNT >= 0x501)
	//	::SendMessage(layout.hWnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect);
#endif
	::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2);

	// use window region if any
	CRgn rgn;
	rgn.CreateRectRgn(0,0,0,0);
	switch (::GetWindowRgn(layout.hWnd, rgn))
	{
	case COMPLEXREGION:
	case SIMPLEREGION:
		rgn.OffsetRgn(rect.TopLeft());
		break;

	default:
		rgn.SetRectRgn(&rect);
	}

	// get the clipping property
	BOOL bClipping = layout.properties.bAskClipping ?
		LikesClipping(layout) : layout.properties.bCachedLikesClipping;

	// modify region accordingly
	if (bClipping)
		pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF);
	else
		pRegion->CombineRgn(pRegion, &rgn, RGN_OR);
}