Помощник
Здравствуйте, гость ( Вход | Регистрация )
|
|
6:03:2008, 13:02
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
нужно выводить циклическую бегущую строку в окне Win32-приложения
|
|
Сообщение
#1
|
|
![]() |
|
|
6:03:2008, 17:01
|
|
Новенький ![]() Группа: Программист Сообщений: 64 Регистрация: 3:06:2006 Пользователь №: 4 574 Специализация: Программирование, анализ, алгоритмы, оптимизация Репутация: 1
|
1. Предположим, что текст строки занесен в переменную MyString
2. На срабатывание таймера пишем Код MyString=Copy(MyString,2,length(MyString)-1)+MyString[1]; если необходимы интервалы между строками, то добавляем в строку пробелы, прежде чем запускать таймер: MyString:=MyString+' '; Сообщение отредактировал Froex - 6:03:2008, 17:02 |
|
Сообщение
#2
|
|
|
|
6:03:2008, 19:29
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
По-моему, так вообще нельзя писать в Win32. Не знаю, что вместо Copy, но вместо length используется strlen() это точно. И что-то я не понимаю, как это должно работать
|
|
Сообщение
#3
|
|
|
|
6:03:2008, 21:29
|
|
Гуру ![]() ![]() ![]() Группа: Достойный программист Сообщений: 301 Регистрация: 3:11:2007 Пользователь №: 13 517 Репутация: 0
|
ну может он на псевдокоде написал
|
|
Сообщение
#4
|
|
|
|
7:03:2008, 12:06
|
|
Новенький ![]() Группа: Программист Сообщений: 64 Регистрация: 3:06:2006 Пользователь №: 4 574 Специализация: Программирование, анализ, алгоритмы, оптимизация Репутация: 1
|
На Си я практически не пишу, поэтому не совсем знаю, какие там команды)))
смысл в том, что первый символ перемещается в конец и все. т.к. в конце строки могут быть пробелы, то получается, что строка как бы бежит в сторону. |
|
Сообщение
#5
|
|
|
|
7:03:2008, 17:35
|
|
Новенький ![]() Группа: Программист Сообщений: 39 Регистрация: 11:11:2007 Пользователь №: 13 626 Специализация: WinAPI C Репутация: 0
|
Код case WM_TIMER:
TextOut(hdc,x,y,"Hello!",6); InvalidateRect(hWnd,GetClientRect(hWnd),TRUE); x++; if(x>=800) x=0; break; Сообщение отредактировал uis99 - 7:03:2008, 17:38 |
|
Сообщение
#6
|
|
|
|
10:03:2008, 00:18
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
ага. пасиба. тока GetClientRect(hwnd, &rect) надо раньше вызывать, т.к. вместо этой функции должна быть передана ссылка на rect.
тока терь у меня появилась другая проблема: Timer. Как реализовать TimerProc и где SetTimer использовать? и как мне прицепить этот hello в конец? (длину строки в пикселях знаю) в общем, я сделала без таймера, тока не знаю, как мне обрубать эту строку при нулевом иксе (у меня она справа налево двигается) и не знаю, как сделать ее циклической Сообщение отредактировал koma - 10:03:2008, 17:13 |
|
Сообщение
#7
|
|
|
|
10:03:2008, 19:01
|
|
Гуру ![]() ![]() ![]() Группа: Достойный программист Сообщений: 301 Регистрация: 3:11:2007 Пользователь №: 13 517 Репутация: 0
|
выше написано: первый символ переводишь в конец строки и печатаешь строку заново.
а таймер - это событие. используй функцию SetTimer и поставь обработчик на WM_TIMER |
|
Сообщение
#8
|
|
|
|
11:03:2008, 15:17
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
Цитата выше написано: первый символ переводишь в конец строки и печатаешь строку заново. в первом случае не понимаю, что делает Copy; а во втором, как я думаю, строка будет выводиться до 800го пикселя по иксу в окне, а потом начинаццо с начала окна. а мне надо, чтобы она всегда бежала, причем справа налево теперь таймер: наскока я понимаю из определения в справке, если в функцию UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ); передавать SetTimer(NULL, [все равно что],100[мс], NULL), то каждые 100 мс у меня будет посылаться сообщение WM_TIMER в WndProc, в обработчике которого код. в функции потока я вызываю SetTimer, значит, каждые 100 мс у меня строка должна двигаться вперед на 1 пиксел. так? тока у меня ничего не происходить вообще код в обработчике: Код void WndProc_OnTimer(HWND hwnd, UINT id) или я с SetTimer'ом че-то не так делаю? 1) если посылать дескриптор окна, то что тогда посылать вторым параметром? 2) если на TimerProc указатель не нулевой, то что в этой процедуре писать?{ HDC hdc=GetDC(hwnd); GetClientRect(hwnd,&rect); TextOut(hdc,xPos,yPos,"Hello!",6);//xPos=yPos=10 первоначально InvalidateRect(hwnd,&rect,TRUE); xPos++; if(xPos>=800) xPos=0; ReleaseDC(hwnd,hdc); } и еще: а смысл этого таймера? мне кажется, можно было это все циклом от х=0 до х=800 сделать, в который добавить какой-нибудь фор для задержки. или я неправильно понимаю все это? и не стирает ли InvalidateRect то, что только что вывел TextOut? |
|
Сообщение
#9
|
|
|
|
11:03:2008, 16:05
|
|
Божественный ![]() ![]() ![]() ![]() ![]() Группа: Модеры Сообщений: 1 200 Регистрация: 17:05:2006 Из: Минск Пользователь №: 4 257 Специализация: .NET Репутация: 27
|
koma
Ты определись - или рисуй в OnTimer, но убери InvalidateRect, или перенеси отрисовку в OnPaint и оставь только InvalidateRect. |
|
Сообщение
#10
|
|
|
|
11:03:2008, 17:22
|
|
Гуру ![]() ![]() ![]() Группа: Достойный программист Сообщений: 301 Регистрация: 3:11:2007 Пользователь №: 13 517 Репутация: 0
|
у меня строка должна двигаться вперед на 1 пиксел на 1 символКод void WndProc_OnTimer(HWND hwnd, UINT id) { HDC hdc=GetDC(hwnd); GetClientRect(hwnd,&rect); TextOut(hdc,xPos,yPos,"Hello!",6);//xPos=yPos=10 первоначально InvalidateRect(hwnd,&rect,TRUE); xPos++; if(xPos>=800) xPos=0; ReleaseDC(hwnd,hdc); } а смысл этого таймера? мне кажется, можно было это все циклом от х=0 до х=800 сделать, в который добавить какой-нибудь фор для задержки. или я неправильно понимаю все это? а смысл в том, что он существует независимо от остальных функций. если бы ты делала это в какой-то функции тем способом, что ты описываешь, то она повисла бы (и наверняка повесила бы все приложение).и не стирает ли InvalidateRect то, что только что вывел TextOut? конечно стирает.
|
|
Сообщение
#11
|
|
|
|
11:03:2008, 18:53
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
Цитата Ты определись - или рисуй в OnTimer, но убери InvalidateRect, или перенеси отрисовку в OnPaint и оставь только InvalidateRect. а. согласна. InvalidateRect же и отсылает в OnPaint этот rect. но в OnTimer'e убираю InvalidateRect - все равно не идет Цитата на 1 символ в случае с TextOut это же пиксел.второй и третий параметры функции: nXStart [in] Specifies the logical x-coordinate of the reference point that the system uses to align the string. nYStart [in] Specifies the logical y-coordinate of the reference point that the system uses to align the string. Цитата если бы ты делала это в какой-то функции тем способом, что ты описываешь, то она повисла бы (и наверняка повесила бы все приложение) почему? (просто я так и делаю: не могу разобраться с таймером, не работает - и все Сообщение отредактировал koma - 11:03:2008, 18:54 |
|
Сообщение
#12
|
|
|
|
12:03:2008, 16:34
|
|
Гуру ![]() ![]() ![]() Группа: Достойный программист Сообщений: 301 Регистрация: 3:11:2007 Пользователь №: 13 517 Репутация: 0
|
в случае с TextOut это же пиксел. нет, это две совершенно разные вещи. просто переноси по символу с начала строки в конец и отображай ее на экране с неизменными координатамипочему? потому чтотаймер выполняется параллельно с другими функциями |
|
Сообщение
#13
|
|
|
|
26:03:2008, 01:05
|
|
Новенький ![]() Группа: Программист Сообщений: 13 Регистрация: 28:04:2007 Пользователь №: 10 536 Репутация: 0
|
в общем, все работает, тока все-таки по-своему сделала - с пикселами и без таймера) при ресайзе, конечно, глючит, но демонстрационно - работает.
всем спасибо) |
|
Сообщение
#14
|
|
![]() |
|
Текстовая версия | Сейчас: 17:05:2008 - 07:48 |