📄 mainfrm.cpp
字号:
OnVScroll(SB_LINEUP, 0, 0);
point.y = rClient.top;
}
else
{
OnVScroll(SB_LINEDOWN, 0, 0);
point.y = rClient.bottom - 1;
}
// Also, start timer to speed up scrolling.
if (!d_bTimerStarted)
{
d_bTimerStarted = TRUE;
d_nTimerID = SetTimer(1, 50, 0);
}
}
// Get current line.
int iNextLine = QueryClickLine(point);
// Ignore if we've already selected.
if (iNextLine == d_nSelectLast)
return;
// Figure direction from First => Last line.
int nFirstLast = (d_nSelectFirst > d_nSelectLast) ? -1 : +1;
if (d_nSelectFirst == d_nSelectLast) nFirstLast = 0;
// Figure direction from First => Next line.
int nFirstNext = (d_nSelectFirst > iNextLine) ? -1 : +1;
if (d_nSelectFirst == iNextLine) nFirstNext = 0;
// Figure direction from Last => Next line.
int nLastNext = (d_nSelectLast > iNextLine) ? -1 : +1;
// First case: extending the current selection.
if ((nFirstLast == 0)
|| ((nFirstLast == nFirstNext) && (nFirstNext == nLastNext)))
{
InvertLines(d_nSelectLast+nLastNext, iNextLine);
}
// Second case: backtracking (erasing) previous lines.
else if ((nFirstNext == 0)
|| (nFirstLast == nFirstNext) && (nFirstLast != nLastNext))
{
InvertLines(d_nSelectLast, iNextLine+nFirstLast);
}
// Third case: crossing over anchor (first) line: backtrack AND extend.
else if ((nFirstNext == nLastNext) && (nFirstNext != nFirstLast))
{
// Erase to backtrack.
InvertLines(d_nSelectLast, d_nSelectFirst+nFirstLast);
// Extend in new direction.
InvertLines(d_nSelectFirst+nFirstNext, iNextLine);
}
// Update last selection to current line.
d_nSelectLast = iNextLine;
}
//-----------------------------------------------------------------------------
// WM_NCLBUTTONDOWN message handler.
void DMainFrame::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
// If we're activating with button click,
// activate window and ignore mouse message.
OnMButtonDown(nHitTest, point);
CFrameWnd::OnNcLButtonDown(nHitTest, point);
}
//-----------------------------------------------------------------------------
// [GETTEXT] Handler for WM_NCRBUTTONDOWN message.
void DMainFrame::OnNcRButtonDown(UINT nHitTest, CPoint point)
{
// If we're activating with button click,
// activate window and ignore mouse message.
OnMButtonDown(nHitTest, point);
}
//-----------------------------------------------------------------------------
// WM_PAINT message handler.
void DMainFrame::OnPaint()
{
// Fetch a device context (dc) for "this" window.
CPaintDC dc(this);
// Select current font into DC.
dc.SelectObject(d_pFont);
// [GETTEXT] -- Only draw foreground text pixels.
dc.SetBkMode(TRANSPARENT);
// Select text color.
dc.SetTextColor(d_crForeground );
// Figure out which lines to draw.
int iLine = d_iTopLine;
int cLastLine = d_iTopLine + d_clHeight + 1;
cLastLine = min (cLastLine, d_cLines);
// [GETTEXT] Modify text colors based on selection state.
int iSelectMin = -1;
int iSelectMax = -1;
if (d_nFocusMode == FOCUS_SELECT && GetFocus() == this)
{
// Get order of selected lines straight .
int nSelectLow = min (d_nSelectFirst, d_nSelectLast);
int nSelectHigh = max (d_nSelectFirst, d_nSelectLast);
if (!(nSelectLow > cLastLine || nSelectHigh < d_iTopLine))
{
// Figure out which lines to draw selected.
iSelectMin = max (nSelectLow, d_iTopLine);
iSelectMax = min (nSelectHigh, cLastLine);
}
}
// Loop through client area coordinates to draw.
int cyLine = 0;
while (iLine < cLastLine)
{
// Draw a line of text.
LPTSTR lp = d_saTextInfo[iLine].pText;
int cc = d_saTextInfo[iLine].ccLen;
// [GETTEXT] Set to "selected" colors.
if (iLine == iSelectMin)
{
// Select text color.
dc.SetTextColor(d_crSelectFore );
}
// Drawing function depends on 'respect tabs' setting.
if (d_bTabs && d_pnTabs != 0)
{
dc.TabbedTextOut(d_cxLeftMargin, cyLine, lp, cc,
g_nTabCount, d_pnTabs, 0);
}
else
{
dc.TextOut(d_cxLeftMargin, cyLine, lp, cc);
}
// [GETTEXT] Set to "normal" colors.
if (iLine == iSelectMax)
{
// Select text color.
dc.SetTextColor(d_crForeground );
}
// Increment various counts.
cyLine += d_cyLineHeight;
iLine++;
}
}
//-----------------------------------------------------------------------------
// [GETTEXT] Handler for WM_RBUTTONDOWN message.
void DMainFrame::OnRButtonDown(UINT nFlags, CPoint point)
{
// If we're activating with button click,
// activate window and ignore mouse message.
OnMButtonDown(nFlags, point);
}
//-----------------------------------------------------------------------------
// [GETTEXT] WM_SETCURSOR message handler.
BOOL DMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest != HTCLIENT)
{
return CFrameWnd::OnSetCursor(pWnd, nHitTest, message);
}
// Query cursor location and convert to client area coordinates.
CPoint ptCursor;
::GetCursorPos(&ptCursor);
ScreenToClient(&ptCursor);
// Calculate rectangle around selected lines of text.
CRect rSelected;
GetSelectedRect(&rSelected);
// Cursor => Right Arrow if cursor in right margin.
// Cursor => Left Arrow if cursor over selected text.
// Cursor => I-Beam for text selection.
if (ptCursor.x <= d_cxLeftMargin) ::SetCursor(d_hcrRArrow);
else if (rSelected.PtInRect(ptCursor)) ::SetCursor(d_hcrLArrow);
else ::SetCursor(d_hcrIBeam);
return TRUE;
}
//-----------------------------------------------------------------------------
// [GETTEXT] WM_SETFOCUS message handler.
void DMainFrame::OnSetFocus(CWnd* pOldWnd)
{
CFrameWnd::OnSetFocus(pOldWnd);
switch(d_nFocusMode)
{
case FOCUS_EMPTY:
break;
case FOCUS_CARET:
// Create, position, and make caret appear.
CreateSolidCaret(0, d_cyLineHeight);
SetCaretPos(d_ptCaret);
ShowCaret();
case FOCUS_SELECT:
InvertLines(d_nSelectFirst, d_nSelectLast);
break;
}
}
//-----------------------------------------------------------------------------
// WM_SIZE message handler.
void DMainFrame::OnSize(UINT nType, int cx, int cy)
{
// Notify base class of new window size.
CFrameWnd ::OnSize(nType, cx, cy);
// Save client area height.
d_cyClient = cy;
// Recalculate scroll bar info.
ResetScrollValues();
}
//-----------------------------------------------------------------------------
// [GETTEXT] Handler for WM_TIMER message.
void DMainFrame::OnTimer(UINT nIDEvent)
{
// Query cursor location and convert to client area coordinates.
CPoint ptCursor;
::GetCursorPos(&ptCursor);
ScreenToClient(&ptCursor);
// Query client area.
CRect rClient;
GetClientRect (&rClient);
// Compare cursor location to client area.
if (rClient.PtInRect(ptCursor))
{
// Kill timer and go home.
KillTimer(d_nTimerID);
d_bTimerStarted = FALSE;
}
else
{
// Send fake mouse move messages to force scrolling.
OnMouseMove(0, ptCursor);
}
CFrameWnd::OnTimer(nIDEvent);
}
//-----------------------------------------------------------------------------
// WM_VSCROLL message handler.
void DMainFrame::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// [GETTEXT] Ignore if scroll bars not present. No scrolling possible.
int nMinPos, nMaxPos;
GetScrollRange(0, &nMinPos, &nMaxPos);
if (nMinPos == nMaxPos)
return;
// Temporary "new line" value.
int iTop = d_iTopLine;
// Based on particular scroll button clicked, modify top line index.
switch(nSBCode)
{
case SB_BOTTOM:
iTop = d_cLines - d_clHeight;
break;
case SB_ENDSCROLL:
break;
case SB_LINEDOWN:
iTop++;
break;
case SB_LINEUP:
iTop--;
break;
case SB_PAGEDOWN:
iTop += d_clHeight;
break;
case SB_PAGEUP:
iTop -= d_clHeight;
break;
case SB_THUMBPOSITION:
iTop = nPos;
break;
case SB_THUMBTRACK:
iTop = nPos;
break;
case SB_TOP:
iTop = 0;
break;
}
// Check range of new index;
iTop = max (iTop, 0);
iTop = min (iTop, d_cLines - d_clHeight);
// If no change, ignore.
if (iTop == d_iTopLine) return;
// Pixels to scroll = (lines to scroll) * height-per-line.
int cyScroll = (d_iTopLine - iTop) * d_cyLineHeight;
// Define new top-line value.
d_iTopLine = iTop;
// Scroll pixels.
ScrollWindow(0, cyScroll);
// Adjust scroll thumb position.
SetScrollPos(SB_VERT, d_iTopLine, TRUE);
}
//-----------------------------------------------------------------------------
// WM_WININICHANGE message handler.
void DMainFrame::OnWinIniChange(LPCTSTR lpszSection)
{
CFrameWnd::OnWinIniChange(lpszSection);
// Get new "normal" background & foreground colors.
d_crForeground = GetSysColor(COLOR_WINDOWTEXT);
d_crBackground = GetSysColor(COLOR_WINDOW);
// [GETTEXT] Get new "selected" colors (in 7 easy steps).
// 1. Create an offscreen DC (compatible with display screen).
CDC dcBitmap;
dcBitmap.CreateCompatibleDC(NULL);
// 2. Query current device details.
CClientDC dcScreen(this);
int nPlanes = dcScreen.GetDeviceCaps(PLANES);
int nBitCount = dcScreen.GetDeviceCaps(BITSPIXEL);
// 3. Create a tiny bitmap and connect to the DC from step #1.
CBitmap bm;
bm.CreateBitmap(2, 2, nPlanes, nBitCount, 0);
CBitmap * pbmOld = dcBitmap.SelectObject(&bm);
// 4. Set up rectangle for bitmap surface.
CRect rBitmap = CRect(0, 0, 3, 3);
// 5. Find foreground color inverse (we're looking for d_crSelectFore).
dcBitmap.SetBkColor(d_crForeground);
dcBitmap.ExtTextOut(0, 0, ETO_OPAQUE, &rBitmap, 0, 0, 0);
dcBitmap.InvertRect(&rBitmap);
d_crSelectFore = dcBitmap.GetPixel(1,1);
// 6. Find background color inverse (we're looking for d_crSelectBack).
dcBitmap.SetBkColor(d_crBackground);
dcBitmap.ExtTextOut(0, 0, ETO_OPAQUE, &rBitmap, 0, 0, 0);
dcBitmap.InvertRect(&rBitmap);
d_crSelectBack = dcBitmap.GetPixel(1,1);
// 7. Disconnect bitmap from DC to help GDI clean up properly.
dcBitmap.SelectObject(pbmOld );
// Force redraw of window.
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -