如何在Win32 API中使用RichEdit控件(如控制台)?
我的简单应用程序中有一个如何在Win32 API中使用RichEdit控件(如控制台)?,c,winapi,richedit,C,Winapi,Richedit,我的简单应用程序中有一个RichEdit控件,我希望用它来模拟类似控制台的显示。我希望能够有一个x行数(比如,300)的缓冲区,并且每当添加一行时,如果新行超过阈值x,我还希望删除最早的(顶部)行。我还想它自动滚动到底部显示最新的行时,添加 我已经成功地使用了SetWindowText,但是我突然想到,可能有一种更有效的方法可以将文本追加到末尾,并从开头删除文本,而不必每次都替换所有文本。这是真的吗?如果是,我该怎么办 另外,当添加新文本时,如何使其自动滚动到窗口底部 这是使用C中的Win32
RichEdit
控件,我希望用它来模拟类似控制台的显示。我希望能够有一个x
行数(比如,300)的缓冲区,并且每当添加一行时,如果新行超过阈值x
,我还希望删除最早的(顶部)行。我还想它自动滚动到底部显示最新的行时,添加
我已经成功地使用了SetWindowText
,但是我突然想到,可能有一种更有效的方法可以将文本追加到末尾,并从开头删除文本,而不必每次都替换所有文本。这是真的吗?如果是,我该怎么办
另外,当添加新文本时,如何使其自动滚动到窗口底部
这是使用C中的Win32 API,我没有使用MFC版本的
RichEdit
(只是在XP和Vista上使用普通的Win32 API)。要添加文本,请将选择设置为文本的结尾(EM_setel),然后用新文本(EM_REPLACESEL)替换选择
要滚动到底部,您可以发送一个WM\u VSCROLL和SB\u bottom。我给您发送了一些示例类的方法
cConsole
:
class cConsole {
private:
//-------------------
int lines;
int max_lines; // Init it with your choise ( 300 )
//-------------------
char* buf;
int buf_size;
//-------------------
int CheckMemory( int size );
void NewLine( int new_lines );
void InternalPrint( char* msg, int size );
public:
HWND hWin;
void Print( char* msg ); // Add text data through this methods
void Print( char* msg, int size );
cConsole( );
~cConsole( );
};
int cConsole::CheckMemory( int size ) {
int rv = 1;
if( size + 16 >= buf_size ) {
int new_buf_size = size + 1024;
char* new_buf = ( char* )realloc( buf, new_buf_size );
if( new_buf != NULL ) {
buf = new_buf;
buf_size = new_buf_size;
} else {
rv = 0;
}
}
return rv;
}
void cConsole::NewLine( int new_lines ) {
int rem_lines = ( new_lines + lines + 1 ) - max_lines;
if( rem_lines <= 0 ) {
lines += new_lines;
} else {
int sel = SendMessage( hWin, EM_LINEINDEX, rem_lines, 0 );
SendMessage( hWin, EM_SETSEL, 0, (LPARAM)sel );
SendMessage( hWin, EM_REPLACESEL, FALSE, (LPARAM)"" );
SendMessage( hWin, WM_VSCROLL, SB_BOTTOM, NULL );
lines = max_lines - 1;
}
}
void cConsole::Print( char* msg ) { InternalPrint( msg, -1 ); }
void cConsole::Print( char* msg, int size ) { if( size < 0 ) size = 0; InternalPrint( msg, size ); }
void cConsole::InternalPrint( char* msg, int size ) {
int s, t = 0;
int new_lines = 0;
char* tb;
// msg only mode
if( size == -1 ) size = 0x7fffffff;
if( msg != NULL && size && CheckMemory( t ) ) {
for( s = 0; msg[ s ] && ( s < size ); s++ ) {
if( msg[ s ] == '\r' ) continue;
if( !CheckMemory( t ) ) break;
if( msg[ s ] == '\n' ) {
++new_lines;
buf[ t++ ] = '\r';
}
buf[ t++ ] = msg[ s ];
}
buf[ t ] = '\0';
}
if( t && msg != NULL ) {
tb = buf;
} else {
++new_lines;
tb = "\r\n";
}
SendMessage( hWin, EM_SETSEL, (WPARAM)-2, (LPARAM)-1 );
SendMessage( hWin, EM_REPLACESEL, FALSE, (LPARAM)tb );
SendMessage( hWin, WM_VSCROLL, SB_BOTTOM, NULL );
if( new_lines ) NewLine( new_lines );
}
类C解决方案{
私人:
//-------------------
内线;
int max_line;//使用您的选项初始化它(300)
//-------------------
char*buf;
int buf_尺寸;
//-------------------
整数校验存储器(整数大小);
无效换行符(int新行);
无效内部打印(字符*消息,整数大小);
公众:
HWND-hWin;
void Print(char*msg);//通过此方法添加文本数据
无效打印(字符*消息,整数大小);
cConsole();
~cConsole();
};
int-cConsole::CheckMemory(int-size){
int-rv=1;
如果(尺寸+16>=基本尺寸){
int new_buf_size=size+1024;
char*new_buf=(char*)realloc(buf,new_buf_size);
如果(新建)=NULL{
buf=新的_buf;
buf_尺寸=新的buf_尺寸;
}否则{
rv=0;
}
}
返回rv;
}
void cConsole::换行符(int新行){
int rem_线=(新_线+线+1)-最大_线;
如果(rem_行我使用-1作为EM_setel
的开始和结束位置,以获得结束。这是否正确?此外,我如何有效地找到第一个换行以删除RichEdit
控件中的第一行?是的,我通常使用-1作为开始和结束点。我相信您应该能够找到一个带有EM\u FINDTEXT的新行(您可能需要查找“\r\n”),不过我想我必须检查一下才能确定。