4954 / 2418 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
1

Не правильная бегущая строка

12.04.2011, 15:23. Показов 2343. Ответов 7
Метки нет (Все метки)

Здравствуйте Уважаемые товарищи программисты!

Помогите разобраться с такой проблемой.
Сделал проект бегущей строки. Строка состоит из 3-слов, проблема в том что первое слово в начале появляется побуквенно, а остальные 2 по словно. Надо чтобы все слова появлялись побуквенно. Так вот вопрос как это исправить?

Второй вопрос.

Есть ли какие-нить методы которые смогут двигать строку, а то я поствил таймер с интервалом = 1, что бы текст как можно плавней двигался, но как говорил уважаемый MikeSoft , если интервал в таймере поставить 1, то сильно грузится процессор это сразу видно потому как при запуске моей программы немного подтупливает комп.

Проект прилагается.

Заранее благодарен, кто отозвётся
Вложения
Тип файла: rar Line2.rar (565.4 Кб, 59 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.04.2011, 15:23
Ответы с готовыми решениями:

Бегущая строка
Бегущая строка Программа читает записанный в файле текст и выводит его в виде бегущей строки,...

Бегущая строка
Как сделать бегущую строку без мерцания с Canvas и чтобы резало примерно так: Бегущая строка ...

бегущая строка
Помогите пожалуйста что нужно прописать в кнопке чтобы при ее нажатии бегущая строка меняла свой...

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

7
LK
Заблокирован
12.04.2011, 15:47 2
а так
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static char const *Text("void __fastcall TForm1::Timer1Timer(TObject *Sender)");
static unsigned const Len = std::strlen(Text);
static unsigned Pos = 0;
AnsiString x(Text + Pos);
x += AnsiString(Text, Pos);
// Label1->AutoSize = false; // set in Obj inspector
Label1->Caption = x;
++Pos; Pos %= Len;
}
0
4954 / 2418 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
12.04.2011, 16:22  [ТС] 3
Цитата Сообщение от LK Посмотреть сообщение
а так
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static char const *Text("void __fastcall TForm1::Timer1Timer(TObject *Sender)");
static unsigned const Len = std::strlen(Text);
static unsigned Pos = 0;
AnsiString x(Text + Pos);
x += AnsiString(Text, Pos);
// Label1->AutoSize = false; // set in Obj inspector
Label1->Caption = x;
++Pos; Pos %= Len;
}
Притормаживает даже на одной миллисекунде

Добавлено через 11 минут
LK, может как-то там можно в моём проекте перекрутить rect.top, rect.bottom
0
LK
Заблокирован
12.04.2011, 16:22 4
ну на, из закромов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
--- Как сделать бегущую строку ---
 
A: 1. Label1->Caption = "Привет";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "ривет П";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "ивет Пр";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "вет При";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "ет Прив";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "т Приве";
Sleep(10);
Application->ProcessMessages();
Label1->Caption = "Привет";
 
Если будет слишком быстро бежать, надо использовать таймер.
 
2. Если текст имеет внушительные размеры и его необходимо отображать в маленькой области в режиме бегущей строки, то давайте подумаем вместе, что мы можем сделать.
На входе:
1. текст, желательно без символов переводов строк. Содержимое текста может изменяться.
2. прямоугольная область задающая область отображения. Размеры области тоже могут изменяться.
3. Процесс отображения должен оставаться последовательным при изменении текста и размеров области отображения.
 
Как это можно сделать?
Можно в том же потоке:
 
Код:
 
/*
=====   Пример бегущей строки (без Битмапов)=========
Размер отображаемого текст ограничен 255 байтами
Это ограничение делают функции рисования текста(DrawText,TextOut...)
  В качестве места отображения может быть любой TControl
  Но на TLabel'е отображение рваное, лучше всего подходит TPaintBox или TButton или TPanel ....
На форме Form1:
TMemo *Memo1; // Для ввода текста для бегущей строки
TEdit *Edit2; // Для изменения задержки потока
TEdit *Edit3; // Для изменения шага смещения в пикселах
TButton * Button1; //Для запуска бегущей строки и её отображения
Чтобы запустить поток необходимо воспользоваться функцией
// Запуск бегущей строки из Memo на контроле Output.
void CreepingLine(TMemo *Memo, TControl *Output)
*/
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include <ddraw.h>
#pragma link "ddraw.lib"
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
DWORD ThreadID=NULL; //Идентификатор потока рисования
int WSpace=20; //ширина разделителя между концом и началом отображения
                // в пикселах
int dX=1; //Шаг смещения рисунка, может быть и - и +.
int TimeScroll=10; //Таймаут для потока в миллисекундах
bool idScroll=false; //Флажок для завершения потока
struct TParamThread
{
  TControl *ControlOut; //Область отображения
  TMemo *MemoText; //Текст отображения
};
// ---------- Creeping line ----------------
//---------- Поток рисования ------------
DWORD CALLBACK ThreadDraw(void *P)
{
TParamThread *Param=(TParamThread *)P;
//+++ Добавление для синхронизации с обратным ходом развёртки экрана
LPDIRECTDRAW lpDD=NULL; // DirectDraw object
HRESULT ddrval;
ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
if(ddrval !=DD_OK){ if(lpDD)lpDD->Release(); lpDD=NULL; }
if(lpDD)
{
  //Проверим, поддерживает ли видеокарта эту функцию?
  HRESULT hr=lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL);
  if( FAILED( hr ) ){if(lpDD)lpDD->Release(); lpDD=NULL; }
}
//+++
TControl *Output=Param->ControlOut; //Область отображения
TMemo *Memo=Param->MemoText; //Текст отображения
 
TWinControl *Parent=NULL;
if(dynamic_cast<TWinControl *>(Output)==NULL)
     Parent=(TWinControl *)Output->Parent;
 
//Используемые переменные, не все они вообще-то необходимы
int X1=0;
//Приступаем к беганию по кругу
   while(idScroll)
   {
    //Поспим, чтобы дать другим поработать
    //+++ Добавление для синхронизации с развёрткой экрана
    if(ddrval==DD_OK && lpDD)
     lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,NULL);
    else
    //+++
     Sleep(TimeScroll);
    //Получим динамически текст, так как он может измениться
    int LenBuf=Memo->GetTextLen();
    if(LenBuf==0)continue;
    if(LenBuf>255)LenBuf=255;
    char *Buffer = new char[LenBuf+1];
    Memo->GetTextBuf(Buffer,LenBuf+1);
    Buffer[LenBuf]=0; //Закроем строку
    //Отфильтруем переводы строк
    char *ptr=Buffer;
    while(*ptr)
    {
      if(*ptr=='\r'||*ptr=='\n')*ptr=0x20;
      ptr++;
    }
 
    //У Output'а может не быть Handle и постоянного HDC
    //Output это всего лишь обозначение места
    //Поэтому берём HDC того TWinControl'а на котором он лежит
    //Так как окно TWinControl может подвергаться процедуре ReCreate,
    // то будем получать его контекст динамически
    HWND hwnd;
    if(Parent)hwnd=Parent->Handle;
    else hwnd=((TWinControl *)Output)->Handle;
    HDC hdc=GetDC(hwnd);
    //Сохраним контекст
    int sdc=SaveDC(hdc);
    //Получим место на окне где лежит Output, вдруг его сместили :)
    int XP=0;
    int YP=0;
    if(Parent)
    {
     XP=Output->Left;
     YP=Output->Top;
    }
    //Сместим начало координат в области отображения
    ::SetViewportOrgEx(hdc,XP,YP,NULL);
    //Обрежем область чтобы не выйти за рамки
    IntersectClipRect(hdc, 0, 0, Output->Width, Output->Height);
    //Очистим область отображения
    PatBlt(hdc,0,0,Output->Width, Output->Height,WHITENESS);
    //Вычисляем размеры под картинку
    RECT r;
    memset(&r,0,sizeof(RECT));
    ::DrawTextEx(hdc,Buffer,LenBuf,&r,DT_CALCRECT,NULL);
    int wFrom=r.right-r.left; //ширина всего текста
  if(wFrom > 0)
  {
     //В области вывода может оказаться несколько кадров
     //рисуемого текста
     //Рисуем первый кусок
     if(X1 < 0)X1 =X1%(wFrom+WSpace)+wFrom+WSpace;
     if(X1 > wFrom+WSpace)X1 =X1%(wFrom+WSpace);
     int W0=wFrom-X1;
     int wTo=Output->Width;
     if(W0 >wTo)W0=wTo;
     if(W0)
     {
      //Сместим начало координат в области отображения
      r.left=-X1; r.right=r.left+wFrom;
      ::DrawTextEx(hdc,Buffer,LenBuf,&r,0,NULL);
     }
     W0+=WSpace;
     //Дорисовываем цепочку до конца
     while(wTo >W0)
     {
       int W1=wTo-W0;
       if(W1 >wFrom)W1=wFrom;
       if(W1)
       {
         //Сместим начало координат в области отображения
         ::SetViewportOrgEx(hdc,W0,YP,NULL);
         r.left=0; r.right=r.left+wFrom;
         ::DrawTextEx(hdc,Buffer,LenBuf,&r,0,NULL);
         W0+=W1+WSpace;
       }
     }
   }
    delete[] Buffer;
    RestoreDC(hdc,sdc);
    ReleaseDC(hwnd,hdc);
    X1+=dX; //Сдвинемся пиксельно
   }
   //Убираем то что мы для себя временно сделали
   if(lpDD)lpDD->Release();
   //Завершаем поток
   ThreadID=NULL;
   return 0;
}
//------------------------------------------------
// Запуск бегущей строки из Memo на контроле Output.
void CreepingLine(TMemo *Memo, TControl *Output)
{
  //Завершим поток на всякий случай
  idScroll=false;
  while(ThreadID){Application->ProcessMessages();}
  //Запускаем поток
  idScroll=true;
//Параметры для потока
  TParamThread *Param=new TParamThread;
  Param->ControlOut=Output;
  Param->MemoText=Memo;
//Запускаем поток отображения
  HANDLE hThread=::CreateThread(0,0,ThreadDraw,Param,0,&ThreadID);
  ::SetThreadPriority(hThread,THREAD_PRIORITY_NORMAL);
  ::CloseHandle(hThread); //Больше не нужен
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  CreepingLine(Memo1,PaintBox1);
}
//---------------------------------------------------------------------------
//Подтираем за собой
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  idScroll=false;
  while(ThreadID){Application->ProcessMessages();}
}
//---------------------------------------------------------------------------
//Изменяем задержку
void __fastcall TForm1::Edit2Change(TObject *Sender)
{
   int i=atoi(Edit2->Text.c_str());
   if(i <1000)TimeScroll=i;
}
//---------------------------------------------------------------------------
//Изменяем шаг смещения
void __fastcall TForm1::Edit3Change(TObject *Sender)
{
   int i=atoi(Edit3->Text.c_str());
   if(abs(i) <10)dX=i;
}
 
Если поломать голову, то ограничение в 255 байтов можно устранить.
 
Решение предлагаемое в RxLib, основывается на битмапе, и на статическом характере текста. Так как изображение вырисовывается предварительно. Тем более это готовое частное решение проблемы, которое не даёт программисту пространства для манёвра. Программисту же, а не простому пользователю компонентов, необходимо дать возможность понять какими способами можно организовать плавное перемещение изображения, чтобы разработать своё решение своей же проблемы.
 
О предложенных вариантах.
 
1. Вариант на основе битмапов это решение в лоб, таким же путём решили идти и в RxLib.
2. Вариант основанный на динамическом характере самого текста, более практичен, но требует больших усилий от программиста в разработке алгоритма. При этом можно организовать и интересные эффекты.
Достаточно убрать всего лишь одну строку и вставить на её место две строки, как можно получить эффект отражения текста от стенки. Убранная строка помечена //---, добавленные //+++:
 
Код:
...
     //Рисуем первый кусок
     if(X1 < 0)X1 =X1%(wFrom+WSpace)+wFrom+WSpace;
     if(X1 > wFrom+WSpace)X1 =X1%(wFrom+WSpace);
     int W0=wFrom-X1;
     int wTo=Output->Width;
     if(W0 >wTo)W0=wTo;
     if(W0)
     {
      //Сместим начало координат в области отображения
      ::SetViewportOrgEx(hdc,X1,YP,NULL); //+++
      r.left=0; r.right=r.left+wFrom; //+++
      //r.left=-X1; r.right=r.left+wFrom; //---
      ::DrawTextEx(hdc,Buffer,LenBuf,&r,0,NULL);
     }
     W0+=WSpace;
     //Дорисовываем цепочку до конца
...
1
4954 / 2418 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
12.04.2011, 16:30  [ТС] 5
Я просто думаю как я потом к своему проекту подключу текстовый файл и выводить построчно информацию из него в бегущую строку
0
LK
Заблокирован
12.04.2011, 16:35 6
Это к какому варианту относится ? А подключают, традиционно, с помощью LoadFromFile .
0
4954 / 2418 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
12.04.2011, 16:46  [ТС] 7
Цитата Сообщение от LK Посмотреть сообщение
какому варианту относится
К моему, который я выложил первым
0
LK
Заблокирован
12.04.2011, 18:17 8
в первом приближении
C++
1
2
3
TStringList list = new TStringList;
list->LoadFromFile("c:\\Сисман.ру");
String s = list->Strings[0];
еще и удобство получишь при необходимости изменения текста бегущей строки - теперь хоть весь list - в бега . И шо ты гоняешь проц этими String, когда есть гламурненькие AnsiString и UnicodeString .
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.04.2011, 18:17
Помогаю со студенческими работами здесь

Бегущая строка моргает (label)
Хочу сделать бегущую строку. Создаю таймер. И по таймеру двигаю текст в label. Проблема в том что...

Бегущая строка. Нужно выполнить в форме (Form), с кнопками и т.п
40. Бегущая строка Программа читает записанный в файле текст и выводит его в виде бегущей строки,...

Бегущая строка
Привет, подскажите, кто может, как в C++ (на самом деле надо на Perl, но д.б. очень похоже) можно...

Апплет "бегущая строка", найти ошибку, строка не останавливается и бежит по второму кругу
Заранее извиняюсь если не туда написал, суть вопроса: у меня стоит задача написать апплет, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru