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

📄 mainfrm.cpp

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

#include "stdafx.h"
#include "filelist.h"

#include "mainfrm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// DMainFrame

IMPLEMENT_DYNCREATE(DMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(DMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(DMainFrame)
	ON_COMMAND(ID_FILE_OPEN, CmdFileOpen)
	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_PAINT()
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_WININICHANGE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// DMainFrame construction/destruction

DMainFrame::DMainFrame()
{
    // Init all data members to a known value.
    d_pOpenFile    = 0;
    d_lpTextBuffer = 0;
    d_dwFileLength = 0;
    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; 
}

DMainFrame::~DMainFrame()
{
    if (d_pFont) delete d_pFont;
    if (d_pnTabs) delete [] d_pnTabs;
    if (d_pOpenFile) delete d_pOpenFile;
    if (d_pSetFont) delete d_pSetFont;
}

///////////////////////////////////////////////////////////////////////////////
// DMainFrame helper functions.

//-----------------------------------------------------------------------------
// BuildStringArray -- Parses text file to create a CString array.
void DMainFrame::BuildStringArray()
{
    // Scan buffer to calculate line count.
    LPTSTR lpNext = d_lpTextBuffer;
    LPTSTR lpEnd  = d_lpTextBuffer + d_dwFileLength - 1;
    *lpEnd = '\n';
    for (d_cLines = 0; lpNext < lpEnd; d_cLines++, lpNext++)
    {
        // Search for next <CR> character.
        lpNext = strchr(lpNext, '\n');

        // Discontinue if NULL encountered.
        if (lpNext == NULL) break;
    }

    // Set array size.
    d_saTextInfo.SetSize(d_cLines);

    // Scan buffer to build array of pointers & sizes.
    STRING string;
    lpNext = d_lpTextBuffer;
    for (int iLine = 0; iLine < d_cLines; iLine++)
    {
        // Char count for current line.
        string.ccLen = 0;
        string.pText = lpNext;

        // Loop to end-of-line.
        while ((*lpNext != '\n') && (*lpNext != '\r'))
        {
            lpNext++;          // Check next char.
            string.ccLen++;    // Increment length counter.
        }

        // Enter value in array.
        d_saTextInfo[iLine] = string;

       // Skip over <CR> <LF>
       lpNext += (2 * sizeof(char));
    }
}

//-----------------------------------------------------------------------------
// CreateNewFont -- Creates new CFont for use in drawing text.
BOOL DMainFrame::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);
    }

    return TRUE;
}

//-----------------------------------------------------------------------------
// ResetScrollValues -- Adjust scrolling for window size changes.
void DMainFrame::ResetScrollValues()
{    
    // Set count of lines in window height.
    d_clHeight = d_cyClient / d_cyLineHeight;

    // Hide scroll bars when not needed.
    if (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, d_cLines - d_clHeight, TRUE);

    // Adjust scroll thumb position.
    SetScrollPos(SB_VERT, d_iTopLine, TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// DMainFrame diagnostics

#ifdef _DEBUG
void DMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void DMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// DMainFrame message handlers

//-----------------------------------------------------------------------------
// Handler for File|Open command message.
void DMainFrame::CmdFileOpen() 
{
    // Display File.Open... dialog box.
    int iRet = d_pOpenFile->DoModal();

    // Ignore when user clicks [Cancel] button.    
    if (iRet != IDOK)
        return;

    // Fetch fully-qualified file name.
    CString csFile = d_pOpenFile->GetPathName();

    // Open file in read-only mode.
    CFile cfData;
    if (!cfData.Open(csFile, CFile::modeRead))
    {
        AfxMessageBox(_T("Error Opening File"));
        return;
    }

    // Free previous buffer contents
    if (d_lpTextBuffer)
    {
        free(d_lpTextBuffer);
        d_lpTextBuffer=0;
    }

    // Calculate file size & allocate buffer.
    // Pad to avoid bad address reference.
    d_dwFileLength = cfData.GetLength() + sizeof(char);
    d_lpTextBuffer = (LPTSTR)malloc (d_dwFileLength);
    if (!d_lpTextBuffer)
    {
        AfxMessageBox(_T("Cannot Allocate Memory For File"));
        return;
    }

    // Read Buffer.
    cfData.Read((LPVOID)d_lpTextBuffer, d_dwFileLength);

    // Empty buffer array.
    d_saTextInfo.RemoveAll();

    // Scan buffer for text line info.
    BuildStringArray();

    // "Index to top line displayed" = top of file.
    d_iTopLine = 0;

    // Recalculate scroll bar info.
    ResetScrollValues();

    // Request a WM_PAINT message to redraw window.
    Invalidate();
}

//-----------------------------------------------------------------------------
// Handler for Format|Font command message.
void DMainFrame::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 DMainFrame::CmdFormatTabs() 
{
    // Toggle "respect tab" flag.
    d_bTabs = !d_bTabs;

    // Request a WM_PAINT message to redraw window.
    Invalidate();
}

//-----------------------------------------------------------------------------
// Handler for CN_UPDATE_COMMAND_UI message.
void DMainFrame::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 DMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    // Send WM_CREATE to base class first...
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // Create File.Open... dialog object.
    d_pOpenFile = new CFileDialog (TRUE);
    if (!d_pOpenFile)
        return -1;

    // Initialize file filter.
    d_pOpenFile->m_ofn.lpstrFilter = _T("All Source Files\0*.cpp;*.h;*.rc\0"
                                        "C++ Sources (*.cpp)\0*.cpp\0"
                                        "Include Files (*.h)\0*.h\0"
                                        "All Files (*.*)\0*.*\0");

    // 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;

    // Initialize application settings.
    OnWinIniChange("");

    // Indicate window creation is OK.
	return 0;
}

//-----------------------------------------------------------------------------
// 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);

    // Select text color.
    dc.SetTextColor(d_crForeground );

    // Select text background color.
    dc.SetBkColor(d_crBackground);

    // Figure out which lines to draw.
    int iLine = d_iTopLine;
    int cLastLine = d_iTopLine + d_clHeight + 1;
    cLastLine = min (cLastLine, d_cLines);

    // 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;

        // 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);
        }

        // Increment various counts.
        cyLine += d_cyLineHeight;
        iLine++;
    }
}

//-----------------------------------------------------------------------------
// 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();
}

//-----------------------------------------------------------------------------
// WM_VSCROLL message handler.
void DMainFrame::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    // 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 background & foreground colors in case these have changed.
    d_crForeground = GetSysColor(COLOR_WINDOWTEXT);
    d_crBackground = GetSysColor(COLOR_WINDOW);

    // Force redraw of window.
    Invalidate();	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -