Click here to Skip to main content
15,892,059 members
Articles / Desktop Programming / MFC

Shared memory

Rate me:
Please Sign up or sign in to vote.
4.80/5 (6 votes)
28 Sep 20028 min read 223.1K   6K   84  
Share variables in the shared memory across processes
// TestSMDlg.cpp : implementation file
//
#include "stdafx.h"
#include "TestSM.h"
#include "AddVal.h"
#include "SetVal.h"
#include "Helpers.h"
#include "WriteDlg.h"
#include "TestSMDlg.h"
#include "CmpExchDlg.h"
#include "ExchAddDlg.h"
#include "TestExchDlg.h"
#include "IntrExchDlg.h"
#include "SharedMemory.h"
#include "WaitMultiVarchDlg.h"

#define MEMORY_SIZE		512
//#define DUMP_SHARED_MEMORY

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// 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()

void InitSharedMemory(CSharedMemory *pMem, void *)
{
	if (!pMem->ExistValue(_T("test"))) {
		DWORD dwVal = 0x00;
		pMem->AddValue(_T("test"),sizeof(dwVal));
		pMem->SetValue(_T("test"),&dwVal,sizeof(dwVal));
	}
}

/////////////////////////////////////////////////////////////////////////////
// CTestSMDlg dialog

CTestSMDlg::CTestSMDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTestSMDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTestSMDlg)
	m_CsUsedSize = _T("0");
	m_CsMemorySize = _T("0");
	m_CsTotalUsage = _T("");
	m_CsVariablesCount = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	SECURITY_DESCRIPTOR sd;
	InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
	SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);

	SECURITY_ATTRIBUTES sa = { sizeof sa, &sd, FALSE };
 
	m_psm = new CSharedMemory(_T("TestMemory"),MEMORY_SIZE);

	if ((m_psm) && (m_psm->IsCreated()) && (! m_psm->ExistValue(_T("Test")))) {
		m_psm->AddDwordValue(_T("Test"),1);
	}
}

CTestSMDlg::~CTestSMDlg()
{
	delete m_psm;
}

void CTestSMDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTestSMDlg)
	DDX_Control(pDX, IDC_TESTEXCHANGE, m_CBtnTestExch);
	DDX_Control(pDX, IDC_INCREMENT, m_CBtnIncr);
	DDX_Control(pDX, IDC_EXCHANGEADD, m_CBtnExchAdd);
	DDX_Control(pDX, IDC_EXCHANGE, m_CBtnExch);
	DDX_Control(pDX, IDC_DECREMENT, m_CBtnDecr);
	DDX_Control(pDX, IDC_COMPAREEXCHANGE, m_CBtnCmpExch);
	DDX_Control(pDX, IDC_WAITFORCHANGE, m_CBtnWaiForVar);
	DDX_Control(pDX, IDC_SHAREDMEMORY, m_SharedMemView);
	DDX_Control(pDX, IDC_SETVAL, m_CBtnSetVal);
	DDX_Control(pDX, IDC_REFR, m_CbtnRefr);
	DDX_Control(pDX, IDC_DEL, m_CBtnDel);
	DDX_Control(pDX, IDC_ADD, m_CbtnAdd);
	DDX_Text(pDX, IDC_USEDSIZE, m_CsUsedSize);
	DDX_Text(pDX, IDC_MEMORYSIZE, m_CsMemorySize);
	DDX_Text(pDX, IDC_TOTALUSAGE, m_CsTotalUsage);
	DDX_Text(pDX, IDC_VARIABLESCOUNT, m_CsVariablesCount);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTestSMDlg, CDialog)
	//{{AFX_MSG_MAP(CTestSMDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ADD, OnAdd)
	ON_BN_CLICKED(IDC_DEL, OnDel)
	ON_BN_CLICKED(IDC_REFR, OnRefr)
	ON_BN_CLICKED(IDC_SETVAL, OnSetval)
	ON_NOTIFY(NM_DBLCLK, IDC_SHAREDMEMORY, OnDblclkSharedmemory)
	ON_BN_CLICKED(IDC_WAITFORCHANGE, OnWaitForChange)
	ON_BN_CLICKED(IDC_WAITMEM, OnWaitForMem)
	ON_NOTIFY(HDN_ITEMCLICK, IDC_SHAREDMEMORY, OnItemclickSharedmemory)
	ON_NOTIFY(NM_CLICK, IDC_SHAREDMEMORY, OnClickSharedmemory)
	ON_NOTIFY(LVN_KEYDOWN, IDC_SHAREDMEMORY, OnKeydownSharedmemory)
	ON_BN_CLICKED(IDC_COMPAREEXCHANGE, OnCompareexchange)
	ON_BN_CLICKED(IDC_DECREMENT, OnDecrement)
	ON_BN_CLICKED(IDC_EXCHANGE, OnExchange)
	ON_BN_CLICKED(IDC_EXCHANGEADD, OnExchangeadd)
	ON_BN_CLICKED(IDC_INCREMENT, OnIncrement)
	ON_BN_CLICKED(IDC_READ, OnRead)
	ON_BN_CLICKED(IDC_TESTEXCHANGE, OnTestexchange)
	ON_BN_CLICKED(IDC_WRITE, OnWrite)
	ON_BN_CLICKED(IDC_WAITFORMULTIVARCHANGE, OnWaitformultivarchange)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestSMDlg message handlers

BOOL CTestSMDlg::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
	
	CRect rect;
	m_SharedMemView.GetWindowRect(&rect);
	m_SharedMemView.InsertColumn(0, _T("Name"), LVCFMT_LEFT,rect.Width() * 1/5, 2);
	m_SharedMemView.InsertColumn(1, _T("Length"), LVCFMT_LEFT,rect.Width() * 1/11, 0);
	m_SharedMemView.InsertColumn(2, _T("Text Value"), LVCFMT_LEFT,rect.Width() * 1/3, 0);
	m_SharedMemView.InsertColumn(3, _T("Binary Value"), LVCFMT_LEFT,rect.Width() * 1/3, 0);

	OnRefr();

	UpdateButtonsState(-1);

#ifdef _UNICODE
	CString strTitle;
	GetWindowText(strTitle);
	strTitle += _T(" - UNICODE");
	SetWindowText(strTitle);
#endif

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTestSMDlg::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 CTestSMDlg::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 CTestSMDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTestSMDlg::OnAdd() 
{
	CAddVal dlg;

	if (dlg.DoModal() == IDOK) {
		if (!m_psm->AddValue((TCHAR *)LPCTSTR(dlg.m_CsName),dlg.m_dwSize)) {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot add value: ");
			msg += str;
			AfxMessageBox(msg);
		} else {
			OnRefr();
		}
	}	
}

void CTestSMDlg::OnDel() 
{
	int pos = m_SharedMemView.GetSelectionMark();
	if (pos != -1) {

		CString name = m_SharedMemView.GetItemText(pos,0);

		if (!m_psm->DeleteValue((TCHAR *)LPCTSTR(name))) {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot delete value: ");
			msg += str;
			AfxMessageBox(msg);
		} else {
			OnRefr();
		}
	}

	m_SharedMemView.SetSelectionMark(0);
	pos = m_SharedMemView.GetSelectionMark();
	UpdateButtonsState(pos);
}

void CTestSMDlg::OnRefr() 
{
	LV_ITEM lvitem;
	ValueHeader varInfo;
	m_SharedMemView.DeleteAllItems();
	TCHAR szText[128];
	TCHAR szVarText[65535];
	DWORD J;

	DWORD dwUsed = 0;
	DWORD dwTotalUsage = 2*sizeof(DWORD);		//this is default

	DWORD dwCount = m_psm->GetVariablesCount();

	for (DWORD i = 0; i < dwCount; i++) {
		m_psm->GetValueInfo(i,&varInfo);

		_stprintf(szText,_T("%d"),varInfo.dwLength);
		dwUsed += varInfo.dwLength;
		dwTotalUsage += sizeof(ValueHeader);
		dwTotalUsage += varInfo.dwLength;

#ifndef _UNICODE
		DWORD dwNamLn = wcslen(varInfo.wszValueName)+2;
		char *szName = new char[dwNamLn];

		WideCharToMultiByte(CP_ACP,0,varInfo.wszValueName,-1,szName,dwNamLn,NULL,NULL);

		m_SharedMemView.InsertItem(i,szName);
#else
		m_SharedMemView.InsertItem(i,varInfo.wszValueName);
#endif

		lvitem.mask = LVIF_TEXT;
		lvitem.iItem = i;
		lvitem.iSubItem = 0;

#ifndef _UNICODE
		lvitem.pszText = szName;
#else
		lvitem.pszText = varInfo.wszValueName;
#endif

		m_SharedMemView.SetItem(&lvitem);

		lvitem.mask = LVIF_TEXT;
		lvitem.iItem = i;
		lvitem.iSubItem = 1;
		lvitem.pszText = szText;

		m_SharedMemView.SetItem(&lvitem);

		BYTE *tmpBuf = NULL;
		DWORD dwLn;
		
#ifndef _UNICODE
		m_psm->GetValue(szName,tmpBuf,&dwLn);
#else
		m_psm->GetValue(varInfo.wszValueName,tmpBuf,&dwLn);
#endif
		tmpBuf = new BYTE[dwLn+1];
#ifndef _UNICODE
		m_psm->GetValue(szName,tmpBuf,&dwLn);
#else
		m_psm->GetValue(varInfo.wszValueName,tmpBuf,&dwLn);
#endif

		lvitem.mask = LVIF_TEXT;
		lvitem.iItem = i;
		lvitem.iSubItem = 2;

		for (DWORD j = 0; j < dwLn; j++) {
			szVarText[j] = GetPrintCharOrDot(tmpBuf[j]);
		}
		szVarText[j] = '\0';

		lvitem.pszText = szVarText;

		m_SharedMemView.SetItem(&lvitem);

		lvitem.mask = LVIF_TEXT;
		lvitem.iItem = i;
		lvitem.iSubItem = 3;

		for (j = 0, J = 0; j < dwLn; j++, J += 3) {
			char c = (char)((0xF0 & tmpBuf[j]) >> 4);
			szVarText[J] = c > 0x9 ? (char)(c + 0x37) : (char)(c + 0x30);

			c = (char)((0x0F & tmpBuf[j]));
			szVarText[J+1] = c > 0x9 ? (char)(c + 0x37) : (char)(c + 0x30);

			szVarText[J+2] = (char)' ';
		}
		szVarText[J] = '\0';

		lvitem.pszText = szVarText;

		m_SharedMemView.SetItem(&lvitem);

		delete [] tmpBuf;
#ifndef _UNICODE
		delete [] szName;
#endif
	}

	m_CsMemorySize.Format(_T("%d"),m_psm->GetMemSize());
	m_CsUsedSize.Format(_T("%d"),dwUsed);
	m_CsVariablesCount.Format(_T("%d"),dwCount);
	m_CsTotalUsage.Format(_T("%d"),dwTotalUsage);

#if defined(_DEBUG) && defined(DUMP_SHARED_MEMORY)
	m_psm->Dump(afxDump);
#endif
	UpdateData(FALSE);
	UpdateButtonsState(-1);
}

void CTestSMDlg::OnSetval() 
{
	CSetVal dlg;

	int pos = m_SharedMemView.GetSelectionMark();
	if (pos != -1) {
		if (dlg.DoModal() == IDOK) {

			CString name = m_SharedMemView.GetItemText(pos,0);

			if (!m_psm->SetValue((TCHAR *)LPCTSTR(name),(void *)LPCTSTR(dlg.m_CsNewValue),_tcsclen(dlg.m_CsNewValue))) {
				CString str;
				GetErrorDescription(m_psm->GetLastError(),str);
				CString msg = _T("Cannot set value: ");
				msg += str;
				AfxMessageBox(msg);
			} else {
				OnRefr();
			}
		}
	}
}

void CTestSMDlg::OnDblclkSharedmemory(NMHDR*, LRESULT* pResult) 
{
	OnSetval();
	
	*pResult = 0;
}

void CTestSMDlg::OnWaitForChange() 
{
	CWaitCursor wait;

	int pos = m_SharedMemView.GetSelectionMark();
	if (pos != -1) {
		CString name = m_SharedMemView.GetItemText(pos,0);
		DWORD dwRet = m_psm->WaitForValueChange((TCHAR *)LPCTSTR(name));

		if (dwRet != WAIT_FAILED) {
			CString str;
			str.Format(_T("Value '%s' has been changed."),name);
			OnRefr();
			AfxMessageBox(str);
		} else {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot wait for value's change: ");
			msg += str;
			AfxMessageBox(msg);
		}
	}	
}

void CTestSMDlg::OnWaitForMem() 
{
	CWaitCursor wait;

	DWORD dwRet = m_psm->WaitForMemChange();

	if (dwRet != WAIT_FAILED) {
		CString str;
		str = _T("Memory has been changed.");
		OnRefr();
		AfxMessageBox(str);
	} else {
		CString str;
		GetErrorDescription(m_psm->GetLastError(),str);
		CString msg = _T("Cannot wait for memory's change: ");
		msg += str;
		AfxMessageBox(msg);
	}
}

void CTestSMDlg::OnItemclickSharedmemory(NMHDR* pNMHDR, LRESULT* pResult) 
{
	HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;

	int pos = m_SharedMemView.GetSelectionMark();
	UpdateButtonsState(pos);
	
	*pResult = 0;
}

void CTestSMDlg::OnClickSharedmemory(NMHDR*, LRESULT* pResult) 
{
	int pos = m_SharedMemView.GetSelectionMark();
	UpdateButtonsState(pos);
	
	*pResult = 0;
}

void CTestSMDlg::OnKeydownSharedmemory(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;

	int pos = m_SharedMemView.GetSelectionMark();

	UpdateButtonsState(pos);
	
	*pResult = 0;
}

void CTestSMDlg::UpdateButtonsState(int pos)
{
	if (pos != -1) {
		m_CBtnWaiForVar.EnableWindow(TRUE);
		m_CBtnSetVal.EnableWindow(TRUE);
		m_CbtnRefr.EnableWindow(TRUE);
		m_CBtnDel.EnableWindow(TRUE);
		m_CbtnAdd.EnableWindow(TRUE);
		m_CBtnTestExch.EnableWindow(TRUE);
		m_CBtnIncr.EnableWindow(TRUE);
		m_CBtnExchAdd.EnableWindow(TRUE);
		m_CBtnExch.EnableWindow(TRUE);
		m_CBtnDecr.EnableWindow(TRUE);
		m_CBtnCmpExch.EnableWindow(TRUE);
		m_CBtnWaiForVar.EnableWindow(TRUE);
	} else {
		m_CBtnWaiForVar.EnableWindow(FALSE);
		m_CBtnSetVal.EnableWindow(FALSE);
		m_CbtnRefr.EnableWindow(TRUE);
		m_CBtnDel.EnableWindow(FALSE);
		m_CbtnAdd.EnableWindow(TRUE);
		m_CBtnTestExch.EnableWindow(FALSE);
		m_CBtnIncr.EnableWindow(FALSE);
		m_CBtnExchAdd.EnableWindow(FALSE);
		m_CBtnExch.EnableWindow(FALSE);
		m_CBtnDecr.EnableWindow(FALSE);
		m_CBtnCmpExch.EnableWindow(FALSE);
		m_CBtnWaiForVar.EnableWindow(FALSE);
	}	
}

void CTestSMDlg::OnCompareexchange() 
{
	CCmpExchDlg dlg;

	if (dlg.DoModal() == IDOK) {
		int pos = m_SharedMemView.GetSelectionMark();
		if (pos != -1) {

			CString name = m_SharedMemView.GetItemText(pos,0);

			LONG dwExch = dlg.m_dwExchange;
			LONG dwComp = dlg.m_dwComperand;
			LONG dwPrevVal = 0;

			if (!m_psm->InterlockedCompareExchange((TCHAR *)LPCTSTR(name),dwExch,dwComp,&dwPrevVal)) {
				CString str;
				GetErrorDescription(m_psm->GetLastError(),str);
				CString msg = _T("Cannot compare and exchange value: ");
				msg += str;
				AfxMessageBox(msg);
			} else {
				OnRefr();
				CString str;
				str.Format(_T("Previous value of '%s' = %d"),name,dwPrevVal);
				AfxMessageBox(str);
			}
		}
		pos = m_SharedMemView.GetSelectionMark();
		UpdateButtonsState(pos);
	}	
}

void CTestSMDlg::OnDecrement() 
{
	int pos = m_SharedMemView.GetSelectionMark();
	if (pos != -1) {

		CString name = m_SharedMemView.GetItemText(pos,0);
		LONG dwNewVal = 0;

		if (!m_psm->InterlockedDecrement((TCHAR *)LPCTSTR(name),&dwNewVal)) {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot decrement value: ");
			msg += str;
			AfxMessageBox(msg);
		} else {
			OnRefr();
			CString str;
			str.Format(_T("New value of '%s' = %d"),name,dwNewVal);
			AfxMessageBox(str);
		}
	}
	pos = m_SharedMemView.GetSelectionMark();
	UpdateButtonsState(pos);
}

void CTestSMDlg::OnExchange() 
{
	CIntrExchDlg dlg;

	if (dlg.DoModal() == IDOK) {

		int pos = m_SharedMemView.GetSelectionMark();
		if (pos != -1) {

			CString name = m_SharedMemView.GetItemText(pos,0);
			LONG dwPriorVal = 0;
			LONG dwNewVal = dlg.m_dwNewValue;

			if (!m_psm->InterlockedExchange((TCHAR *)LPCTSTR(name),dwNewVal,&dwPriorVal)) {
				CString str;
				GetErrorDescription(m_psm->GetLastError(),str);
				CString msg = _T("Cannot exchange value: ");
				msg += str;
				AfxMessageBox(msg);
			} else {
				OnRefr();
				CString str;
				str.Format(_T("Previous value of '%s' = %d"),name,dwPriorVal);
				AfxMessageBox(str);
			}
		}
		pos = m_SharedMemView.GetSelectionMark();
		UpdateButtonsState(pos);
	}
}

void CTestSMDlg::OnExchangeadd() 
{
	CExchAddDlg dlg;

	if (dlg.DoModal() == IDOK) {

		int pos = m_SharedMemView.GetSelectionMark();
		if (pos != -1) {

			CString name = m_SharedMemView.GetItemText(pos,0);
			LONG lnewVal = 0;
			LONG lIncr = dlg.m_lAdd;

			if (!m_psm->InterlockedExchangeAdd((TCHAR *)LPCTSTR(name),lIncr,&lnewVal)) {
				CString str;
				GetErrorDescription(m_psm->GetLastError(),str);
				CString msg = _T("Cannot exchange and add value: ");
				msg += str;
				AfxMessageBox(msg);
			} else {
				OnRefr();
				CString str;
				str.Format(_T("Previous value of '%s' = %d"),name,lnewVal);
				AfxMessageBox(str);
			}
		}
		pos = m_SharedMemView.GetSelectionMark();
		UpdateButtonsState(pos);

	}	
}

void CTestSMDlg::OnIncrement() 
{
	int pos = m_SharedMemView.GetSelectionMark();
	if (pos != -1) {

		CString name = m_SharedMemView.GetItemText(pos,0);
		LONG dwNewVal = 0;

		if (!m_psm->InterlockedIncrement((TCHAR *)LPCTSTR(name),&dwNewVal)) {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot increment value: ");
			msg += str;
			AfxMessageBox(msg);
		} else {
			OnRefr();
			CString str;
			str.Format(_T("New value of '%s' = %d"),name,dwNewVal);
			AfxMessageBox(str);
		}
	}
	pos = m_SharedMemView.GetSelectionMark();
	UpdateButtonsState(pos);
}

void CTestSMDlg::OnTestexchange() 
{
	CTestExchDlg dlg;
	
	if (dlg.DoModal() == IDOK) {
		int pos = m_SharedMemView.GetSelectionMark();
		if (pos != -1) {

			CString name = m_SharedMemView.GetItemText(pos,0);

			LONG dwOldVal = dlg.m_dwOldValue;
			LONG dwNewVal = dlg.m_dwNewValue;
			LONG dwPrevVal = 0;

			if (!m_psm->InterlockedTestExchange((TCHAR *)LPCTSTR(name),dwOldVal,dwNewVal,&dwPrevVal)) {
				CString str;
				GetErrorDescription(m_psm->GetLastError(),str);
				CString msg = _T("Cannot test and exchange value: ");
				msg += str;
				AfxMessageBox(msg);
			} else {
				OnRefr();
				CString str;
				str.Format(_T("Previous value of '%s' = %d"),name,dwPrevVal);
				AfxMessageBox(str);
			}
		}
		pos = m_SharedMemView.GetSelectionMark();
		UpdateButtonsState(pos);
	}
}

void CTestSMDlg::OnWrite() 
{
	CWriteDlg dlg;

	if (dlg.DoModal()) {
		if (!m_psm->Write((BYTE*)LPCTSTR(dlg.m_CsData),dlg.m_CsData.GetLength()*sizeof(TCHAR),dlg.m_dwOffset)) {
			CString str;
			GetErrorDescription(m_psm->GetLastError(),str);
			CString msg = _T("Cannot write memory: ");
			msg += str;
			AfxMessageBox(msg);
		} 
	}	
}

void CTestSMDlg::OnRead() 
{
	BYTE pData[MEMORY_SIZE];
	ZeroMemory(pData,MEMORY_SIZE);

	if (!m_psm->Read(pData,MEMORY_SIZE-2*sizeof(DWORD),0)) {
		CString str;
		GetErrorDescription(m_psm->GetLastError(),str);
		CString msg = _T("Cannot read memory: ");
		msg += str;
		AfxMessageBox(msg);
	} else {
		CString str;
		str.Format(_T("Memory:\n%s"),GetDumpString(pData,MEMORY_SIZE));
		AfxMessageBox(str);
	}		
}

void CTestSMDlg::OnWaitformultivarchange() 
{
	
	DWORD dwCount = m_psm->GetVariablesCount();
	if(dwCount <= 0)
	{
		AfxMessageBox(_T("No variables to wait for."));	
		return;
	}

	CWaitMultiVarchDlg dlg(m_psm);
	if(dlg.DoModal() == IDOK)
	{		
//		m_psm->WaitForMultipleValuesChanges(dlg.m_strArray);	
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions