📄 mainfrm.cpp
字号:
// 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 + -