📄 scwinthumbs.cpp
字号:
// Scroll window.
#if 0
// scroll position is integrated to scpaint
if (SB_VERT == nScrollBar)
nVertScroll = nPosition - ScrollInfo.nPos;
else
nHorzScroll = nPosition - ScrollInfo.nPos;
ScrollWindowEx(nHorzScroll, nVertScroll, NULL, NULL,
NULL, NULL, SW_INVALIDATE);
#endif
Invalidate();
UpdateWindow();
return TRUE;
}
void CSCWinThumbs::SCSizeScrollBars(int uiWindowWidth, int uiWindowHeight)
{
// Only size for validte windows and dib info.
// Don't SCSizeScrollBars if in process of adjusting them.
if (IsWindow(m_hWnd) &&
!m_bAdjusting)
{
int nScrollHeight = GetSystemMetrics (SM_CXVSCROLL);
int nScrollWidth = GetSystemMetrics (SM_CYHSCROLL);
SCROLLINFO VertScrollInfo;
SCROLLINFO HorzScrollInfo;
// Make sure that we don't get into an infinite loop when updating scroll bars.
m_bAdjusting = TRUE;
// Get current vertical scroll info.
VertScrollInfo.cbSize = sizeof(SCROLLINFO);
VertScrollInfo.fMask = SIF_ALL;
GetScrollInfo(SB_VERT, &VertScrollInfo);
// Get current horizontal scroll info.
HorzScrollInfo.cbSize = sizeof(SCROLLINFO);
HorzScrollInfo.fMask = SIF_ALL;
GetScrollInfo(SB_HORZ, &HorzScrollInfo);
// Update vertical scroll info.
VertScrollInfo.fMask = SIF_PAGE;
VertScrollInfo.nPage = uiWindowHeight;
SetScrollInfo(SB_VERT, &VertScrollInfo, TRUE);
// Update horizontal scroll info.
HorzScrollInfo.fMask = SIF_PAGE;
HorzScrollInfo.nPage = uiWindowWidth;
SetScrollInfo(SB_HORZ, &HorzScrollInfo, TRUE);
m_bAdjusting = FALSE;
}
}
inline int CSCWinThumbs::SCNbColsInSpace(int iWndCx, int iImgCx)
{
ASSERT(iImgCx>0);
int iNbCols = (iWndCx + COL_SPACE - 2*MIN_MARGIN) / iImgCx;
if (iNbCols<=0)
return 1;
if (iNbCols>m_uiNbThumbs)
return m_uiNbThumbs;
return iNbCols;
}
inline int CSCWinThumbs::SCNbRowsInCols(int iNbCols)
{
ASSERT(iNbCols>0);
int iNbRows = m_uiNbThumbs / iNbCols;
if (m_uiNbThumbs % iNbCols)
iNbRows++;
return iNbRows;
}
void CSCWinThumbs::SCComputeRowsCols()
{
if (!m_uiNbThumbs)
{
SCInitializeScrollBars(m_iWorldCx, m_iWorldCy);
Invalidate();
return;
}
CSize OldSize = m_ThumbsSize;
int iImgCx = m_ThumbsMinSize.cx + COL_SPACE;
int iImgCy = m_ThumbsMinSize.cy + ROW_SPACE;
ASSERT(iImgCx && iImgCy);
CRect rc;
GetClientRect(rc);
int iWndCx = rc.Width();
int iWndCy = rc.Height();
float fTotalSurface = float(iWndCx - 2*MIN_MARGIN)*float(iWndCy - 2*MIN_MARGIN);
float fImgSurface = float(iImgCx)*float(iImgCy)*m_uiNbThumbs;
if (fTotalSurface > 1.1f*fImgSurface)
{
fImgSurface = fTotalSurface/m_uiNbThumbs;
iImgCy = (int)sqrt(fImgSurface);
iImgCx = MulDiv(iImgCy, m_ThumbsMinSize.cx, m_ThumbsMinSize.cy);
for (;iImgCx>m_ThumbsMinSize.cx && iImgCy>m_ThumbsMinSize.cy;)
{
int iNbCols = SCNbColsInSpace(iWndCx, iImgCx);
int iNbRows = SCNbRowsInCols(iNbCols);
int iColsSpan = iNbCols*iImgCx - COL_SPACE + 2*MIN_MARGIN;
int iRowsSpan = iNbRows*iImgCy - ROW_SPACE + 2*MIN_MARGIN;
if ((iNbCols*iImgCx - COL_SPACE + 2*MIN_MARGIN)>iWndCx)
{
iImgCx -= 5;
iImgCy = MulDiv(iImgCx, m_ThumbsMinSize.cy, m_ThumbsMinSize.cx);
} else
if ((iNbRows*iImgCy - ROW_SPACE + 2*MIN_MARGIN)>iWndCy)
{
iImgCy -= 5;
iImgCx = MulDiv(iImgCy, m_ThumbsMinSize.cx, m_ThumbsMinSize.cy);
}
else
break;
}
m_ThumbsSize.cx = iImgCx - COL_SPACE;
m_ThumbsSize.cy = iImgCy - ROW_SPACE;
} else
{
m_ThumbsSize = m_ThumbsMinSize;
}
m_uiNbCols = SCNbColsInSpace(iWndCx, iImgCx);
m_uiNbRows = SCNbRowsInCols(m_uiNbCols);
// try to set an y margin (if one row)
int iRowsSpan = m_uiNbRows*iImgCy - ROW_SPACE; // space used by rows
if (iRowsSpan<iWndCy)
m_iWorldCy = iWndCy;
else
m_iWorldCy = MIN_MARGIN*2 + iRowsSpan;
ASSERT(m_iWorldCy>=iWndCy);
// compute world dimensions for scrollbars
int iColsSpan = m_uiNbCols*iImgCx - COL_SPACE; // space used by cols
if (iColsSpan<iWndCx)
m_iWorldCx = iWndCx;
else
m_iWorldCx = MIN_MARGIN*2 + iColsSpan;
ASSERT(m_iWorldCx>=iWndCx);
// center
m_iMarginX = (m_iWorldCx - iColsSpan)/2;
m_iMarginY = (m_iWorldCy - iRowsSpan)/2;
ASSERT(m_iMarginX>=0);
ASSERT(m_iMarginY>=0);
SCInitializeScrollBars(m_iWorldCx, m_iWorldCy);
if (OldSize!=m_ThumbsSize)
m_pIThumbsHolder->SCSetThumbsSize(m_ThumbsSize);
}
// Compute the thumb containing a client space point
int CSCWinThumbs::SCComputeHitTest(CPoint point)
{
if (0==m_uiNbThumbs)
return -1;
// Message handler code here and/or call default
int xScroll = GetScrollPos(SB_HORZ);
int yScroll = GetScrollPos(SB_VERT);
int iWdt = m_ThumbsSize.cx;
int iHgt = m_ThumbsSize.cy;
int iImgCx = iWdt + COL_SPACE;
int iImgCy = iHgt + ROW_SPACE;
int iPosY = yScroll + point.y;
int iPosX = xScroll + point.x;
int iPgRow = (iPosY - m_iMarginY) / iImgCy;
int iPgCol = (iPosX - m_iMarginX) / iImgCx;
int iThumbNum = iPgRow*m_uiNbCols + iPgCol;
ASSERT(iPgRow>=0 && iPgCol>=0);
// check thumb/col/row number overflows
if (iThumbNum>=m_uiNbThumbs || iPgCol>=m_uiNbCols || iPgRow>=m_uiNbRows)
iThumbNum = -1;
else
// check left and top bands
if ((0==iPgCol && point.x<=m_iMarginX)||
(0==iPgRow && point.y<=m_iMarginY))
iThumbNum = -1;
else
// check right and bottom bands, and between columns or rows
if ((iPosX >= (m_iMarginX + iPgCol*iImgCx + iWdt))||
(iPosY >= (m_iMarginY + iPgRow*iImgCy + iHgt)))
iThumbNum = -1;
return iThumbNum;
}
///
/// Tell the parent that selection has changed.
///
void CSCWinThumbs::SCNotifyParent()
{
CWnd *pParent = GetParent();
ASSERT(pParent);
if (!pParent)
return;
NMHDR nmhdr;
nmhdr.code = THN_SELCHANGE;
nmhdr.hwndFrom = m_hWnd;
nmhdr.idFrom = GetDlgCtrlID();
pParent->SendMessage(WM_NOTIFY, (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
void CSCWinThumbs::SCEnsureCurThumbVisible()
{
if (0==m_uiNbThumbs)
return;
CRect rc;
GetClientRect(&rc);
int cy = rc.Height();
int xScroll = GetScrollPos(SB_HORZ);
int yScroll = GetScrollPos(SB_VERT);
// Get thumb top in client coordinates
int xThumbLeft;
int yThumbTop;
SCGetThumbPos(m_iCurSel, xThumbLeft, yThumbTop);
int iBottom = yThumbTop + m_ThumbsSize.cy;
if (iBottom >= cy)
{// make bottom visible
int iDeltaY = iBottom - cy;
int iQuant = iDeltaY / SC_PIX_TXTLINE;
if (iQuant<=0)
iQuant = 1;
else
if (iDeltaY % SC_PIX_TXTLINE)
iQuant++;
ScrollChildWindow(SB_VERT, SB_LINEDOWN, iQuant);
} else
{// make top visible
if (yThumbTop <= 0)
{
int iDeltaY = -yThumbTop;
int iQuant = iDeltaY / SC_PIX_TXTLINE;
if (iQuant<=0)
iQuant = 1;
else
if (iDeltaY % SC_PIX_TXTLINE)
iQuant++;
ScrollChildWindow(SB_VERT, SB_LINEUP, iQuant);
} else
{
Invalidate();
}
}
}
void CSCWinThumbs::SCGetThumbPos(int iThumbIdx, int& xThumbLeft, int& yThumbTop)
{
ASSERT(iThumbIdx>=0 && iThumbIdx<m_uiNbThumbs);
CSize ThSizeEx = m_ThumbsSize; // extended size of thumb
ThSizeEx.cx += COL_SPACE;
ThSizeEx.cy += ROW_SPACE;
// remove scroll, and start with world margins
yThumbTop = m_iMarginY - GetScrollPos(SB_VERT);
xThumbLeft = m_iMarginX - GetScrollPos(SB_HORZ);
// skip rows and cols
yThumbTop += (iThumbIdx / m_uiNbCols)*ThSizeEx.cy;
xThumbLeft += (iThumbIdx % m_uiNbCols)*ThSizeEx.cx;
}
/////////////////////////////////////////////////////////////////////////////
// CSCWinThumbs message handlers
BOOL CSCWinThumbs::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_HSCROLL|WS_VSCROLL;
return CWnd::PreCreateWindow(cs);
}
BOOL CSCWinThumbs::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
//return CWnd::OnEraseBkgnd(pDC);
}
void CSCWinThumbs::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// message handler code here
ASSERT(cx && cy);
if (!cx || !cy)
return;
m_WorkMemDC.SCPrepareSurface(cx, cy, NULL);
SCSizeScrollBars(cx, cy);
SCComputeRowsCols();
}
void CSCWinThumbs::OnPaint()
{
CPaintDC dc(this); // device context for painting
SCPaint(dc);
}
void CSCWinThumbs::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
ScrollChildWindow(SB_HORZ, nSBCode);
CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CSCWinThumbs::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
ScrollChildWindow(SB_VERT, nSBCode);
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}
// Reading flow tracking
void CSCWinThumbs::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (0==m_uiNbThumbs)
return;
switch(nChar)
{
case VK_RIGHT:
case VK_DOWN:
ScrollChildWindow(SB_VERT, SB_LINEDOWN); // temp
break;
case VK_LEFT:
case VK_UP:
ScrollChildWindow(SB_VERT, SB_LINEUP); // temp
break;
// case VK_DOWN:
// case VK_UP:
// break;
case VK_HOME:
ScrollChildWindow(SB_VERT, SB_TOP);
break;
case VK_END:
ScrollChildWindow(SB_VERT, SB_BOTTOM);
break;
case VK_PRIOR: //VK_PAGE_UP:
ScrollChildWindow(SB_VERT, SB_PAGEUP);
break;
case VK_NEXT: //VK_PAGE_DOWN:
ScrollChildWindow(SB_VERT, SB_PAGEDOWN);
break;
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSCWinThumbs::OnLButtonDown(UINT nFlags, CPoint point)
{
// Message handler code here and/or call default
int iThumbNum = SCComputeHitTest(point);
// location on thumb
if (iThumbNum>=0 && iThumbNum!=m_iCurSel)
{// move to this location
m_iCurSel = iThumbNum;
Invalidate();
SCNotifyParent();
}
CWnd::OnLButtonDown(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -