2010-02-05 6 views
2

간단한 간단한 응용 프로그램에서 콘솔과 같은 디스플레이를 시뮬레이트하고자하는 컨트롤이 RichEdit입니다. x 라인의 수 (말하자면, 300)의 버퍼를 가질 수 있고, 라인이 추가 될 때마다 새로운 라인이 임계 값 x을 초과하면 가장 오래된 (맨 위) 라인을 제거하고 싶습니다. 추가 할 때 가장 아래에 자동으로 스크롤하여 최신 라인을 표시하고 싶습니다.Win32 API가있는 콘솔과 같은 RichEdit 컨트롤을 사용하는 방법은 무엇입니까?

나는 성공적으로 SetWindowText을 사용했지만, 매번 텍스트를 모두 바꾸지 않고 끝까지 텍스트를 추가하고 처음부터 텍스트를 제거하는보다 효율적인 방법이있을 것입니다. 이것이 사실입니까, 그렇다면 어떻게해야합니까?

또한 새 텍스트를 추가 할 때 어떻게 자동으로 창 아래로 스크롤 할 수 있습니까?

이것은 C의 Win32 API를 사용하고 있으며 RichEdit의 MFC 버전을 사용하고 있지 않습니다. XP와 Vista의 경우 vanilla Win32 API 만 사용합니다.

답변

3

텍스트를 추가하려면 텍스트의 끝 (EM_SETSEL)을 선택하고 새 텍스트 (EM_REPLACESEL)로 바꾸십시오.

하단으로 스크롤하려면 SB_BOTTOM을 사용하여 WM_VSCROLL을 보낼 수 있습니다.

+1

끝을 얻기 위해'EM_SETSEL'의 시작과 끝 위치로 -1을 사용했습니다. 이 올바른지? 또한'RichEdit' 컨트롤의 첫 번째 줄을 제거하는 첫 번째 줄 바꿈을 어떻게 효율적으로 찾을 수 있습니까? – Sydius

+0

예, 저는 보통 시작점과 끝점으로 -1을 사용합니다. 나는 당신이 EM_FINDTEXT (아마도 "\ r \ n"을 찾을 필요가있을 것이다)가있는 개행 문자를 찾을 수 있어야한다고 생각한다. 물론 확신 할 필요가 있다고 생각한다. –

1

난 당신에게 샘플 클래스 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); 
} 

자신의 클래스를 내장하고 확인!

관련 문제