📄 engrecitedlg.cpp
字号:
// EngReciteDlg.cpp : implementation file
//
#include "stdafx.h"
#include "EngRecite.h"
#include "EngReciteDlg.h"
#include <list>
#include <map>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_TRAYICON_NOTIFY WM_USER + 100
#define DATA_FILE_NAME _T("recite.log")
typedef struct _RECITE_HISTORY_INFO_STRUCT
{
CTime ct;
CString hzMeaning;
CString allStatement;
CString ownStatement;
CString remark;
}
ReciteHisInfo;
typedef list<ReciteHisInfo*> ReciteHisinfoList;
typedef map<CString, ReciteHisinfoList*, less<CString> > ReciteRecordMap;
static BOOL g_bAddNew = FALSE;
static ReciteRecordMap mapReciteRec;
ReciteHisinfoList* GetHisInfoListFromMap(const CString& key)
{
ReciteRecordMap::iterator i = mapReciteRec.find(key);
if (i == mapReciteRec.end())
return NULL;
return (*i).second;
}
int LoadFromFile()
{
CFile file;
int nRecSize = 0;
if (file.Open(DATA_FILE_NAME, CFile::modeRead | CFile::typeBinary))
{
file.Read(&nRecSize, sizeof(nRecSize));
if (nRecSize > 0)
{
for (int i = 0; i < nRecSize; ++i)
{
// Read key size and content
CString szKey;
int nKeySize = 0;
char szKeyBuff[MAX_PATH];
memset(szKeyBuff, 0, MAX_PATH);
file.Read(&nKeySize, sizeof(nKeySize));
file.Read(szKeyBuff, nKeySize);
szKey.Format(_T("%s"), szKeyBuff);
ReciteHisinfoList* pList = new ReciteHisinfoList();
// Write history info size
int nHisSize = 0;
file.Read(&nHisSize, sizeof(int));
for (int i2 = 0; i2 < nHisSize; ++i2)
{
// Read History info object
ReciteHisInfo* pInfo = new ReciteHisInfo();
// time
file.Read(&pInfo->ct, sizeof(pInfo->ct));
int nContentSize = 0;
char szContentBuff[4096];
// hzMeaning size and content
memset(szContentBuff, 0, 4096);
file.Read(&nContentSize, sizeof(int));
file.Read(szContentBuff, nContentSize);
pInfo->hzMeaning.Format(_T("%s"), szContentBuff);
// allStatement size and content
memset(szContentBuff, 0, 4096);
file.Read(&nContentSize, sizeof(int));
file.Read(szContentBuff, nContentSize);
pInfo->allStatement.Format(_T("%s"), szContentBuff);
// ownStatement size and content
memset(szContentBuff, 0, 4096);
file.Read(&nContentSize, sizeof(int));
file.Read(szContentBuff, nContentSize);
pInfo->ownStatement.Format(_T("%s"), szContentBuff);
// remark size and content
memset(szContentBuff, 0, 4096);
file.Read(&nContentSize, sizeof(int));
file.Read(szContentBuff, nContentSize);
pInfo->remark.Format(_T("%s"), szContentBuff);
pList->insert(pList->end(), pInfo);
}
mapReciteRec.insert(ReciteRecordMap::value_type(szKey, pList));
}
}
file.Close();
}
return nRecSize;
}
BOOL SaveToFile()
{
CFile file;
if (!file.Open(DATA_FILE_NAME, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
{
CString szError;
szError.Format(_T("无法打开文件: %s"), DATA_FILE_NAME);
AfxMessageBox(szError, MB_OK | MB_ICONERROR);
return FALSE;
}
// Write record size
int nRecSize = mapReciteRec.size();
file.Write(&nRecSize, sizeof(int));
ReciteRecordMap::iterator i = NULL;
for (i = mapReciteRec.begin(); i != mapReciteRec.end(); ++i)
{
ReciteHisinfoList* pList = (*i).second;
ASSERT(pList != NULL);
if (pList != NULL && pList->size() > 0)
{
// Write key size and content
CString key = (*i).first;
int nKeySize = key.GetLength();
file.Write(&nKeySize, sizeof(int));
file.Write(key.GetBuffer(0), key.GetLength());
// Write history info size
int nHisSize = pList->size();
file.Write(&nHisSize, sizeof(int));
ReciteHisinfoList::iterator i2 = NULL;
for (i2 = pList->begin(); i2 != pList->end(); ++i2)
{
ReciteHisInfo* pInfo = *i2;
ASSERT(pInfo != NULL);
if (pInfo != NULL)
{
// Write History info object
// time
file.Write(&pInfo->ct, sizeof(pInfo->ct));
int nContentSize;
// hzMeaning size and content
nContentSize = pInfo->hzMeaning.GetLength();
file.Write(&nContentSize, sizeof(int));
file.Write(pInfo->hzMeaning.GetBuffer(0), pInfo->hzMeaning.GetLength());
// allStatement size and content
nContentSize = pInfo->allStatement.GetLength();
file.Write(&nContentSize, sizeof(int));
file.Write(pInfo->allStatement.GetBuffer(0), pInfo->allStatement.GetLength());
// ownStatement size and content
nContentSize = pInfo->ownStatement.GetLength();
file.Write(&nContentSize, sizeof(int));
file.Write(pInfo->ownStatement.GetBuffer(0), pInfo->ownStatement.GetLength());
// remark size and content
nContentSize = pInfo->remark.GetLength();
file.Write(&nContentSize, sizeof(int));
file.Write(pInfo->remark.GetBuffer(0), pInfo->remark.GetLength());
}
}
}
}
file.Flush();
file.Close();
return TRUE;
}
void ClearUpReciteRecMap()
{
ReciteRecordMap::iterator i = NULL;
for (i = mapReciteRec.begin(); i != mapReciteRec.end(); ++i)
{
ReciteHisinfoList* pList = (*i).second;
if (pList != NULL)
{
ReciteHisinfoList::iterator ii = NULL;
for (ii = pList->begin(); ii != pList->end(); ++ii)
{
ReciteHisInfo* pInfo = *ii;
if (pInfo != NULL)
{
delete pInfo;
}
}
pList->clear();
delete pList;
}
}
mapReciteRec.clear();
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEngReciteDlg dialog
CEngReciteDlg::CEngReciteDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEngReciteDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CEngReciteDlg)
m_szWord = _T("");
m_szChinese = _T("");
m_szOwnStatement = _T("");
m_szRemark = _T("");
m_szAllStatement = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CEngReciteDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEngReciteDlg)
DDX_Control(pDX, IDC_RECITE, m_btnRecite);
DDX_Control(pDX, IDC_ALL_STATEMENT, m_txtAllStatement);
DDX_Control(pDX, IDC_DELETE_REC, m_btnDelRec);
DDX_Control(pDX, IDC_DELETE_HIS, m_btnDelHis);
DDX_Control(pDX, IDC_LOAD, m_btnLoad);
DDX_Control(pDX, IDC_SAVE, m_btnSave);
DDX_Control(pDX, IDC_REMARK, m_txtRemark);
DDX_Control(pDX, IDC_OWN_STATEMNET, m_txtOwnStatement);
DDX_Control(pDX, IDC_HISTORY_LIST, m_selHistory);
DDX_Control(pDX, IDC_CHINESE, m_txtChinese);
DDX_Control(pDX, IDC_WORD_LIST, m_selWord);
DDX_CBString(pDX, IDC_WORD_LIST, m_szWord);
DDX_Text(pDX, IDC_CHINESE, m_szChinese);
DDX_Text(pDX, IDC_OWN_STATEMNET, m_szOwnStatement);
DDX_Text(pDX, IDC_REMARK, m_szRemark);
DDX_Text(pDX, IDC_ALL_STATEMENT, m_szAllStatement);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEngReciteDlg, CDialog)
//{{AFX_MSG_MAP(CEngReciteDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_EXIT, OnExit)
ON_WM_DESTROY()
ON_CBN_EDITCHANGE(IDC_WORD_LIST, OnEditchangeWordList)
ON_CBN_KILLFOCUS(IDC_WORD_LIST, OnKillfocusWordList)
ON_CBN_SELENDCANCEL(IDC_WORD_LIST, OnSelendcancelWordList)
ON_CBN_SETFOCUS(IDC_WORD_LIST, OnSetfocusWordList)
ON_EN_KILLFOCUS(IDC_ALL_STATEMENT, OnKillfocusAllStatement)
ON_EN_KILLFOCUS(IDC_CHINESE, OnKillfocusChinese)
ON_EN_KILLFOCUS(IDC_OWN_STATEMNET, OnKillfocusOwnStatemnet)
ON_EN_KILLFOCUS(IDC_REMARK, OnKillfocusRemark)
ON_CBN_SELCHANGE(IDC_HISTORY_LIST, OnSelchangeHistoryList)
ON_CBN_SELENDOK(IDC_WORD_LIST, OnSelendokWordList)
ON_BN_CLICKED(IDC_SAVE, OnSave)
ON_BN_CLICKED(IDC_DELETE_REC, OnDeleteRec)
ON_BN_CLICKED(IDC_DELETE_HIS, OnDeleteHis)
ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDBLCLK()
ON_NOTIFY(NM_KILLFOCUS, IDC_ALL_STATEMENT, OnKillfocusAllStatement)
ON_BN_CLICKED(IDC_RECITE, OnRecite)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_HOTKEY, OnHotKey)
ON_MESSAGE(WM_TRAYICON_NOTIFY, OnTrayIconNotify)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEngReciteDlg message handlers
BOOL CEngReciteDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_HotKeyId1 = ::GlobalAddAtom("#4433");
m_HotKeyId2 = ::GlobalAddAtom("#4443");
m_bRegHotKey = TRUE;
m_bRegHotKey &= ::RegisterHotKey(::AfxGetMainWnd()->m_hWnd, m_HotKeyId1, MOD_ALT | MOD_SHIFT, 'Z');
m_bRegHotKey &= ::RegisterHotKey(::AfxGetMainWnd()->m_hWnd, m_HotKeyId2, MOD_ALT | MOD_SHIFT, 'A');
if (!m_bRegHotKey)
{
if (AfxMessageBox(_T("无法注册热键! 是否退出?"), MB_OKCANCEL | MB_ICONWARNING) == IDOK)
return FALSE;
}
m_notifyIconData.cbSize = sizeof(NOTIFYICONDATA);
m_notifyIconData.hIcon = m_hIcon;
m_notifyIconData.hWnd = ::AfxGetMainWnd()->m_hWnd;
m_notifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
m_notifyIconData.uID = IDR_MAINFRAME;
m_notifyIconData.uCallbackMessage = WM_TRAYICON_NOTIFY;
sprintf(m_notifyIconData.szTip, "Simple English Recite.");
if (LoadFromFile() > 0)
{
ReciteRecordMap::iterator i;
for (i = mapReciteRec.begin(); i != mapReciteRec.end(); ++i)
{
int nIndex = m_selWord.AddString((*i).first);
if (nIndex != LB_ERR)
{
m_selWord.SetItemData(nIndex, (DWORD)((*i).second));
}
}
m_selWord.SetCurSel(0);
RefreshRecInfo();
}
m_btnSave.SetIcon(IDI_SAVE);
m_btnSave.SetFlat(FALSE);
m_btnLoad.SetIcon(IDI_LOAD);
m_btnLoad.SetFlat(FALSE);
m_btnDelRec.SetIcon(IDI_DELETE);
m_btnDelRec.SetFlat(FALSE);
m_btnDelHis.SetIcon(IDI_DELETE);
m_btnDelHis.SetFlat(FALSE);
#ifndef _DEBUG
SetWindowPos(&wndTopMost, -1, -1, -1, -1, SWP_NOMOVE | SWP_NOSIZE);
#endif
return TRUE; // return TRUE unless you set the focus to a control
}
void CEngReciteDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CEngReciteDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CEngReciteDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
LRESULT CEngReciteDlg::OnHotKey(WPARAM wParam, LPARAM lParam)
{
if (((UINT)LOWORD(lParam) == (MOD_ALT | MOD_SHIFT)))
{
if (((UINT)HIWORD(lParam) == 'Z'))
{
if(IsIconic())
{
ShowWindow(SW_SHOWNORMAL);
}
else
{
ShowWindow(SW_SHOW);
}
Shell_NotifyIcon(NIM_DELETE, &m_notifyIconData);
m_selWord.SetFocus();
SetFocus();
SetActiveWindow();
}
if (((UINT)HIWORD(lParam) == 'A'))
{
Shell_NotifyIcon(NIM_ADD, &m_notifyIconData);
ShowWindow(SW_HIDE);
}
}
return 0;
}
LRESULT CEngReciteDlg::OnTrayIconNotify(WPARAM wParam, LPARAM lParam)
{
if ((UINT)wParam == IDR_MAINFRAME && (UINT)lParam == WM_LBUTTONDBLCLK)
{
Shell_NotifyIcon(NIM_DELETE, &m_notifyIconData);
ShowWindow(SW_SHOW);
}
return 0;
}
void CEngReciteDlg::OnClose()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -