Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];

Вниз

Схема передачи сообщений в VCL компоненте   Найти похожие ветки 

 
Dmk   (2002-08-24 12:50) [0]

Желательно визуальную диаграмму. Адрес подскажите плз.
Можно на примере TForm. Книжек никаких нет.


 
Юрий Зотов   (2002-08-24 16:56) [1]

> книжек никаких нет.

Тогда я тоже не берусь отвечать на этот вопрос. Просто у меня нет столько времени. Обещайте подумать, ладно?


 
Dmk   (2002-08-24 21:41) [2]

Я имел ввиду, что у меня нет книг с желаемой диаграммой. Литературы у меня для изучения хватает, а чтению я отдаю предпочтение. Просто я неправильно задал вопрос.
Как работает компонент я понимаю, и как сообщения передаются тоже. Мне кажется, что я где-то, что-то мог пропустить. Проблема возникает только под Win2k server.
Если вы готовы общаться и не кипятитесь по поводу книг, я могу описать эту проблему.
Я прекрасно понимаю ваше негодование и занятость, но мне казалось:
1. Что кто-то уже составлял такие диаграммы.
2. Он намного опытнее меня.
3. Я допустил ошибку в коде.
4. Хотел проверить себя по искомой схеме.

Я чувствую себя виноватым за поставленный вопрос, но надеюсь кто-нибудь подскажет мне адрес.


 
Dmk   (2002-08-24 21:41) [3]

... или книгу.


 
Dmk   (2002-08-24 21:52) [4]

В дополнение к сказанному.
Я уже два месяца тщетно бьюсь над этой проблемой.


 
Юрий Зотов   (2002-08-25 04:18) [5]

Давайте попробуем, может и получится. В чем проблема?


 
Dmk   (2002-08-25 13:41) [6]

Управление прорисовкой клиентской части окна я передаю своим процедурам. Перекрыты WM_PAINT, WM_ERASEBKGND, WM_MouseMove. т.е. именно по этим сообщениям родитель не получает сообщения.

Проблема именно в WM_MouseMove.

За курсором мыши в ней происходит прорисовка клиентской части формы. Вроде прокрутки Изображения. Вроде все нормально. Ошибок в движении быть не может. Перепроверил раз 10.

Procedure TDrawForm.WMMouseMove(var m: TWMMouseMove);
begin

if LB_Down then
begin
mMovePosX := m.XPos;
mMovePosY := m.YPos;

ofsMouseX := (mDownPosX - mMovePosX);
ofsMouseY := (mDownPosY - mMovePosY);

If (ofsMouseX <> 0) or (ofsMouseY <> 0) then
begin
sPosX := sPosX + ofsMouseX;
sPosY := sPosY + ofsMouseY;

ClipImagePos(sPosX, sPosY);

HorzScrollBar.Position := sPosX;
VertScrollBar.Position := sPosY;

vpDraw(sPosX,sPosY,dtRegionRepaint);

mDownPosX := MouseX;
mDownPosY := MouseY;
end;
end;
end;

В функции прорисовки vpDraw ничего особенного. Простая BitBlt.
Вроде схема проста. Движение мыши - сдвиг изображения.
Но под Win2k server происходит вот что. Сдвигаем изображение
на 20 пикселов вправо и вниз (это к примеру). Курсор мыши вроде резко переместился на заданное положение. Должен быть один сдвиг и одно изменение координат. Но под вышеуказанной системой эта процедура может получить от 1 до 20 сообщений за сдвиг. Происходит медленное перемещение изображения по всем полученным координатам. Даже если отпустить кнопку мыши во время движения.
При разборе класса TForm и всех его предшественников синхронизации со временем я не обнаружил.
Вот такой прикол. Странно, что под win2k Prof такого не происходит. Скорее всего распределение сообщений под server происходит чаще чем в других. А може очередь при выборке из нее сообщения данного типа (WM_MouseMove) не очищается от остальных. Кстати в некоторых программах верстки (QuarkXPress, PageMaker) происходит тот же самый эффект на той же системе.


Вроде все описал. Благодарен за внимание.


 
Игорь Шевченко   (2002-08-26 11:21) [7]

А зачем рисовать в событии MouseMove ? Может, вместо vpDraw просто сказать invalidateRect (или InvalidateRgn) ???


 
Dmk   (2002-08-26 22:38) [8]

vpDraw рисует на внутреннем контексте формы. Там где все контролы рисуются при прокрутке. Просто скроллинг TForm я отключил. У меня свой InvalidateRect, т.к. вся прорисовка формы и ее содержимого реализуется собственными процедурами.


 
Юрий Зотов   (2002-08-26 23:23) [9]

Да, ситуация непонятная. Попытался в MSDN найти какие-то особенности 2k server, и, конечно, не нашел. А в VCL синхронизации со временем нет, там "поступило - выбрали - обработали".

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

Таким образом, программа сможет реагировать лишь на последнее из серии WM_MOUSEMOVE, исключая промежуточные перерисовки. Не очень ясно, конечно, что считать "серией" (возможно, алгоритм принятия решения "обрабатывать или нет" придется усложнить), но попробовать, IMHO, стоит.


 
Dmk   (2002-08-27 01:34) [10]

Спасибо Юрий. Действительно как я и ожидал очередь не полностью очищается от сообщений MouseMove. При начале движения возникает от 1 до 3 лишних сообщений даже под w2k prof. Просто при высокой скорости прорисовки лишние 1-3 BitBlt не так заметны как например 20. С помощью GetQueueStatus удается отсечь лишние. Завтра попробую на работе на Server"e.
Придется наверно еще и дома поставить. О результатах (если интересуют) обязательно сообщу.


 
Dmk   (2002-08-27 01:38) [11]

Складывается впечатление, что под w2k server идет более интенсивный поток сообщений :|
Хотя может я что-нибудь и недопонял.


 
Dmk   (2002-08-28 00:05) [12]

Ну и прикол! Ничего не понимаю. Поставил дома Server - все в порядке. Что за дребедень?!?


 
Юрий Зотов   (2002-08-28 00:17) [13]

А нет ли различий в установках флажка "показывать окно при перетаскивании"? Может, при установке/снятии этого флажка механизм посылки/прохождения сообщений как-то меняется?


 
Dmk   (2002-08-28 03:17) [14]

От этого флажка прорисовка никак не зависит.
Нашел еще одну "утечку" Messages.
-> HorzScrollBar.Position := sPosX;
После передачи Bar"у значения управление передается в WndProc и обратно в мой обработчик WM_MOUSEMOVE. Мне кажется, что если сообщение еще не стерто из переменной MESSAGE, то после этого происходит рекурсионный вызов WM_MOUSEMOVE обработчика до появления в очереди новых MOUSE сообщений. При этом переменные
mDownPosX := MouseX;
mDownPosY := MouseY;
стоящие после изменения позиции скролл-баров не получают новые значения координат мыши(они записываются в переменные класса при входе в процедуру)! Отсчет движения идет от старых. Поэтому наверно и получается эффект тянущегося хвоста изображений. Но происходить это может только в случае быстрого процессора!
На работе P4-2.0 GHz + 1Gb RIMM RAM, а дома PIII550 384DIMM RAM.

УФФ...!!! Надеюсь моя догадка верна хотябы на 51%
Завтра буду пробовать.


 
Dmk   (2002-08-28 03:24) [15]

Извиняюсь за "рекурсионный". Следует читать "рекурсивный".


 
Dmk   (2002-09-02 23:13) [16]

УРАААААААААААА! Нашел ГЛЮЧАРУ.
VCL недоделка. Не все на VCL сделать можно. :(
Все из-за передачи управления в WindProc. Как я и описывал выше.
Если напрямую к WinApi обращаться (SetScrollPos), то все в порядке!
Спасибо Юрию Зотову за поддержку.
:)


 
Dmk   (2002-09-02 23:15) [17]

И Игорю Шевченко thx :) (навел на мысль новую)


 
Dmk   (2002-09-03 22:05) [18]

Кстати !!!!!!!!!!!!!! Вниманию Юрия Зотова!
Я нашел в TControlScrollBar синхронизацию со временем!!!!!!!!!
Именно из за нее и был этот глюк. Переписал без синхронизации, все стало нормально.
Работа со временем тут -> procedure TControlScrollBar.ScrollMessage(var Msg: TWMScroll);


 
passing_walker   (2002-09-04 06:23) [19]

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



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.008 c
14-50928
Ketmar
2002-08-21 11:11
2002.09.16
нужен плуг к Миранде...


1-50718
DN
2002-09-02 15:28
2002.09.16
Работа с файлами


4-51032
Alexcool
2002-07-24 17:21
2002.09.16
stdout 128 bytes


1-50807
CrazyAngel
2002-09-02 21:26
2002.09.16
Access to process memory


14-50965
Ренат
2002-08-19 10:45
2002.09.16
А какие автомобили предпочитают программеры?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский