📄 pagemous.cpp
字号:
/*
* PAGEMOUS.CPP
* Patron Chapter 13
*
* Implementation of mouse-related member functions of CPage.
* The remainder is in PAGE.CPP. This separate file keeps this
* grungy hit-testing/drawing code out of our way.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
//Lookups into the array using g_rgHTCode[x+y*3] in PAGEMOUS.CPP
#define YTOP 0
#define YMID 1
#define YBOT 2
#define XLEFT 0
#define XMID 1
#define XRIGHT 2
//Values to restrict sizing in CPage::OnMouseMove
#define SIZINGTOP 0x0001
#define SIZINGBOTTOM 0x0002
#define SIZINGLEFT 0x0004
#define SIZINGRIGHT 0x0008
//This array is for hit-testing lookups
static UINT g_rgHTCode[9]={HTTOPLEFT, HTTOP, HTTOPRIGHT
, HTLEFT, HTCLIENT, HTRIGHT, HTBOTTOMLEFT, HTBOTTOM
, HTBOTTOMRIGHT};
//This is for restricting tracking based on the hit-test
static UINT g_rguSizingFlags[9]={SIZINGTOP | SIZINGLEFT, SIZINGTOP
, SIZINGTOP | SIZINGRIGHT, SIZINGLEFT, 0, SIZINGRIGHT
, SIZINGBOTTOM | SIZINGLEFT, SIZINGBOTTOM
, SIZINGBOTTOM | SIZINGRIGHT};
/*
* CPage::OnLeftDown
*
* Purpose:
* Called when the user clicks with the left button on this page.
* We find the object under that position that is visibly on top
* (always the first one under this location in the page list since
* we paint in reverse order) and select it.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if the action changed the object.
*/
BOOL CPage::OnLeftDown(UINT uKeys, UINT x, UINT y)
{
UINT iTenant;
PCTenant pTenant;
//CHAPTER13MOD
/*
* If the mouse is in a position to start dragging,
* start the timer as with sizing below.
*/
if (HTCAPTION==m_uHTCode)
{
m_fDragPending=TRUE;
//Save down point and start timer.
m_ptDown.x=x;
m_ptDown.y=y;
m_uKeysDown=uKeys;
m_fTimer=TRUE;
SetTimer(m_hWnd, IDTIMER_DEBOUNCE, m_cDelay, NULL);
return FALSE;
}
//End CHAPTER13MOD
/*
* If the mouse is in a position to start sizing, start
* the debounce timer and note the condition. The sizing
* will start in OnTimer or OnMouseMove. This will always
* happen on the currently selected tenant, and m_uHTCode is
* set in OnNCHitTest below.
*/
if (HTNOWHERE!=m_uHTCode && HTCLIENT!=m_uHTCode)
{
m_fSizePending=TRUE;
//Save down point and start timer.
m_ptDown.x=x;
m_ptDown.y=y;
m_fTimer=TRUE;
SetTimer(m_hWnd, IDTIMER_DEBOUNCE, m_cDelay, NULL);
return FALSE;
}
iTenant=TenantFromPoint(x, y, &pTenant);
if (NULL==pTenant)
return FALSE;
//If this one is already current, we might be now sizing.
if (pTenant==m_pTenantCur)
return FALSE;
//Deselect the current tenant
if (NULL!=m_pTenantCur)
m_pTenantCur->Select(FALSE);
//Move this tenant to the top of the list
m_iTenantCur=0;
SendMessage(m_hWndTenantList, LB_DELETESTRING, iTenant, 0L);
SendMessage(m_hWndTenantList, LB_INSERTSTRING, 0,(LONG)pTenant);
//Select and repaint the new tenant to show it up front
m_pTenantCur=pTenant;
m_pTenantCur->Repaint();
m_pTenantCur->Select(TRUE);
return FALSE;
}
/*
* CPage::OnLeftUp
*
* Purpose:
* Called when the user clicks up with the left button on this
* page. We stop tracking on this message, if necessary, and
* resize the object.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if this action changed the object.
*/
BOOL CPage::OnLeftUp(UINT uKeys, UINT x, UINT y)
{
RECT rc, rcT;
//CHAPTER13MOD
if (m_fSizePending || m_fDragPending)
//End CHAPTER13MOD
{
m_fSizePending=FALSE;
//CHAPTER13MOD
m_fDragPending=FALSE;
//#nd CHAPTER13MOD
if (m_fTimer)
{
KillTimer(m_hWnd, IDTIMER_DEBOUNCE);
m_fTimer=FALSE;
}
return FALSE;
}
if (!m_fTracking)
return FALSE;
//Remove the dotted rectangle.
RECTFROMRECTL(rc, m_rcl)
DrawFocusRect(m_hDC, &rc);
ReleaseDC(m_hWnd, m_hDC);
ReleaseCapture();
m_fTracking=FALSE;
//If the original and new rects are the same, nothing happened.
RECTFROMRECTL(rcT, m_rclOrg);
if (EqualRect(&rc, &rcT))
return FALSE;
RECTFROMRECTL(rcT, m_rclOrg);
InvalidateRect(m_hWnd, &rcT, TRUE);
//Invalidate on the screen before accounting for scrolling
InvalidateRect(m_hWnd, &rc, TRUE);
//Factor in scrolling and tell the tenant where it now stands.
OffsetRect(&rc, (int)m_pPG->m_xPos, (int)m_pPG->m_yPos);
RECTLFROMRECT(m_rcl, rc);
m_pTenantCur->RectSet(&m_rcl, TRUE);
UpdateWindow(m_hWnd);
return TRUE;
}
/*
* CPage::OnLeftDoubleClick
*
* Purpose:
* Called when the user double-clicks with the left button on this
* page. We find the object under that position that is visibly on
* top (always the first one under this location in the page list
* since we paint in reverse order) and activate it.
*
* Parameters:
* uKeys UINT carrying the key state.
* x, y UINT coordinates of the click in device units.
*
* Return Value:
* BOOL Indicates if the action changed the object.
*/
BOOL CPage::OnLeftDoubleClick(UINT uKeys, UINT x, UINT y)
{
/*
* The current tenant is the only one that can be activated, so
* we just have to make sure the mouse is there. For that we
* can use the last hit-test code we saw since it's updated on
* every mouse move.
*/
if (HTNOWHERE!=m_uHTCode)
return m_pTenantCur->Activate(OLEIVERB_PRIMARY);
return FALSE;
}
/*
* CPage::OnMouseMove
*
* Purpose:
* Processes WM_MOUSEMOVE on a page so we can handle tracking
* resize of a tenant.
*
* Parameters:
* x, y int device coordinates to check.
*
* Return Value:
* None
*/
void CPage::OnMouseMove(UINT uKeys, int x, int y)
{
RECT rc, rcO, rcB;
int cxy;
//CHAPTER13MOD
if (m_fSizePending || m_fDragPending)
//End CHAPTER13MOD
{
int dx, dy;
dx=(x > m_ptDown.x) ? (x-m_ptDown.x) : (m_ptDown.x-x);
dy=(y > m_ptDown.y) ? (y-m_ptDown.y) : (m_ptDown.y-y);
/*
* Has the mouse moved outside the debounce distance? If
* so, we can start sizing. Note that this happens
* regardless of the timer state.
*/
if (dx > m_cxyDist || dy > m_cxyDist)
{
POINT pt;
//CHAPTER13MOD
BOOL fSize=m_fSizePending;
BOOL fDrag=m_fDragPending;
m_fSizePending=FALSE;
m_fDragPending=FALSE;
//End CHAPTER13MOD
if (m_fTimer)
{
KillTimer(m_hWnd, IDTIMER_DEBOUNCE);
m_fTimer=FALSE;
}
//CHAPTER13MOD
if (fDrag)
{
//Set dirty flag if drag & drop changed things.
m_pPG->m_fDirty |= DragDrop(m_uKeysDown, x, y);
return;
}
if (fSize)
StartSizeTracking();
//End CHAPTER13MOD
/*
* Since we might have moved out of the sizing handle
* in order to start the operation, we need to set the
* m_uSizingFlags field based on the original down point
* for subsequent mouse moves to function properly.
* Note that OnNCHitTest expects screen coordinates.
*/
SETPOINT(pt, m_ptDown.x, m_ptDown.y);
ClientToScreen(m_hWnd, &pt);
OnNCHitTest(pt.x, pt.y);
OnSetCursor(m_uHTCode);
return;
}
}
if (!m_fTracking)
return;
//Get rid of the old rectangle.
RECTFROMRECTL(rc, m_rcl)
DrawFocusRect(m_hDC, &rc);
/*
* Calculate the new. The flags in m_uSizingFlags tell us what
* to change. We limit the object by the page margins and a
* minimum size of 3*CXYHANDLE in either dimension.
*/
cxy=3*CXYHANDLE;
RECTFROMRECTL(rcO, m_rclOrg);
RECTFROMRECTL(rcB, m_rclBounds);
if (m_uSizingFlags & SIZINGTOP)
{
if (y >= rcO.bottom-cxy)
y=rcO.bottom-cxy;
if (y <= rcB.top) //Limit to top of page.
y=rcB.top;
m_rcl.top=y;
}
if (m_uSizingFlags & SIZINGBOTTOM)
{
if (y <= rcO.top+cxy)
y=rcO.top+cxy;
if (y >= rcB.bottom) //Limit to bottom of page.
y=rcB.bottom;
m_rcl.bottom=y;
}
if (m_uSizingFlags & SIZINGLEFT)
{
if (x >= rcO.right-cxy)
x=rcO.right-cxy;
if (x <= rcB.left) //Limit to left of page.
x=rcB.left;
m_rcl.left=x;
}
if (m_uSizingFlags & SIZINGRIGHT)
{
if (x <= rcO.left+cxy)
x=rcO.left+cxy;
if (x >= rcB.right) //Limit to right of page.
x=rcB.right;
m_rcl.right=x;
}
//Draw the new
RECTFROMRECTL(rc, m_rcl)
DrawFocusRect(m_hDC, &rc);
return;
}
/*
* CPage::OnTimer
*
* Purpose:
* Processes WM_TIMER messages to a page used to perform mouse
* debouncing.
*
* Parameters:
* uID UINT timer ID.
*
* Return Value:
* None
*/
void CPage::OnTimer(UINT uID)
{
//CHAPTER13MOD
if (m_fSizePending || m_fDragPending)
{
BOOL fSize=m_fSizePending;
BOOL fDrag=m_fDragPending;
/*
* Having this function called means the delay requirement
* is satisfied. Start tracking for sizing or dragging.
*/
m_fSizePending=FALSE;
m_fDragPending=FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -