2012-02-20 3 views
3

У меня есть элемент управления EDIT создан так:Win32 API: как автоматически прокручивать текст внутри элемента управления EDIT?

hwndEDIT_5 = CreateWindowEx (
    0, "EDIT", NULL, 
    WS_VSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY, 
    135, 450, 555, 200, 
    h2, (HMENU) ID_EDIT_CONSOLE, 
    h1, NULL 
); 

Как вы можете видеть, что это только для чтения области редактирования, где можно отобразить мульти строки текста. Предполагается, что это консоль, где я могу отображать некоторую информацию для пользователей, когда они используют программу. Я бы хотел, чтобы текстовая область автоматически прокручивалась до самой нижней записи (самой новой) всякий раз, когда добавляется новая строка (или сообщение для пользователя). Я реализовал это:

SetDlgItemText (h2, ID_EDIT_CONSOLE, ch_s); 
SCROLLINFO scr; 
SCROLLINFO * scr_p = &scr; 
scr.cbSize = sizeof (SCROLLINFO); 
scr.fMask = SIF_RANGE; 
GetScrollInfo (GetDlgItem (h2, ID_EDIT_CONSOLE), SB_VERT, scr_p); 
int mmax = scr.nMax; 
scr.fMask = SIF_POS; 
scr.nPos = mmax; 
SetScrollInfo (GetDlgItem (h2, ID_EDIT_CONSOLE), SB_VERT, scr_p, TRUE); 

Этот код является прокрутки вертикальной полосы прокрутки в конце элемента управления EDIT после добавления нового Сообщ и он прекрасно работает, то полоса прокрутки получает прокручивается, но текст все еще остается видимым с самого начала - это перематывается в начале после добавления, в то время как полоса прокрутки перематывается вниз. Как это сделать правильно?

И последнее, но не в последнюю очередь - это может быть важным - для того, чтобы отобразить сообщение, во-первых, я захватить текст, который уже отображается с помощью: GetDlgItemText (h2, ID_EDIT_CONSOLE, ЬиЕ, LEN + 1); Затем я конвертирую buf в строку и добавляю к этой строке новое сообщение, которое я хочу отобразить. Затем я конвертирую его обратно в массив char и настроил его с помощью SetDlgItemText. Я разделяю строки, используя \ r \ n. Я закодировал это так, потому что я не знал, как добавить строку в элемент управления EDIT по-разному, чем с помощью SetDlgItemText. И он добавляет только одну запись AFAIK - если использовать дважды, я не буду придумывать две записи, добавленные в элемент управления EDIT, но первая будет заменена вторым вызовом функции.

ответ

2

Вы можете добавить текст, установив начало и конец выделения в конце текста в элементе управления (EM_SETSEL), то замена (пустой) выбор с новым текстом (EM_REPLACESEL).

Прокрутка вниз может быть выполнена с помощью EM_SCROLLCARET после того, как каретка (выделение) находится в конце текста. Есть и другие способы, но если вы делаете это сразу после добавления текста, это, вероятно, самый простой.

+0

Я попытался сделать это, и результат в том, что он продолжает мигать доверху, а затем снова вниз .. не очень – Marenz

5

Не используйте SetScrollInfo. Используйте SendMessage() с сообщением EM_LINESCROLL, отправив сообщение в дескриптор окна управления редактированием.

SendMessage(MemoHwnd, EM_LINESCROLL, 0, NumLinesToScroll); 

В документации сказано:

управления не прокручивается вертикально мимо последней строки текста в элементе управления редактирования. Если текущая строка плюс количество строк, заданных параметром lParam, превышает общее количество строк в элементе управления редактирования, значение настраивается так, чтобы последняя строка элемента управления редактирования прокручивалась в верхней части окна редактирования.

6

У меня была такая же проблема и она была решена с ответом Джерри Коффина и некоторыми исследованиями. Это способ, которым я пользуюсь сейчас:

string text = "Append this text"; 
SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all 
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos 
SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)(text.c_str())); //append text to current pos and scroll down 

При необходимости: Для прокрутки в конце Edit Control без добавления текста:

SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all. 
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos 
SendMessageA(hEdit, EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos 
0

для проектов MFC вы можете использовать:

mLoggingTextCtl.SendMessage(EM_SETSEL, 0, -1); //Select all. 
mLoggingTextCtl.SendMessage(EM_SETSEL, -1, -1);//Unselect and stay at the end pos 
mLoggingTextCtl.SendMessage(EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos 
Смежные вопросы