Example #1
0
void CTobCompiler::Reset()
{
	m_line = 0;
	m_err.Empty();
	m_bin.RemoveAll();
	if(m_fsrc) { fclose(m_fsrc); m_fsrc = 0; }
	if(m_fdst) { fclose(m_fdst); m_fdst = 0; }

	POSITION p = m_defbin.GetStartPosition();
	CString str;
	CByteArray* bin;
	while(p)
	{
		m_defbin.GetNextAssoc(p, str, bin);
		delete bin;
	}
	m_defbin.RemoveAll();
	m_defbin.InitHashTable(251);

	m_label.RemoveAll();
	m_label.InitHashTable(251);
	for(int i = m_exp.GetSize() - 1; i >= 0; --i)
		delete m_exp.GetAt(i);
	m_exp.RemoveAll();
	m_change.RemoveAll();
	m_change.InitHashTable(251);
	m_bit_i = 32;
	m_bit_f = 32;
	m_maxc = -1;
	m_maxw = -1;
	m_maxs = -1;
}
Example #2
0
void COXAutoComplete::Detach(HWND hWnd)
{
	if (hWnd)
	{
		COXAutoStorage* pStorage;
		if (m_mpStorage.Lookup(hWnd,pStorage))
		{
			m_mpStorage.RemoveKey(hWnd);
			m_mpOptions.RemoveKey(hWnd);
		}
		else
			return;
		//try to find out who else is using this storage,
		//if no one is using, delete it
		COXAutoStorage* pTest=NULL;
		POSITION pos=m_mpStorage.GetStartPosition();

		while (pos)
		{
			HWND hwnd;
			m_mpStorage.GetNextAssoc(pos,hwnd,pTest);
			if (pTest==pStorage)
				return;
		}
		delete pStorage;
		return;
	}

	//detach all storages
	POSITION pos=m_mpStorage.GetStartPosition();
	
	//cannot delete directly because the same storage can be mapped 
	//to different windows
	CMap<COXAutoStorage*,COXAutoStorage*,DWORD,DWORD> mpToDelete;

	while (pos)
	{
		HWND hwnd;
		COXAutoStorage* pStorage=NULL;
		m_mpStorage.GetNextAssoc(pos,hwnd,pStorage);
		mpToDelete.SetAt(pStorage,NULL);	
	}

	//delete all objects
	pos=mpToDelete.GetStartPosition();
	while (pos)
	{
		COXAutoStorage* pStorage;
		DWORD dwNULL;
		mpToDelete.GetNextAssoc(pos,pStorage,dwNULL);
		delete pStorage;

	}

	mpToDelete.RemoveAll();
	m_mpStorage.RemoveAll();
	m_mpOptions.RemoveAll();
}
Example #3
0
/******************************************************************************
 Function Name  :   vMapCopy

 Input(s)       :   omDestMap - Destination Map object.
                    omSrcMap - Map object which should be copied.
 Output         :   -
 Functionality  :   Copies a CMap object.
 Member of      :   CMessageAttrib

 Author(s)      :   Ratnadip Choudhury
 Date Created   :   03-05-2002
******************************************************************************/
void CMessageAttrib::vMapCopy(CMap <UINT, UINT, SMsgIDAttr, SMsgIDAttr>&
                              omDestMap,
                              CMap <UINT, UINT, SMsgIDAttr, SMsgIDAttr>& omSrcMap)
{
    UINT unMsgID;
    omDestMap.RemoveAll();
    POSITION psCurrPos = omSrcMap.GetStartPosition();

    while (psCurrPos != NULL)
    {
        omSrcMap.GetNextAssoc(psCurrPos, unMsgID, m_sIDAttrTmp);
        omDestMap.SetAt(unMsgID, m_sIDAttrTmp);
    }
}
void CRemoteLuaDebuggerDoc::GetActiveFiles(CStringArray& fileList)
{
	fileList.RemoveAll();

	POSITION pos = m_receivedFileMap.GetStartPosition();
	while (pos)
	{
		CString fileName;
		int temp;
		m_receivedFileMap.GetNextAssoc(pos, fileName, temp);

		fileList.Add(fileName);
	}
}
// 把选中区域转换为绝对排列字符串
CString CGraphInstrumentList::ConvertSelectAreaToAbsoluteSpreadString(CRect* pSelectAreaIndex)
{
	CString strAbsoluteSpread = "";
	CString strLine, strPoint;
	int iPointNb, iPointNbStart, iPointNbEnd;
	int iLineNb;
	CMap<int, int, CString, CString> oLineNbMap;

	for(int i = pSelectAreaIndex->top; i <= pSelectAreaIndex->bottom; i++)
	{
		// 得到图形区列索引对应的测线号
		iLineNb = GetLineNbByRowIndex(i);
		if(iLineNb > 0)	// 测线有效
		{
			iPointNbStart = GetPointNbByColumnIndex(pSelectAreaIndex->left);	// 得到起始测点
			iPointNbEnd = GetPointNbByColumnIndex(pSelectAreaIndex->right);	// 得到终止测点
			if((iPointNbStart > 0) && (iPointNbEnd > 0))	// 测点有效
			{
				if(iPointNbStart > iPointNbEnd)
				{
					iPointNb = iPointNbStart;
					iPointNbStart = iPointNbEnd;
					iPointNbEnd = iPointNb;
				}
				strPoint.Format("%d-%d", iPointNbStart, iPointNbEnd);	// 测点字符串
				strLine.Format("%d:%s;", iLineNb, strPoint);	// 测线字符串
				oLineNbMap.SetAt(iLineNb, strLine);	// 加入索引表
			}
		}
	}
	POSITION pos = oLineNbMap.GetStartPosition();
	while(NULL != pos)
	{
		oLineNbMap.GetNextAssoc(pos, iLineNb, strLine);
		strAbsoluteSpread = strAbsoluteSpread + strLine;	// 链接测线字符串
	}
	if(strAbsoluteSpread.GetLength() > 0)
	{
		strAbsoluteSpread = strAbsoluteSpread.Left(strAbsoluteSpread.GetLength() - 1);	// 去掉最后一个字符“;”
	}
	oLineNbMap.RemoveAll();
	return strAbsoluteSpread;
}
Example #6
0
void CDlgSpeedTest::Sort()
{
	CMap<DWORD,DWORD,SpeedTestResult,SpeedTestResult> mapTmp;
	CArray<SpeedTestResult,SpeedTestResult> ayTmp;
	for (int i=0; i<m_ayTestResult.GetCount(); i++)
	{
		SpeedTestResult res = m_ayTestResult.GetAt(i);
		if (!res.m_bError)
		{
			mapTmp.SetAt(res.m_result,res);
		}
		else
			ayTmp.Add(res);
	}
	m_ayTestResult.RemoveAll();
	POSITION pos = mapTmp.GetStartPosition();
	DWORD key;
	SpeedTestResult val;
	while (pos)
	{
		mapTmp.GetNextAssoc(pos,key,val);
		m_ayTestResult.Add(val);
	}
	for (int j=0; j<ayTmp.GetCount(); j++)
	{
		m_ayTestResult.Add(ayTmp.GetAt(j));
	}

	for(int i=0; i<m_cList.GetItemCount(); i++)
	{
		CString str;
		str = m_cList.GetItemText(i,0);
		if (FindRes(str))
		{
			m_cList.DeleteItem(i);
			i--;
		}
	}
	ShowRes();
}
Example #7
0
void Reporter :: WriteReport ( void )
{
	FILE * pFile = fopen ( "report.txt", "w" );
	ASSERT ( pFile );
	if (pFile == NULL )
		return;

	for ( POSITION pos = m_mapHistory.GetStartPosition(); pos != NULL; )
	{
		CString str;
		CMap<int,int,int,int> *pCount;
		int i;

		m_mapHistory.GetNextAssoc ( pos, str, pCount );

		int c = 0;

		for ( POSITION pos2 = pCount->GetStartPosition(); pos2 != NULL; )
		{
			int t, c2;
			pCount->GetNextAssoc ( pos2, t, c2 );
			c += c2;
		}


//		c /= pCount->GetSize();
		if ( c < 1000 )
			continue;

		fprintf ( pFile, "%s\t", str );
		for ( i = 0; i < m_time; i++ )
		{
			fprintf ( pFile, "%d\t", (*pCount)[i] );
			fflush ( pFile );
		}

		fprintf ( pFile, "\n" );
	}
}
void CXTPMarkupInputElement::FireTriggers(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pNewValue)
{
	BOOL bChanged = FALSE;
	int i;

	CMap<CXTPMarkupDependencyProperty*, CXTPMarkupDependencyProperty*, CXTPMarkupObject*, CXTPMarkupObject*> mapOldValues;

	if (m_pActiveTriggers)
	{
		for (i = m_pActiveTriggers->GetCount() - 1; i >= 0; i--)
		{
			CXTPMarkupTrigger* pTrigger = m_pActiveTriggers->GetItem(i);

			if (pTrigger->GetTriggerProperty() == pProperty)
			{
				if (!pTrigger->GetTriggerValue()->IsEqual(pNewValue))
				{
					CXTPMarkupSetterColection* pSetters = pTrigger->GetSetters();

					for (int j = 0; j < pSetters->GetCount(); j++)
					{
						CXTPMarkupSetter* pSetter = pSetters->GetItem(j);
						CXTPMarkupDependencyProperty* pSetterProperty = pSetter->GetSetterProperty();

						CXTPMarkupObject* pOldValue = m_pTriggerProperties->Lookup(pSetterProperty);

						CXTPMarkupObject* pTempValue;
						if (!mapOldValues.Lookup(pSetterProperty, pTempValue))
						{
							MARKUP_ADDREF(pOldValue);
							mapOldValues.SetAt(pSetterProperty, pOldValue);
						}

						m_pTriggerProperties->Set(pSetterProperty, NULL);
					}

					m_pActiveTriggers->Remove(i);
					bChanged = TRUE;
				}
			}
		}
	}

	if (m_pStyleCache)
	{
		bChanged = AddStyleTriggers(m_pStyleCache, pProperty, pNewValue) || bChanged;
	}
	else if (GetType()->GetTypeStyle())
	{
		bChanged = AddStyleTriggers(GetType()->GetTypeStyle(), pProperty, pNewValue) || bChanged;
	}


	if (bChanged)
	{
		if (!m_pTriggerProperties)
			m_pTriggerProperties = new CXTPMarkupProperties(NULL);

		for (i = 0; i < m_pActiveTriggers->GetCount(); i++)
		{
			CXTPMarkupTrigger* pTrigger = m_pActiveTriggers->GetItem(i);

			CXTPMarkupSetterColection* pSetters = pTrigger->GetSetters();

			for (int j = 0; j < pSetters->GetCount(); j++)
			{
				CXTPMarkupSetter* pSetter = pSetters->GetItem(j);

				CXTPMarkupObject* pValue = pSetter->GetSetterValue();

				CXTPMarkupDependencyProperty* pSetterProperty = pSetter->GetSetterProperty();

				CXTPMarkupObject* pOldValue = m_pTriggerProperties->Lookup(pSetterProperty);

				if (!pValue->IsEqual(pOldValue))
				{
					CXTPMarkupObject* pTempValue;
					if (!mapOldValues.Lookup(pSetterProperty, pTempValue))
					{
						MARKUP_ADDREF(pOldValue);
						mapOldValues.SetAt(pSetterProperty, pOldValue);
					}

					pValue->AddRef();
					m_pTriggerProperties->Set(pSetterProperty, pValue);
				}
			}
		}
	}

	POSITION pos = mapOldValues.GetStartPosition();
	while (pos)
	{
		CXTPMarkupDependencyProperty* pProperty;
		CXTPMarkupObject* pOldValue;
		mapOldValues.GetNextAssoc(pos, pProperty, pOldValue);

		CXTPMarkupObject* pNewValue = m_pTriggerProperties->Lookup(pProperty);

		if (!::IsEqual(pNewValue, pOldValue))
		{
			OnPropertyChanged(pProperty, pOldValue, pNewValue);

			if (pProperty->GetFlags() & CXTPMarkupPropertyMetadata::flagInherited)
			{
				RecursePropertyChanged(pProperty, pOldValue, pNewValue);
			}
		}

		MARKUP_RELEASE(pOldValue);
	}
}
Example #9
0
BOOL 	CWedApp::InitInstance()

{
	CString str;
	char *ptr;

	//SetDialogBkColor(0x00ff0000, 0xffffff);

	WaitCursor = AfxGetApp()->LoadStandardCursor(IDC_WAIT);
	NormalCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);

	GetModuleFileName(AfxGetInstanceHandle(), approot, MAX_PATH);

	CTime ct = CTime::GetCurrentTime();
	CString datestr = ct.Format("%A, %B %d, %Y - %I:%M %p");

	C2N();
	P2N("\r\nStarted WED application at %s\r\n", datestr);
	//P2N("AppRoot=%s\r\n", approot);

	//CString desktop;
	//GetSpecialFolder(CSIDL_DESKTOPDIRECTORY, desktop);
	//desktop += "wed";

	//P2N("Desktop special: %s\r\n", desktop);

	// Create initial desktop xcpt folder
	//if(access(desktop, 0) == -1)
	//	{
	//	P2N("Making %s\r\n", desktop);
	//	//message("Created desktop folder.");
	//	_mkdir(desktop);
	//	}

	ptr = strrchr(approot, '\\');
	if(ptr)
		*(ptr+1) = '\0';

	//dataroot = (CString)approot + "wed\\";

	GetSpecialFolder(CSIDL_PERSONAL, dataroot);
	dataroot += "WedData\\";

	P2N("Wed user data directory: %s\r\n", dataroot);

	if(access(dataroot, 0))
		{
		if(mkdir(dataroot))
			{
			//P2N("Cannot create data root dir\r\n");
			}
		}

	//////////////////////////////////////////////////////////////////////
	// Create data dirs

	str = dataroot; str += "data";

	// Check if data dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create data dir\r\n");
			}
		}
	str = dataroot; str += "macros";
	// Check if data dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create macro dir\r\n");
			}
		}
	str = dataroot; str += "holdings";
	// Check if data dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create holders dir\r\n");
			}
		}
	str = dataroot; str += "coco";
	// Check if coco dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create coco dir\r\n");
			}
		}
	str = dataroot; str += "backup";
	// Check if state dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create state dir\r\n");
			}
		}
	str = dataroot; str += "template";
	// Check if state dir is in order
	if(access(str, 0))
		{
		if(mkdir(str))
			{
			//P2N("Cannot create template dir\r\n");
			}
		}

	//P2N("Started Application: %s %s\r\n",
	//		m_pszAppName, approot);

	getcwd(str.GetBuffer(MAX_PATH), MAX_PATH);
	str.ReleaseBuffer();

	//P2N("Initial dir: %s\r\n", str);

	if (!AfxSocketInit())
		{
		AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
		return FALSE;
		}

	// Initialize OLE 2.0 libraries
	if (!AfxOleInit())
		{
		AfxMessageBox("Failed OLE library init, OLE functions will not be available");
		}
	AfxEnableControlContainer();

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// You should modify this string to be something appropriate
	// such as the name of your company or organization.

	SetRegistryKey(_T("RobotMonkeySoftware"));

	LoadStdProfileSettings(6);  // Load standard INI file options (including MRU)

	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.

	pDocTemplate = new CMultiDocTemplate(
			IDR_WEDTYPE,
				RUNTIME_CLASS(CWedDoc),
					RUNTIME_CLASS(CChildFrame), // custom MDI child frame
						RUNTIME_CLASS(CWedView));
	AddDocTemplate(pDocTemplate);

	// create main MDI Frame window
	pMainFrame = new CMainFrame;

	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;

	// Global
	m_pMainWnd = pMainFrame;

	// Get resources we need:
	// 1. Fonts

	CString fontname = 	GetProfileString(strConfig, strFontName, "Courier");
	int size    =  		GetProfileInt(strConfig,  strFontSize, 10);
	int weight  =  		GetProfileInt(strConfig, strFontWeight, 0);
	int italic  =  		GetProfileInt(strConfig, strFontItalic, 0);

	if(!ff.CreateFont(size, 0, 0, 0, weight, italic, 0, 0,
				0, 0, 0, 0, FIXED_PITCH, fontname))
		{
		AfxMessageBox("Cannot set font");
		}
	if(!ff.GetLogFont(&fflf))
		{
		AfxMessageBox("Cannot get font parameters");
		}

	// 2. Printer fonts
	if(!pp.CreateFont(80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                FF_MODERN, "system"))
		{
		MessageBox(NULL, "Cannot set font", "Wed", 0);
		}
	if(!pp.GetLogFont(&pplf))
		{
		MessageBox(NULL, "Cannot get font parameters", "Wed", 0);
		}

	// Get colors
	bgcol 	=  GetProfileInt(strConfig,  strColorBg, 	bgcol);
	fgcol 	=  GetProfileInt(strConfig,  strColorFg, 	fgcol);
	selcol 	=  GetProfileInt(strConfig,  strColorSel , 	selcol );
    cselcol =  GetProfileInt(strConfig,  strColorCSel, 	cselcol);
    cadd    =  GetProfileInt(strConfig,  strColorAdd , 	cadd   );
    cdel    =  GetProfileInt(strConfig,  strColorDel , 	cdel   );
    cchg    =  GetProfileInt(strConfig,  strColorChg , 	cchg   );
    comm    =  GetProfileInt(strConfig,  strColorComm, 	comm   );
    srcc    =  GetProfileInt(strConfig,  strColorSrc , 	srcc   );
    clng    =  GetProfileInt(strConfig,  strColorLong, 	clng   );

	// Bimaps
	caret.LoadBitmap(IDB_BITMAP1);
    backwrap  =  GetProfileInt(strConfig,  strBackWrap , 0);
    Tab2Space =  GetProfileInt(strConfig,  strTab2Space, 0);
    tabstop   =  GetProfileInt(strConfig,  strTabStop, 4);

	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	if(cmdInfo.m_strFileName != "")
		{
		comline = TRUE;
		OpenDocumentFile(cmdInfo.m_strFileName);
		}
	else
		{
   		// DON'T display a new MDI child window during startup!!!
		cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
		}

	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// Key settings

	// Figure out last usage time ...
	int last = GetProfileInt(strConfig, "strLastUsage", 0);
	use = GetProfileInt(strConfig, "strUsage", 	0);
	//P2N("Usage count %d \r\n", use);

	// First time ever, display initial file
	if(!use)
		{
		OpenDocumentFile("Welcome.txt");
		comline  = TRUE;
		if(currentedit)
			{
			}
		}

	use++;
	CTime tt = CTime::GetCurrentTime();
	CTimeSpan t(tt.GetTime() - (time_t)last);

	//P2N("Time diff of last fire %d -- %d \r\n",
	//	t.GetTotalSeconds(), (int)tt.GetTime());

	YieldToWin() ;

	// Show sign banner only if more then 60 seconds passed
	//if(t.GetTotalSeconds() > 60)
		{
		spp.Create(IDD_DIALOG5, NULL);
 		spp.Show();
		}

	YieldToWin() ;

	//if(GetKeyState(VK_SHIFT))
	//	{
	//	AfxMessageBox("SHIFT HELD on startup\r\n");
	//	return(TRUE);
	//	}

	// The main window has been initialized ...
	// Show and update it.
	m_nCmdShow = GetProfileInt(strConfig, "WindowState", 1);
	pMainFrame->ShowWindow(m_nCmdShow);
	pMainFrame->UpdateWindow();

	int num = GetProfileInt(strSection, strIntItem, 0);

	// De-serialize hash map
	CMap < int, int&, CString, CString& > HashMap;
	CFile cf;
	CString fname;
	fname.Format("%s%s", dataroot, "macros\\hashes.000");
	if( cf.Open( fname, CFile::modeRead))
		{
		CArchive ar( &cf, CArchive::load);
		HashMap.Serialize(ar);
		}
	else
		{
		//P2N("Cannot open hash map file: %s\r\n", fname);
		}
	POSITION rpos;
	rpos = HashMap.GetStartPosition();
	while(rpos)
		{
		int key;
		CString val;
		HashMap.GetNextAssoc(rpos, key, val);
		//P2N("In Hashlist: %x %s\r\n", key, val);
		}

	if(!comline)
		{
		// Reopen old documents:
		CString buf2, file;
		for(int count1 = 1; count1 <= num; count1++)
			{
			CWedDoc *doc = NULL;
			buf2.Format("%d", count1);
			file = GetProfileString(strSection, strStringItem + buf2);
			//P2N("Reloading file: '%s' at %s\r\n", file, buf2);

			// Empty file, no action
			if(file == "")
				continue;

			doc = (CWedDoc*)OpenDocumentFile(file);

			if(YieldToWinEx())
				break;

			//P2N("After Reloading file: %s at %s\r\n", file, buf2);

			if(doc)
				{
				ASSERT_VALID(doc);

				// Document had an error
				if(doc->ssel.m_err)
					break;

				int lrow, lcol;

				lrow = GetProfileInt(strSection,
					strStringItem + buf2 + "row", 0);

				lcol = GetProfileInt(strSection,
					strStringItem + buf2 + "col", 0);

				// Update cursor positions ...
				POSITION pos = doc->GetFirstViewPosition();
				for(;;)
					{
					if(!pos)
						break;
					CWedView *cv = (CWedView*)doc->GetNextView(pos);
					if(cv)
						{
						ASSERT_VALID(cv);
						cv->row = lrow;  cv->col = lcol;
						cv->SyncCaret();
						YieldToWin() ;
						}
					}
				// This happens after load, set it again
				doc->UpdateAllViews(NULL);
				}
			}

	// Try figure out last current directory
	int idx;
	if( (idx = file.ReverseFind('\\')) != -1)
		{
		file = file.Left(idx + 1);
		}
	P2N("CWedApp::InitInstance Chdir: '%s'\r\n", file);
	_chdir(file);
	targdir = srcdir = file;
    }

	message ("Loading macros ...");
	LoadMacros();

	message ("Loading holdings ...");
	LoadHoldings();

	message("");

	return TRUE;
}
//! Gets the created HTML elements as HTML text
void CRTF_HTMLConverter::R2H_GetHTMLElements(CString& strHTML)
{
	strHTML = _T("");

	// remove invalid trailing elements
	int iElemCount = m_arrHTMLElements.GetSize();

	while (iElemCount--)
	{
		CHTMLElement* pElem = m_arrHTMLElements[iElemCount];

		if (pElem->m_enNodeType == CHTMLElement::c_nodHTMLEnd)
		{
			iElemCount++; // we want this element
			break;
		}
		else if (pElem->m_enNodeType == CHTMLElement::c_nodText)
		{
			CString sText = pElem->m_strNodeText;
			sText.TrimLeft();
			sText.TrimRight();

			if (!sText.IsEmpty() && sText != _T("br") && sText != _T("\n") && sText != _T("\r\n"))
			{
				iElemCount++; // we want this element
				break;
			}
		}
	}

	// Loop thru what's remaining of the HTML elements
	CMap<CString, LPCTSTR, int, int> mapOpenTags;

	for (int iElem = 0; iElem < iElemCount; iElem++)
	{
		CHTMLElement* pElem = m_arrHTMLElements[iElem];
		CString sElem;

		if (pElem->m_enNodeType == CHTMLElement::c_nodHTMLBegin)
		{
			// look ahead so that we can strip out empty tag pairs (typically 'font')
			bool bEmpty = false;

			if (iElem + 1 < m_arrHTMLElements.GetSize())
			{
				CHTMLElement* pElemNext = m_arrHTMLElements[iElem + 1];

				if (pElemNext->m_enNodeType == CHTMLElement::c_nodHTMLEnd &&
					pElemNext->m_strNodeText == pElem->m_strNodeText)
				{
					//TRACE ("CRTF_HTMLConverter::R2H_GetHTMLElements(removing '%s')\n", pElemNext->m_strNodeText);
					bEmpty = true;
				}
			}

			if (bEmpty)
			{
				iElem++;   // remove end tag too
			}
			else
			{
				// keep track of opentags
				int nCount = 0;

				mapOpenTags.Lookup(pElem->m_strNodeText, nCount);
				mapOpenTags[pElem->m_strNodeText] = ++nCount;

				// HTML element open tag
				sElem = _T("<");
				sElem += pElem->m_strNodeText;

				// HTML element parameters (<font param1="test" param2="hugo">
				POSITION pos = pElem->m_mapParams.GetStartPosition();

				while (pos)
				{
					CString strKey, strValue;
					pElem->m_mapParams.GetNextAssoc(pos, strKey, strValue);

					sElem += _T(" ") + strKey + _T(" = ") + strValue;
				}
				sElem += _T(">");
			}
		}
		else if (pElem->m_enNodeType == CHTMLElement::c_nodHTMLEnd)
		{
			sElem.Format(_T("</%s>"), pElem->m_strNodeText);

			// decrement open tag count
			int nCount = 0;

			mapOpenTags.Lookup(pElem->m_strNodeText, nCount);

			if (nCount > 0)
			{
				mapOpenTags[pElem->m_strNodeText] = --nCount;
			}
		}
		else if (pElem->m_enNodeType == CHTMLElement::c_nodText)
		{
			sElem = pElem->m_strNodeText;
		}
		else
		{
			ASSERT(FALSE); //internal error (wrong html tag)
		}

		if (!sElem.IsEmpty())
		{
			strHTML += sElem;
		}
	}

	// any open tags remaining?
	POSITION pos = mapOpenTags.GetStartPosition();

	while (pos)
	{
		CString sTag, sClose;
		int nCount = 0;
		mapOpenTags.GetNextAssoc(pos, sTag, nCount);

		if (nCount && sTag != _T("br"))
		{
			sClose.Format(_T("</%s>"), sTag);

			while (nCount--)
			{
				strHTML += sClose;
			}
		}
	}
}