public void AppendText(string text, MessageType message)
{
switch(message)
{
case MessageType.KeyboardInput:
{
if(Echo)
{
InsertTextAsRtf(text, new Font("Courier New", 10f), RtfColor.BrightYellow, RtfColor.Black);
}
break;
}
case MessageType.Normal:
{
if(boldFont && ((int)foreColor) < 8)
{
foreColor = (RtfColor) ((int)foreColor + 8);
} InsertTextAsRtf(text, new Font("Courier New", 10f), foreColor, backColor);
break;
}
case MessageType.Error:
{
InsertTextAsRtf(text, new Font("Courier New", 10f, FontStyle.Bold), RtfColor.BrightRed, RtfColor.BrightWhite);
break;
}
case MessageType.ANSI:
{
ProcessANSI(text);
break;
}
}
} private void ProcessANSI(string text)
{
ArrayList parms = new ArrayList(); int i = 0;
while(i < text.Length)
{
switch(state)
{
case State.Normal:
{
if(text[i] != EscChar)
{
int start = i;
while(i < text.Length && text[i] != EscChar)
{
i++;
} AppendText(text.Substring(start, i - start), MessageType.Normal);
}
else
{
++i;
}
state = State.Esc;
break;
}
case State.Esc:
{
if(text[i] == '[' && ((i+1) < text.Length && Char.IsNumber(text[i+1])))
{
parms = new ArrayList();
state = State.Bracket;
++i;
break;
}
else
{
state = State.Normal;
break;
}
}
case State.Bracket:
{
while(i < text.Length && (Char.IsNumber(text[i]) || text[i] == ';'))
{
if(Char.IsNumber(text[i]))
{
int param = int.Parse(text[i].ToString());
++i; while(Char.IsNumber(text[i]))
{
param *= 10;
param += int.Parse(text[i].ToString());
++i;
} parms.Add(param); if(text[i] == ';')
{
++i;
break;
}
}
else if(text[i] == ';')
{
++i;
break;
} state = State.Parms;
} break;
}
case State.Parms:
{
switch(text[i])
{
case 'A': //Move cursor up N lines
{
++i;
break;
}
case 'B': //Move cursor down N lines
{
++i;
break;
}
case 'C': //Move cursor foward N lines
{
++i;
break;
}
case 'D': //Move cursor backward N lines
{
++i;
break;
}
case 'H': case 'f': //Move cursor to C column and N line
{
++i;
break;
}
case 'J': //Clear the screen, return to 0,0
{
if(parms[0].Equals(2))
{
/*int chars,lines;
string newlines = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
Graphics g = rich.CreateGraphics();
g.MeasureString(newlines, new Font("Courier New", 8f), rich.DisplayRectangle.Size, StringFormat.GenericDefault, out chars, out lines); this.AppendText(newlines.Substring(0, lines), MessageType.ANSI);
*/
}
++i;
break;
}
case 'K': //erase to EOL
{
++i;
break;
}
case 's': //save cursor position: non-standard
{
++i;
break;
}
case 'u': //restore cursor position - non-standard
{
++i;
break;
}
case 'm':
{
ProcessParms(parms);
++i;
break;
}
default:
{
++i;
break;
}
} state = State.Normal;
break;
}
}
}
}
{
switch(message)
{
case MessageType.KeyboardInput:
{
if(Echo)
{
InsertTextAsRtf(text, new Font("Courier New", 10f), RtfColor.BrightYellow, RtfColor.Black);
}
break;
}
case MessageType.Normal:
{
if(boldFont && ((int)foreColor) < 8)
{
foreColor = (RtfColor) ((int)foreColor + 8);
} InsertTextAsRtf(text, new Font("Courier New", 10f), foreColor, backColor);
break;
}
case MessageType.Error:
{
InsertTextAsRtf(text, new Font("Courier New", 10f, FontStyle.Bold), RtfColor.BrightRed, RtfColor.BrightWhite);
break;
}
case MessageType.ANSI:
{
ProcessANSI(text);
break;
}
}
} private void ProcessANSI(string text)
{
ArrayList parms = new ArrayList(); int i = 0;
while(i < text.Length)
{
switch(state)
{
case State.Normal:
{
if(text[i] != EscChar)
{
int start = i;
while(i < text.Length && text[i] != EscChar)
{
i++;
} AppendText(text.Substring(start, i - start), MessageType.Normal);
}
else
{
++i;
}
state = State.Esc;
break;
}
case State.Esc:
{
if(text[i] == '[' && ((i+1) < text.Length && Char.IsNumber(text[i+1])))
{
parms = new ArrayList();
state = State.Bracket;
++i;
break;
}
else
{
state = State.Normal;
break;
}
}
case State.Bracket:
{
while(i < text.Length && (Char.IsNumber(text[i]) || text[i] == ';'))
{
if(Char.IsNumber(text[i]))
{
int param = int.Parse(text[i].ToString());
++i; while(Char.IsNumber(text[i]))
{
param *= 10;
param += int.Parse(text[i].ToString());
++i;
} parms.Add(param); if(text[i] == ';')
{
++i;
break;
}
}
else if(text[i] == ';')
{
++i;
break;
} state = State.Parms;
} break;
}
case State.Parms:
{
switch(text[i])
{
case 'A': //Move cursor up N lines
{
++i;
break;
}
case 'B': //Move cursor down N lines
{
++i;
break;
}
case 'C': //Move cursor foward N lines
{
++i;
break;
}
case 'D': //Move cursor backward N lines
{
++i;
break;
}
case 'H': case 'f': //Move cursor to C column and N line
{
++i;
break;
}
case 'J': //Clear the screen, return to 0,0
{
if(parms[0].Equals(2))
{
/*int chars,lines;
string newlines = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
Graphics g = rich.CreateGraphics();
g.MeasureString(newlines, new Font("Courier New", 8f), rich.DisplayRectangle.Size, StringFormat.GenericDefault, out chars, out lines); this.AppendText(newlines.Substring(0, lines), MessageType.ANSI);
*/
}
++i;
break;
}
case 'K': //erase to EOL
{
++i;
break;
}
case 's': //save cursor position: non-standard
{
++i;
break;
}
case 'u': //restore cursor position - non-standard
{
++i;
break;
}
case 'm':
{
ProcessParms(parms);
++i;
break;
}
default:
{
++i;
break;
}
} state = State.Normal;
break;
}
}
}
}
{
int nowcol = 0;
foreach(int i in parms)
{
switch(i)
{
case 0: //Reset/None
{
boldFont = false;
foreColor = RtfColor.BrightWhite;
backColor = RtfColor.Black;
break;
}
case 1: //Bold
{
boldFont = true;
break;
}
case 4: //Underscore
{
break;
}
case 5: //Blink
{
break;
}
case 7: //Reverse
{
break;
}
case 8: //Concealed
{
break;
}
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
{
nowcol = i;
break;
}
case 40:
{
backColor = RtfColor.Black;
break;
}
case 41:
{
backColor = RtfColor.Red;
break;
}
case 42:
{
backColor = RtfColor.Green;
break;
}
case 43:
{
backColor = RtfColor.Yellow;
break;
}
case 44:
{
backColor = RtfColor.Blue;
break;
}
case 45:
{
backColor = RtfColor.Cyan;
break;
}
case 46:
{
backColor = RtfColor.Magenta;
break;
}
case 47:
{
backColor = RtfColor.White;
break;
}
default:
{
break;
}
} //If it's a foreground color
if(nowcol >= 30 && nowcol <= 37)
{
if(boldFont)
{
foreColor = (RtfColor)nowcol - 22;
}
else
{
foreColor = (RtfColor)nowcol - 30;
}
}
}
} public void InsertTextAsRtf(string text, Font font, RtfColor textColor, RtfColor backColor)
{ StringBuilder rtf = new StringBuilder(); rtf.Append(RTF_HEADER);
rtf.Append(GetFontTable(font));
rtf.Append(GetColorTable(textColor, backColor));
rtf.Append(GetDocumentArea(text, font)); this.SelectionStart = this.Rtf.Length;
this.SelectedRtf = rtf.ToString(); Win32Helper.SendMessage(this.Handle.ToInt32(), Win32Helper.WM_VSCROLL, Win32Helper.SB_BOTTOM, 1);
} private string GetDocumentArea(string text, Font font)
{ StringBuilder doc = new StringBuilder();
doc.Append(RTF_DOCUMENT_PRE);
doc.Append(@"\highlight2");
if (font.Bold)
doc.Append(@"\b");
if (font.Italic)
doc.Append(@"\i");
if (font.Strikeout)
doc.Append(@"\strike"); if (font.Underline)
doc.Append(@"\ul"); doc.Append(@"\f0 "); doc.Append(@"\fs"); //font size
doc.Append((int)Math.Round((2 * font.SizeInPoints))); // Apppend a space before starting actual text (for clarity)
doc.Append(@" "); //escape special characters
text = text.Replace(@"\", @"\\");
text = text.Replace("{", "\\{");
text = text.Replace("}", "\\}"); doc.Append(text.Replace("\n", @"\par ")); //new lines to \par
doc.Append(@"\highlight0 "); if (font.Bold)
doc.Append(@"\b0"); if (font.Italic)
doc.Append(@"\i0"); if (font.Strikeout)
doc.Append(@"\strike0"); if (font.Underline)
doc.Append(@"\ulnone"); doc.Append(@"\f0");
doc.Append(@"\fs20"); doc.Append(RTF_DOCUMENT_POST); return doc.ToString();
} private string GetFontTable(Font font)
{ StringBuilder fontTable = new StringBuilder(); // Append table control string
fontTable.Append(@"{\fonttbl{\f0");
// If the font's family corresponds to an RTF family, append the
// RTF family name, else, append the RTF for unknown font family.
if (rtfFontFamily.Contains(font.FontFamily.Name))
fontTable.Append(rtfFontFamily[font.FontFamily.Name]);
else
fontTable.Append(rtfFontFamily[FF_UNKNOWN]); // \fcharset specifies the character set of a font in the font table.
// 0 is for ANSI.
fontTable.Append(@"\fcharset0 "); // Append the name of the font
fontTable.Append(font.Name); // Close control string
fontTable.Append(@";}}"); return fontTable.ToString();
} private string GetColorTable(RtfColor textColor, RtfColor backColor)
{ StringBuilder colorTable = new StringBuilder(); colorTable.Append(@"{\colortbl ;"); colorTable.Append(rtfColor[textColor]);
colorTable.Append(@";"); colorTable.Append(rtfColor[backColor]);
colorTable.Append(@";}\n");
return colorTable.ToString();
} }//end class
}//end namespace
ANSI 到 UNICODE:
这个转换用函数MultiByteToWideChar()完成代码:
--------------------------------------------------------------------------------
char *ansistr = "Hello";
int a = lstrlenA(ansistr)+1;
BSTR unicodestr = SysAllocStringLen(NULL, 2*a);
MultiByteToWideChar(CP_ACP, 0, ansistr, a, unicodestr, a);
AfxMessageBox(CString(unicodestr), MB_OK, 0); //displays "Hello"
//... when done, free the BSTR
SysFreeString(unicodestr);
--------------------------------------------------------------------------------UNICODE 到 ANSI:UNICODE大多数情况下被OLE函数返回, 像这个代码:
--------------------------------------------------------------------------------
HRESULT SomeOLEFunction(BSTR &bstr)
{
bstr = ::SysAllocString(L"Hello");
return S_OK;
}
--------------------------------------------------------------------------------这个转换用WideCharToMultiByte()函数完成代码:
--------------------------------------------------------------------------------
BSTR unicodestr;
SomeOLEFunction(unicodestr);
int a = SysStringLen(unicodestr)+1;
char *ansistr = new char[a];
WideCharToMultiByte(CP_ACP,
0,
unicodestr,
-1,
ansistr,
a,
NULL,
NULL);
AfxMessageBox(ansistr, MB_OK, 0); // will display "Hello"
//...use the strings, then free their memory:
delete[] ansistr;
SysFreeString(unicodestr);