⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view.cpp

📁 《Visual C++ Bible》或者说是《Visual C++ 宝典》的对应的源码文件
💻 CPP
字号:
// view.cpp : implementation of the DView class
//

#include "stdafx.h"
#include "HASAVIEW.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 + -