📄 view.cpp
字号:
// view.cpp : implementation of the DView class
//
#include "stdafx.h"
#include "HASVIEWS.h"
#include "doc.h"
#include "view.h"
#include "mainfrm.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// DView
IMPLEMENT_DYNCREATE(DView, CView)
BEGIN_MESSAGE_MAP(DView, CView)
//{{AFX_MSG_MAP(DView)
ON_COMMAND(ID_FORMAT_FONT, CmdFormatFont)
ON_COMMAND(ID_FORMAT_TABS, CmdFormatTabs)
ON_UPDATE_COMMAND_UI(ID_FORMAT_TABS, UpdFormatTabs)
ON_WM_CREATE()
ON_WM_KEYDOWN()
ON_WM_SIZE()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// DView construction/destruction
DView::DView()
{
// Init all data members to a known value.
d_pFont = 0;
// Init desired font.
memset (&d_lf, 0, sizeof(LOGFONT));
// Initial font face name is Courier New.
lstrcpy (d_lf.lfFaceName, _T("Courier New"));
// Initial font size is 10 pt.
CWindowDC dc(NULL);
int cyPixels = dc.GetDeviceCaps(LOGPIXELSY);
d_lf.lfHeight = (-1) * MulDiv(10, cyPixels, 72);
// Initial tab setting is OFF.
d_bTabs = TRUE;
// Tab table initially empty (set when font selected).
d_pnTabs = 0;
}
DView::~DView()
{
if (d_pFont) delete d_pFont;
if (d_pnTabs) delete [] d_pnTabs;
if (d_pSetFont) delete d_pSetFont;
}
///////////////////////////////////////////////////////////////////////////////
// DView helper functions.
//-----------------------------------------------------------------------------
// CreateNewFont -- Creates new CFont for use in drawing text.
BOOL DView::CreateNewFont()
{
// Delete any previous font.
if (d_pFont)
delete d_pFont;
// Create a new font
d_pFont = new CFont();
if (!d_pFont) return FALSE;
d_pFont->CreateFontIndirect(&d_lf);
// Calculate font height
CClientDC dc(this);
TEXTMETRIC tm;
dc.SelectObject(d_pFont);
dc.GetTextMetrics(&tm);
d_cyLineHeight = tm.tmHeight + tm.tmExternalLeading;
// Calculate left margin.
d_cxLeftMargin = tm.tmAveCharWidth * 2;
// Rebuild tab setting table.
if (d_pnTabs) delete [] d_pnTabs;
d_pnTabs = new INT[g_nTabCount];
for (int i=0; i<g_nTabCount; i++)
{
d_pnTabs[i] = d_cxLeftMargin + (i * g_nTabStop * tm.tmAveCharWidth);
}
// Recalculate scroll bar info.
ResetScrollValues();
return TRUE;
}
//-----------------------------------------------------------------------------
// ResetScrollValues -- Adjust scrolling for window size changes.
void DView::ResetScrollValues()
{
// Set count of lines in window height.
d_clHeight = d_cyClient / d_cyLineHeight;
// [HASAVIEW] Get Doc pointer in type-safe way.
DDoc * pDoc = (DDoc *)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(DDoc)));
// Hide scroll bars when not needed.
if (pDoc->d_cLines <= d_clHeight)
{
SetScrollRange(SB_VERT, 0, 0, TRUE);
d_iTopLine = 0;
return;
}
// Adjust scroll range for new window size.
SetScrollRange (SB_VERT, 0, pDoc->d_cLines - d_clHeight, TRUE);
// Adjust scroll thumb position.
SetScrollPos(SB_VERT, d_iTopLine, TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// DView drawing
void DView::OnDraw(CDC* pDC)
{
DDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Select current font into DC.
pDC->SelectObject(d_pFont);
// Fetch pointer to frame window, which holds desired drawing colors.
DMainFrame * pFrame = GetFrame();
// Select text color.
pDC->SetTextColor(pFrame->d_crForeground );
// Select text background color.
pDC->SetBkColor(pFrame->d_crBackground);
// Figure out which lines to draw.
int iLine = d_iTopLine;
int cLastLine = d_iTopLine + d_clHeight + 1;
cLastLine = min (cLastLine, pDoc->d_cLines);
// Loop through client area coordinates to draw.
int cyLine = 0;
while (iLine < cLastLine)
{
// Draw a line of text.
LPTSTR lp = pDoc->d_saTextInfo[iLine].pText;
int cc = pDoc->d_saTextInfo[iLine].ccLen;
// Drawing function depends on 'respect tabs' setting.
if (d_bTabs && d_pnTabs != 0)
{
pDC->TabbedTextOut(d_cxLeftMargin, cyLine, lp, cc,
g_nTabCount, d_pnTabs, 0);
}
else
{
pDC->TextOut(d_cxLeftMargin, cyLine, lp, cc);
}
// Increment various counts.
cyLine += d_cyLineHeight;
iLine++;
}
}
/////////////////////////////////////////////////////////////////////////////
// DView diagnostics
#ifdef _DEBUG
void DView::AssertValid() const
{
CView::AssertValid();
}
void DView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
DDoc* DView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(DDoc)));
return (DDoc*)m_pDocument;
}
#endif //_DEBUG
DMainFrame* DView::GetFrame()
{
DMainFrame * pFrame = (DMainFrame *)AfxGetApp()->m_pMainWnd;
ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(DMainFrame)));
return pFrame;
}
/////////////////////////////////////////////////////////////////////////////
// DView message handlers
//-----------------------------------------------------------------------------
// Handler for Format|Font command message.
void DView::CmdFormatFont()
{
// Display font picker dialog box.
int iRet = d_pSetFont->DoModal();
// Ignore when user clicks [Cancel] button.
if (iRet != IDOK)
return;
// Rebuild font definition based on dialog selection.
CreateNewFont();
// Recalculate scroll bar info.
ResetScrollValues();
// Request a WM_PAINT message to redraw window.
Invalidate();
}
//-----------------------------------------------------------------------------
// Handler for Format|Tabs command message.
void DView::CmdFormatTabs()
{
// Toggle "respect tab" flag.
d_bTabs = !d_bTabs;
// Request a WM_PAINT message to redraw window.
Invalidate();
}
//-----------------------------------------------------------------------------
// Handler for ON_COMMAND_UPDATE_UI message for Format|Tabs command.
void DView::UpdFormatTabs(CCmdUI* pCmdUI)
{
// Display a checkmark if user wants to respect tabs.
int nCheck = (d_bTabs) ? 1 : 0;
pCmdUI->SetCheck(nCheck);
}
//-----------------------------------------------------------------------------
// WM_CREATE message handler.
int DView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// Create Format.Font... dialog object.
d_pSetFont = new CFontDialog(&d_lf, CF_SCREENFONTS);
if (!d_pSetFont)
return -1;
// Create initial font object.
if (!CreateNewFont())
return -1;
return 0;
}
//-----------------------------------------------------------------------------
// WM_KEYDOWN message handler.
void DView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_HOME:
// Ctrl+Home means go to start of document.
if (::GetKeyState(VK_CONTROL) < 0)
{
// Scroll to start of document
OnVScroll(SB_TOP, 0, 0);
}
break;
case VK_END:
// Ctrl+End means go to end of document.
if (::GetKeyState(VK_CONTROL) < 0)
{
// Scroll to end
OnVScroll(SB_BOTTOM, 0, 0);
}
break;
case VK_UP:
case VK_LEFT:
OnVScroll(SB_LINEUP, 0, 0);
break;
case VK_DOWN:
case VK_RIGHT:
OnVScroll(SB_LINEDOWN, 0, 0);
break;
case VK_PRIOR: // [PgUp] key.
OnVScroll(SB_PAGEUP, 0, 0);
break;
case VK_NEXT: // [PgDn] key.
OnVScroll(SB_PAGEDOWN, 0, 0);
break;
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
//-----------------------------------------------------------------------------
// WM_SIZE message handler.
void DView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// Save client area height.
d_cyClient = cy;
// Recalculate scroll bar info.
ResetScrollValues();
}
//-----------------------------------------------------------------------------
// WM_VSCROLL message handler.
void DView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// Temporary "new line" value.
int iTop = d_iTopLine;
// Temporary copy of document line count.
int cLines = GetDocument()->d_cLines;
// Based on particular scroll button clicked, modify top line index.
switch(nSBCode)
{
case SB_BOTTOM:
iTop = 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, 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);
CView::OnVScroll(nSBCode, nPos, pScrollBar);
}
//-----------------------------------------------------------------------------
// Notification from CDocument that contents have
// changed (due to File|Open or File|New).
void DView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// Reset "Index to top line displayed" = top of file.
d_iTopLine = 0;
// Recalculate scroll bar info.
ResetScrollValues();
// Force repaint.
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -