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

📄 mainfrm.cpp

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

#include "stdafx.h"
#include "gettext.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_ERASEBKGND()
    ON_WM_KEYDOWN()
    ON_WM_KILLFOCUS()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MBUTTONDOWN()
    ON_WM_MOUSEACTIVATE()
    ON_WM_MOUSEMOVE()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_NCRBUTTONDOWN()
    ON_WM_PAINT()
    ON_WM_RBUTTONDOWN()
    ON_WM_SETCURSOR()
    ON_WM_SETFOCUS()
    ON_WM_SIZE()
    ON_WM_TIMER()
    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; 

    // [GETTEXT] Set to a known value.
    d_cLines       = 0;

    // [GETTEXT] Set initial caret position.
    d_ptCaret = CPoint(0,0);

    // [GETTEXT] NULL pointer for later initialization.
    d_piCharWidth = 0;

    // [GETTEXT] Width of a tab stop.
    d_cxTabStop = 0;

    // [GETTEXT] Initialize WM_SETFOCUS action.
    d_nFocusMode = FOCUS_EMPTY;

    // [GETTEXT] Set mouse activation to 'OFF'.
    d_bMouseActive = FALSE;

    // [GETTEXT] Initialize selected line counters.
    d_nSelectFirst = -1;
    d_nSelectLast  = -1; 

    // [GETTEXT] Timer flag.
    d_bTimerStarted = FALSE;
    d_nTimerID = 0;
}

DMainFrame::~DMainFrame()
{
    if (d_pFont) delete d_pFont;
    if (d_pnTabs) delete [] d_pnTabs;
    if (d_piCharWidth) delete [] d_piCharWidth;
    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 * 3;

    // [GETTEXT] Calculate width of tab stop.
    d_cxTabStop = g_nTabStop * tm.tmAveCharWidth;

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

    // [GETTEXT] For new font, reset caret to upper left window corner.
    d_ptCaret = CPoint(d_cxLeftMargin,0);

    // [GETTEXT] If we have focus, recreate and move caret.
    if (GetFocus() == this)
    {
        HideCaret();
        DestroyCaret();
        CreateSolidCaret(0, d_cyLineHeight);
        SetCaretPos(d_ptCaret);
        ShowCaret();
    }

    // [GETTEXT] Rebuild character width table for newly selected font.
    if (d_piCharWidth) delete [] d_piCharWidth;

    // [GETTEXT] Calculate size of new width table and allocate.
    int nCharCount = tm.tmLastChar - tm.tmFirstChar + 1;
    d_piCharWidth = new INT[nCharCount];

    // [GETTEXT] Query GDI for character width data.
    dc.GetCharWidth(tm.tmFirstChar, tm.tmLastChar, d_piCharWidth);

    // [GETTEXT] Record first character to use in using character width table.
    d_bchFirstChar = tm.tmFirstChar;

    // [GETTEXT] Store average character width for tab stop handling.
    d_cxAveCharWidth = tm.tmAveCharWidth;

    return TRUE;
}

//-----------------------------------------------------------------------------
// [GETTEXT] Helper function to open a file.
void DMainFrame::OpenTextFile(CString strFile)
{
    // Display hourglass cursor.
    BeginWaitCursor();

    // Open file in read-only mode.
    CFile cfData;
    if (!cfData.Open(strFile, 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();

    // [GETTEXT] Set focus mode to "use caret".
    if (d_nFocusMode == FOCUS_EMPTY)
    {
        d_nFocusMode = FOCUS_CARET;
        OnSetFocus(this);
    }

    // [GETTEXT] Move Caret to beginning of text file.
    MoveCaret(0,0);

    // [GETTEXT] Set selection state 'off'.
    d_nSelectFirst = -1;
    d_nSelectLast  = -1;

    // [GETTEXT] Modify frame window title.
    UpdateFrameTitleForDocument(strFile);

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

    // Restore normal cursor.
    EndWaitCursor();
}

//-----------------------------------------------------------------------------
// 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;
    }
    else
    {
        // 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() 
{
    // [GETTEXT] Hide all focus related settings.
    OnKillFocus(this);

    // 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 strFile = d_pOpenFile->GetPathName();

    // [GETTEXT] Open and parse text file.
    OpenTextFile(strFile);

    // [GETTEXT] Set focus mode to "use caret".
    d_nFocusMode = FOCUS_CARET;
    OnSetFocus(this);
}

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

⌨️ 快捷键说明

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