Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

338 lines
9.2 KiB

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFXCTL_CORE2_SEG
#pragma code_seg(AFXCTL_CORE2_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
static const int _nResizeStyle =
CRectTracker::resizeInside | CRectTracker::resizeOutside;
static void PASCAL _OffsetTrackerRect(CRect& rect, CWnd* pWnd)
{
DWORD dwStyle = pWnd->GetStyle();
DWORD dwExStyle = pWnd->GetExStyle();
int nBorders = ((dwStyle & WS_BORDER) != 0) +
((dwExStyle & WS_EX_CLIENTEDGE) != 0) * 2;
int dx = -nBorders * GetSystemMetrics(SM_CXBORDER);
int dy = -nBorders * GetSystemMetrics(SM_CYBORDER);
if (dwExStyle & WS_EX_LEFTSCROLLBAR)
dx -= GetSystemMetrics(SM_CXVSCROLL);
rect.OffsetRect(dx - rect.left, dy - rect.top);
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::CreateTracker - Creates tracker for UIActive control
void COleControl::CreateTracker(BOOL bHandles, BOOL bHatching)
{
ASSERT(bHandles || bHatching);
ASSERT(!m_bOpen);
ASSERT(m_bUIActive);
ASSERT(m_pRectTracker == NULL);
UINT nStyle = 0;
if (bHandles)
nStyle |= CRectTracker::resizeOutside;
if (bHatching)
nStyle |= CRectTracker::hatchedBorder;
ASSERT(nStyle != 0);
TRY
{
// Create the tracker.
CRect rectTmp = m_rcPos;
_OffsetTrackerRect(rectTmp, this);
m_pRectTracker = new CRectTracker(rectTmp, nStyle);
UINT nHandleSize = m_pRectTracker->m_nHandleSize++;
// Enlarge window to expose non-client area.
CWnd* pWndOuter = GetOuterWindow();
CWnd* pWndParent = pWndOuter->GetParent();
CRect rectWindow;
CRect rectParent;
pWndOuter->GetWindowRect(rectWindow);
pWndParent->GetClientRect(rectParent);
pWndParent->ClientToScreen(rectParent);
rectWindow.OffsetRect(-rectParent.left, -rectParent.top);
rectWindow.InflateRect(nHandleSize, nHandleSize);
::MoveWindow(pWndOuter->m_hWnd, rectWindow.left, rectWindow.top,
rectWindow.Width(), rectWindow.Height(), TRUE);
}
CATCH (CException, e)
{
// If anything went wrong, just continue without the tracker.
if (m_pRectTracker != NULL)
{
delete m_pRectTracker;
m_pRectTracker = NULL;
}
}
END_CATCH
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::DestroyTracker - destroys tracker when control UIDeactivates
void COleControl::DestroyTracker()
{
ASSERT(!m_bOpen);
ASSERT(m_bUIActive);
if (m_pRectTracker == NULL)
return;
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
// Destroy the tracker.
delete m_pRectTracker;
m_pRectTracker = NULL;
// Restore window to its original (pre-UIActive) size.
CWnd* pWndOuter = GetOuterWindow();
CWnd* pWndParent = pWndOuter->GetParent();
CRect rectWindow;
CRect rectParent;
pWndOuter->GetWindowRect(rectWindow);
pWndParent->GetClientRect(rectParent);
pWndParent->ClientToScreen(rectParent);
rectWindow.OffsetRect(-rectParent.left, -rectParent.top);
rectWindow.InflateRect(-(int)nHandleSize, -(int)nHandleSize);
::MoveWindow(pWndOuter->m_hWnd, rectWindow.left, rectWindow.top,
rectWindow.Width(), rectWindow.Height(), TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::OnNcPaint - handler for WM_NCPAINT message
void COleControl::OnNcPaint()
{
if (m_bOpen || m_pRectTracker == NULL)
{
Default();
return;
}
DWORD dwStyle = GetStyle();
DWORD dwExStyle = GetExStyle();
DWORD dwScrollStyle = dwStyle & (WS_HSCROLL | WS_VSCROLL);
// Paint scrollbars, if any.
if (dwScrollStyle != 0)
Default();
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
CWindowDC dc(this);
// Convert client coords to window coords, draw tracker, and convert back.
CRect& rectTrack = m_pRectTracker->m_rect;
int dx = rectTrack.left - nHandleSize;
int dy = rectTrack.top - nHandleSize;
rectTrack.OffsetRect(-dx, -dy);
CRect rc = rectTrack;
m_pRectTracker->Draw(&dc);
m_pRectTracker->m_rect.OffsetRect(dx, dy);
// Draw border, if any.
_AfxDrawBorders(&dc, rc, (dwStyle & WS_BORDER),
(dwExStyle & WS_EX_CLIENTEDGE));
if (dwScrollStyle == (WS_HSCROLL | WS_VSCROLL))
{
// Workaround for Windows bug:
// Draw the corner between the scrollbars
int cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
if (dwExStyle & WS_EX_LEFTSCROLLBAR) // Middle East Windows only
rc.right = rc.left + cxVScroll;
else
rc.left = rc.right - cxVScroll;
rc.top = rc.bottom - GetSystemMetrics(SM_CYVSCROLL);
CBrush brushGUI(GetSysColor(COLOR_3DFACE));
dc.FillRect(rc, &brushGUI);
}
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::OnNcCalcSize - handler for WM_NCCALCSIZE message
void COleControl::OnNcCalcSize(BOOL, NCCALCSIZE_PARAMS* lpParams)
{
Default();
if (m_bOpen || m_pRectTracker == NULL)
return;
// Adjust client rect to make room for tracker.
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
::InflateRect(lpParams->rgrc, -(int)nHandleSize, -(int)nHandleSize);
m_pRectTracker->m_rect = m_rcPos;
_OffsetTrackerRect(m_pRectTracker->m_rect, this);
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::OnNcHitTest - handler for WM_NCHITTEST message
UINT COleControl::OnNcHitTest(CPoint point)
{
if (m_bOpen || m_pRectTracker == NULL ||
!(m_pRectTracker->m_nStyle & _nResizeStyle))
{
return (UINT)Default();
}
UINT nHitCode = (UINT)Default();
// Check for scrollbar or sizebox hit.
if ((nHitCode == HTHSCROLL) || (nHitCode == HTVSCROLL) ||
(nHitCode == HTSIZE))
{
return nHitCode;
}
// Check for client area hit.
CPoint pointClient(point);
ScreenToClient(&pointClient);
CRect rect;
GetClientRect(rect);
if (rect.PtInRect(pointClient))
return HTCLIENT;
// Check for border hit.
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
GetWindowRect(rect);
rect.InflateRect(-(int)nHandleSize, -(int)nHandleSize);
if (rect.PtInRect(point))
return HTBORDER;
// If tracker detects a hit, return HTBORDER; otherwise HTNOWHERE.
nHitCode = m_pRectTracker->HitTest(pointClient);
return (nHitCode == CRectTracker::hitNothing) ? HTNOWHERE : HTBORDER;
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::OnNcLButtonDown - handler for WM_NCLBUTTONDOWN message
void COleControl::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (m_bOpen || m_pRectTracker == NULL ||
!(m_pRectTracker->m_nStyle & _nResizeStyle) ||
(nHitTest == HTHSCROLL) || (nHitTest == HTVSCROLL))
{
Default();
return;
}
ScreenToClient(&point);
AfxLockTempMaps();
// Setup a (semi-)permanent CWnd for the control's parent window
CRect rectBefore = m_pRectTracker->m_rect;
CWnd* pWndClip = CWnd::FromHandle(::GetParent(GetOuterWindow()->m_hWnd));
// Move or resize the tracker.
BOOL bTrack = m_pRectTracker->Track(this, point, FALSE, pWndClip);
AfxUnlockTempMaps();
if (bTrack)
{
ASSERT(m_pInPlaceSite);
CRect rectAfter = m_pRectTracker->m_rect;
if (rectBefore != rectAfter)
{
// If rectangle changed, adjust the tracker's rectangle and move
// the control.
m_pRectTracker->m_rect.OffsetRect(-m_pRectTracker->m_rect.left,
-m_pRectTracker->m_rect.top);
CWnd* pWndOuter = GetOuterWindow();
CWnd* pWndParent = pWndOuter->GetParent();
CRect rectWindow;
CRect rectParent;
pWndOuter->GetWindowRect(rectWindow);
pWndParent->GetClientRect(rectParent);
pWndParent->ClientToScreen(rectParent);
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
rectAfter.OffsetRect(rectWindow.left - rectParent.left +
nHandleSize, rectWindow.top - rectParent.top + nHandleSize);
// Update the control's extents.
SIZEL szlPixels;
SIZEL szlHimetric;
szlPixels.cx = (long)rectAfter.Width();
szlPixels.cy = (long)rectAfter.Height();
_AfxXformSizeInPixelsToHimetric(NULL, &szlPixels, &szlHimetric);
if ((m_cxExtent != szlHimetric.cx) ||
(m_cyExtent != szlHimetric.cy))
{
m_cxExtent = szlHimetric.cx;
m_cyExtent = szlHimetric.cy;
SetModifiedFlag();
}
// Move/resize the control's window.
m_pInPlaceSite->OnPosRectChange(rectAfter);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::OnSetCursor - handler for WM_SETCURSOR message
BOOL COleControl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT)
{
if (m_bOpen || m_pRectTracker == NULL ||
!(m_pRectTracker->m_nStyle & _nResizeStyle))
{
return (BOOL)Default();
}
if ((nHitTest == HTCLIENT) || (nHitTest == HTHSCROLL) ||
(nHitTest == HTVSCROLL) || (nHitTest == HTSIZE))
{
// In client area: use default cursor or arrow.
if (!Default())
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
}
else
{
// In non-client area: use tracker-supplied cursor.
m_pRectTracker->SetCursor(pWnd, HTCLIENT);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif