📄 mainfrm.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 + -