бегущая строка

uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

бегущая строка

Post by uniqueman »

Есть строка, которую надо отобразить на диалоге в виде бегущей строки. Символы появляются справа налево. В каком контроле лучше всего это сделать ? Пытался CEdit, да что то не могу найти некоторых фич которые нужны.

Кто нибудь делал подобное? Работаю с MFC

Спасибо
Aden
Уже с Приветом
Posts: 144
Joined: 05 Mar 2001 10:01

Post by Aden »

Kогда-то попадалась ActiveX-компонента, отображающая "навороченную" бегущую строку, но не помню где.
Ну а если уж самопально на коленке, то проще всего наверное использовать onTimer(). Контрол может быть любой, отображающий текст, вот, например, эскиз функциональной части для CStatic (IDC_RUNSTR):

void CMyDlg::OnTimer(UINT nIDEvent)
{
m_runString = myLongString.Right(myLongStringLength - shiftValue);
if ((++shiftValue)==myLongStringLength ) shiftValue = 0;
InvalidateRect(&rectString);
UpdateData(false);
CDialog::OnTimer(nIDEvent);
}

при этом

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
<...skip...>
DDX_Control(pDX, IDC_RUNSTR, m_runStringCtrl);
DDX_Text(pDX, IDC_RUNSTR, m_runString);
<...skip...>
}

BOOL CrunStrDlg::OnInitDialog()
{
<...skip...>
shiftValue = 0;
m_runStringCtrl.GetClientRect(&rectString);
myLongString= CString(" ")+myLongString; // количество пробелов подбирается экспериментально
// (или вычисляется, исходя из размера контрола и размеров шрифта) так,
// чтобы строчка "появлялась" с правой стороны контрола
// ( не получается вставить в сообщение больше одного пробела :? )
myTimerID = SetTimer(1, 100, 0);
<...skip...>
}

Успехов.
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

спасибо. сделал наподобие этого. За контрол взял CRichEdit.

Только вот проблема. Функция обновления вызывается каждые 50 миллисекунд, чтобы скорость строки была приемлимой. Но тогда появляется раздражающее моргание из за частого вызова UpdateData.

Есть ли способ сгладить это моргание ?

Спасбо
User avatar
DenisM
Уже с Приветом
Posts: 1976
Joined: 08 Jun 1999 09:01
Location: SPb -> SFBA -> Beaverton, OR

Post by DenisM »

uniqueman wrote:спасибо. сделал наподобие этого. За контрол взял CRichEdit.

Только вот проблема. Функция обновления вызывается каждые 50 миллисекунд, чтобы скорость строки была приемлимой. Но тогда появляется раздражающее моргание из за частого вызова UpdateData.

Есть ли способ сгладить это моргание ?

Спасбо


Рисуйте в memory bitmap, а потом копируйте на экран нужные куски. Будет без мерцания и scrolling можно сделать плавным, т.е. не дергать текст сразу на символ в сторону, а попиксельно ( за счет немного большей загрузки CPU ). Если не хочется заморачиваться, сделайте ctrlEdit.SetRedraw( FALSE ) до перерисовки и ctrlEdit.SetRedraw( TRUE ); ctrlEdit.Invalidate( NULL ); ctrlEdit.UpdateWindow() после ( писал по памяти, проверьте аргументы методов! )
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

http://www.codeproject.com/staticctrl/t ... print=true

вот здесь нашел что то подобное. DenisM, если несложно, посмотрите сорс. Вы это имели в виду. ? В этом примере все равно мерцает довольно сильно, когда скорость прокрутки где то насередине (ползунок).
User avatar
DenisM
Уже с Приветом
Posts: 1976
Joined: 08 Jun 1999 09:01
Location: SPb -> SFBA -> Beaverton, OR

Post by DenisM »

uniqueman wrote:http://www.codeproject.com/staticctrl/ticker.asp?print=true

вот здесь нашел что то подобное. DenisM, если несложно, посмотрите сорс. Вы это имели в виду. ? В этом примере все равно мерцает довольно сильно, когда скорость прокрутки где то насередине (ползунок).


Ага, я посмотрел, у меня верхний ticker тоже заметно мерцает. Можно попробовать уменьшить мерцание, перенеся CPaintDC к последнему BitBlt в OnPaint(). Вообще для максимизации скорости отрисовки лучше всего в OnPaint() только делать BitBlt из memory bitmap на screen. А всю подготовительную работу ( относительно долгую ) проводить заранее.
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

вот такой еще вопрос.

в качестве контнейнера для строки использую CRichEdit контрол. Мне надо разные части бегущей строки рисовать разным цветом. Как это возможно сделать быстро ? Вроде слышал что CRichEdit позволяет это легко делать, однако не могу найти как :pain1:

Спасибо
User avatar
DenisM
Уже с Приветом
Posts: 1976
Joined: 08 Jun 1999 09:01
Location: SPb -> SFBA -> Beaverton, OR

Post by DenisM »

uniqueman wrote:вот такой еще вопрос.

в качестве контнейнера для строки использую CRichEdit контрол. Мне надо разные части бегущей строки рисовать разным цветом. Как это возможно сделать быстро ? Вроде слышал что CRichEdit позволяет это легко делать, однако не могу найти как :pain1:

Спасибо


Я делал так: создал шаблон в WordPad, где установил все необходимые мне аттрибуты для каждого участка текста. Вместо собственно информативного текста были вставлены метки %1, %2 etc. А потом на runtime просто заменял эти метки на нужный мне текст. То же самое можно сделать с аттрибутами. Ну если очень хочется большого геммороя, можно разобраться в формате RTF ( ~150 страниц описания, см. www.wotsit.org ), генерить его из Ваших данных по мере надобности и запихивать в RichEdit.
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Я делал так: создал шаблон в WordPad, где установил все необходимые мне аттрибуты для каждого участка текста. Вместо собственно информативного текста были вставлены метки %1, %2 etc. А потом на runtime просто заменял эти метки на нужный мне текст. То же самое можно сделать с аттрибутами.


не совсем понял каким образом получается текст разного цвета :pain1:
User avatar
olley
Мистер Привет 2015
Posts: 7606
Joined: 26 Mar 2002 10:01
Location: San Diego

Post by olley »

uniqueman wrote:в качестве контнейнера для строки использую CRichEdit контрол.

Таки решили не использовать битмапы для строки? Зря, зря :) Такой плавности как там, при помощи Rich Edit не достигнуть.

uniqueman wrote: Мне надо разные части бегущей строки рисовать разным цветом. Как это возможно сделать быстро ? Вроде слышал что CRichEdit позволяет это легко делать, однако не могу найти как :pain1:

Так надо быстро или легко? :wink: Я в свое время просто делал selection участка, который надо было выводить нужным цветом а потом менял аттрибуты символов в этом selection

Code: Select all

CHARFORMAT cf;
cf.crTextColor = RGB(255, 0, 0);
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0;
m_RichEdit->SetSelectionCharFormat(cf);
olley
uniqueman
Уже с Приветом
Posts: 2013
Joined: 16 Mar 2002 10:01
Location: New York City

Post by uniqueman »

Таки решили не использовать битмапы для строки? Зря, зря :) Такой плавности как там, при помощи Rich Edit не достигнуть.


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

Так надо быстро или легко? :wink: Я в свое время просто делал selection участка, который надо было выводить нужным цветом а потом менял аттрибуты символов в этом selection

Code: Select all

CHARFORMAT cf;
cf.crTextColor = RGB(255, 0, 0);
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0;
m_RichEdit->SetSelectionCharFormat(cf);


надо без гемора всякого с GDI если можно :wink: Сейчас текст выводится вот так..


// запоминаем пришешие данные..
string sTemp = sHouse + ":" + sData;

// добавляем данные к текущей строке
sTickerString += sTemp;

// если длина текущей строки превышает предел, то вырезаем из текущей строки подстроку, захыватывая последние данные.

if (sTickerString.length() > 150)
{
sTickerString = sTickerString.substr(sTemp.length(), sTickerString.length() - sTemp.length());
}

// выводим на контрол
m_editRichTicker.SetWindowText (sTickerString.c_str());

мне в какой то момент надо делать часть sData либо зеленой либо красной (в зависимости от знака данных). Как это сделать?
User avatar
olley
Мистер Привет 2015
Posts: 7606
Joined: 26 Mar 2002 10:01
Location: San Diego

Post by olley »

uniqueman wrote:мне в какой то момент надо делать часть sData либо зеленой либо красной (в зависимости от знака данных). Как это сделать?

Если объяснять на пальцах, то сделайте так:
1. Сохранить текущее выделение GetSel()
2. Выделить ту часть текста, в которой данные из sData. Используйте для этого SetSel()
3. Изменить цвет выделенного текста - SetSelectionCharFormat()
4. Вернуть выделение к тому виду, каким оно было до шага 2 - SetSel()

Это то, что я могу вспомнить навскидку. Да, чтобы эти выделения не мерцали, сделайте richEdit->SetRedraw(FALSE); до всех операций и richEdit->Invalidate(); - после.

У меня работало и вроде не мерцало :wink: Это был обновляющийся разноцветный лог. Правда я писал в окно через потоки (StreamIn()), а не через SetWindowText(). Но думаю, что для однострочного контрола это не принципиально.
olley

Return to “Вопросы и новости IT”