www.pudn.com > MemFile.rar > testmemmap.cpp
#include "stdafx.h"
#include "testmemmap.h"
const int MAX_EDIT_TEXT = 100;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CTestmemmapApp, CWinApp)
//{{AFX_MSG_MAP(CTestmemmapApp)
//}}AFX_MSG
END_MESSAGE_MAP()
CTestmemmapApp::CTestmemmapApp()
{
}
CTestmemmapApp theApp;
BOOL CTestmemmapApp::InitInstance()
{
//First test out the class when we want to map a file
//You might want to step through this code to test it out
CMemMapFile mmf;
BOOL bSuccess = mmf.MapFile(_T("C:\\CONFIG.SYS"), FALSE);
LPVOID pData = mmf.Open();
BOOL bIsOpen = mmf.IsOpen();
CString sName = mmf.GetMappingName();
bSuccess = mmf.Flush();
#ifdef _DEBUG
afxDump << mmf;
#endif
bSuccess = mmf.Close();
bIsOpen = mmf.IsOpen();
sName = mmf.GetMappingName();
mmf.UnMap();
//As above but with read only access, Writing into the
//returned pointer should then cause an access violation
//hence the need for exception handling code
CMemMapFile mmf2;
bSuccess = mmf2.MapFile(_T("C:\\CONFIG.SYS"), TRUE);
pData = mmf2.Open();
try
{
((BYTE*) pData)[0] = 3;
}
catch (...)
{
TRACE("Unhandled exception caught\n");
}
bIsOpen = mmf2.IsOpen();
sName = mmf2.GetMappingName();
bSuccess = mmf2.Flush();
#ifdef _DEBUG
afxDump << mmf2;
#endif
bSuccess = mmf2.Close();
bIsOpen = mmf2.IsOpen();
sName = mmf2.GetMappingName();
mmf2.UnMap();
//Now a real demonstration of Memory mapped file usage
//Backup the file CONFIG.SYS to CONFIG.PJ and make it all
//uppercase. Error checking is ignored for demonstration purposes
//The real power of memory mapped files is that this demonstration
//would work just as efficiently with a 100 MB file as it does with
//just a small file like config.sys.
CopyFile(_T("C:\\CONFIG.SYS"), _T("C:\\CONFIG.PJ"), FALSE);
CMemMapFile mmf3;
mmf3.MapFile(_T("C:\\CONFIG.PJ"), FALSE);
pData = mmf3.Open();
CharUpperBuff((char*) pData, mmf3.GetLength());
mmf3.UnMap();
AfxMessageBox(_T("The file c:\\config.pj should be the uppercase version of c:\\config.sys"));
//test out the NULL termination functions
CopyFile(_T("C:\\CONFIG.SYS"), _T("C:\\CONFIG.PJ2"), TRUE);
CMemMapFile mmf4;
bSuccess = mmf4.MapFile(_T("C:\\CONFIG.PJ2"), FALSE, 0, FALSE);
pData = mmf4.Open();
CharLower((char*) pData);
mmf4.UnMap();
AfxMessageBox(_T("The file c:\\config.pj2 should be the lowercase version of c:\\config.sys"));
//Finally a demonstration of the shared memory capabilities of
//memory mapped files. For this demo, we will bring up a UI which
//will take whatever is put into its edit box and transfer it into
//shared memory. Then if you bring up another version of testmemmap,
//you will see this value being reflecting into it.
//periodically
CDialog1 dlg;
dlg.DoModal();
return FALSE;
}
CDialog1::CDialog1(CWnd* pParent /*=NULL*/)
: CDialog(CDialog1::IDD, pParent)
{
//{{AFX_DATA_INIT(CDialog1)
//}}AFX_DATA_INIT
}
void CDialog1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDialog1)
DDX_Control(pDX, IDC_EDIT1, m_ctrlEdit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDialog1, CDialog)
//{{AFX_MSG_MAP(CDialog1)
ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
ON_WM_DESTROY()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CDialog1::OnInitDialog()
{
CDialog::OnInitDialog();
//Limit the text to the size that can be held in the MMF
m_ctrlEdit.LimitText(MAX_EDIT_TEXT);
//Check to see if we are the first instance
//of this program running. In the process testing
//the MapExistingMemory method
if (m_mmf.MapExistingMemory(_T("MMFTEST"), (MAX_EDIT_TEXT+1)*sizeof(TCHAR)))
AfxMessageBox(_T("This program is already running"));
else
{
AfxMessageBox(_T("This program is the first instance"));
//map the shared memory,
if (m_mmf.MapMemory(_T("MMFTEST"), (MAX_EDIT_TEXT+1)*sizeof(TCHAR)))
{
//Set the initial text which will go into the MMF
m_ctrlEdit.SetWindowText(_T("Initial Text"));
}
else
{
AfxMessageBox(_T("Failed to map shared memory"));
PostMessage(WM_CLOSE);
}
}
//Create a 1 second timer to allow us to update the
//edit box
m_nTimer = SetTimer(1, 1000, NULL);
return TRUE;
}
void CDialog1::OnChangeEdit1()
{
TCHAR sText[MAX_EDIT_TEXT+1];
m_ctrlEdit.GetWindowText(sText, MAX_EDIT_TEXT);
LPVOID lpData = m_mmf.Open();
if (lpData)
_tcscpy((TCHAR*)lpData, sText);
m_mmf.Close();
}
void CDialog1::OnDestroy()
{
KillTimer(m_nTimer);
CDialog::OnDestroy();
}
void CDialog1::OnTimer(UINT /*nIDEvent*/)
{
//Retreive the contents of the MMF
TCHAR sNewText[MAX_EDIT_TEXT+1];
_tcscpy(sNewText, _T(""));
LPVOID lpData = m_mmf.Open();
if (lpData)
_tcscpy(sNewText, (TCHAR*) lpData);
m_mmf.Close();
//update the edit control if the text has changed
CString sCurrentText;
m_ctrlEdit.GetWindowText(sCurrentText);
if (sCurrentText != sNewText)
m_ctrlEdit.SetWindowText(sNewText);
}