Скролинг текста (мерцание)

Тема в разделе "WASM.WIN32", создана пользователем rain, 4 июн 2007.

  1. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    Помогите устрaнить мерцание при скролинге текста.
    Что делаю: в оконной процедуре на WM_CREATE создаю поток, в который как параметр идёт хэндл окна
    Код (Text):
    1. DrawTextThread proc lParam:DWORD
    2.    
    3.    
    4.  
    5.     invoke GetDC, lParam
    6.     xchg eax, ebx
    7.     invoke CreateFont, 50, 20, 0, 0, 0, TRUE, TRUE, 0, 0, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, 0
    8.     invoke SelectObject, ebx, eax
    9.     mov edi, eax
    10.     .repeat
    11.         invoke TextOut, ebx, esi, 0, offset szOutText, OutTextLen
    12.         invoke UpdateWindow, lParam
    13.         dec esi
    14.         .if esi ==  -(OutTextLen) * 20
    15.             xor esi, esi
    16.            
    17.         .endif
    18.         invoke Sleep,10  
    19.     .until FALSE
    20.     ret
    21.  
    22. DrawTextThread endp
    при этом происходит характерное мерцание (довольно заметное чтобы на это закрывать глаза), хотелось бы конечно от этого избавиться
    в атаче всё. Если проблема с атачем, то залил вот ещё здесь
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    xp sp1: пустой диалог, текста вообще нет (запускал ехе в аттаче. Не компилил)
     
  3. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    xp sp2 текст видно, мерцание видно. Выход - двойной буффер и блиттинг.
    [+]
    либо фон текста = фону окна, что слегка может сгладить картину.
     
  4. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Замени свою. Уже не
    Код (Text):
    1. OutTextThread proc lParam: DWORD
    2. LOCAL   hDC1:DWORD
    3. LOCAL   hDC2:DWORD
    4.  
    5.     invoke GetDC, [lParam]
    6.     mov [hDC1],eax
    7.    
    8.     invoke  CreateCompatibleDC,eax
    9.     mov [hDC2],eax
    10.     invoke  CreateCompatibleBitmap,[hDC1],5000,150; 5000 - ширина для всего текста ,150 - высота текста (окна)
    11.     invoke  SelectObject,[hDC2],eax
    12.    
    13.    
    14.     invoke CreateFont, 50, 20, 0, 0, FW_BOLD, 0, 0, 0, 0, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, 0
    15.    
    16.     invoke SelectObject, [hDC2], eax
    17.     invoke TextOut, [hDC2], 0, 0, offset szOutText, OutTextLen
    18.  
    19.     xor esi, esi
    20.    
    21.     .repeat
    22.         invoke  BitBlt,[hDC1],0,0,500,150,[hDC2],esi,0,SRCCOPY ;500 - реальная ширина окна,150 - высота текста (окна)
    23.         inc esi
    24.         .if esi ==  -(OutTextLen) * 20
    25.             xor esi, esi
    26.         .endif
    27.         invoke Sleep,5
    28.     .until FALSE
    29.     ret
    30.  
    31. OutTextThread endp
     
  5. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    всем большой-большой сенк
    странно, брякнись плиз на CreateFont, создаётся ли шрифт ?
     
  6. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    да, все создается нормально.
    Где инициализация esi? У меня при входе в функцию потока esi равно 0x400000, так что ждать, пока появится текст, придется долго :)
     
  7. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    А с ресурсами как? Вроде-бы возвращать надо ресурсы:

    1. CreateCompatibleBitmap(), CreateFont() -> DeleteObject()
    2. CreateCompatibleDC() -> DeleteDC()
    3. GetDC() -> ReleaseDC()

    4. Перед ReleaseDC() надо использовать SelectObject(), чтобы вернуть на место старые объекты из HDC. Естественно, старые объекты надо где-то сохранить. Кроме того, для скорости неплохо сделать CreateCompatibleBitmap() один раз и держать хэндл глобально.
     
  8. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    тьфу, обнулить канеш нада перед входом в цикл :] в попыхах пропустил...
    проверьте плиз работает ли у вас (атач или здесь)
    цикл крутится вечно от создания окна до ExitProcessос не в цикле же всё заново открывать и закрывать =\
    всё что повторяется у меня в цикле это:
    Код (Text):
    1.     .repeat
    2.         invoke TextOut, hCompatDC, esi, 0, offset szOutText, OutTextLen
    3.         invoke BitBlt, ebx, 0, 0, 290, 50, hCompatDC, 0, 0, SRCCOPY
    4.         dec esi
    5.         .if esi ==  -(OutTextLen) * 20
    6.             xor esi, esi
    7.            
    8.         .endif
    9.         invoke Sleep,10
    10.     .until FALSE
     
  9. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    думаю регистры надо сохранять согласно конвенции в процедуре потока.
     
  10. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Можно вывести из цикла. Смотри пример.
     
  11. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    S_Alex
    смотрел, спасиба ещё раз ) но это не критично, а свой код всегда роднее
    это ты о чём?
     
  12. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    stdcall
     
  13. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Есть где-то тема на WASMe там говорится что нужно сохранять.
    От себя могу добавить, сам палился и не раз на таких "ПРИКОЛАХ" от M$,
    В Win2000 работает в XP SP1 через раз, а в SP2 ВАЩЕ не рулит.
    Короче (слушай) читай сюда.
    EBX ESI EDI необходимо сохранить такими как при входе в оконную процедуру иначе MD Shell32 or User32 иногда и NTDLL.
    Они любят писать в память через эти регистры а вот если там МУСОРЕЦ то MD.
     
  14. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    статья называется "записки дзенстувющего" кажется, тока причём это к моему коду я так и не понял
    на практике я этого никогда не делал, да и не видел что-бы кто-то это делал в оконной процедуре и проблем никогда с этим не возникало, наверно вот почему. Вот код на который возвращается управление из оконной процедуры в user32:
    Код (Text):
    1. .text:7D9472F5                 call    [ebp+arg_0] <<<---вызов
    2. .text:7D9472F8                 mov     ecx, large fs:18h
    3. .text:7D9472FF                 and     byte ptr [ecx+0FB8h], 0
    4. .text:7D947306                 cmp     [esp+24h+var_20], 0DCBAABCDh
    5. .text:7D94730E                 jnz     loc_7D9708FE
    6. .text:7D947314
    7. .text:7D947314 loc_7D947314:                           ; CODE XREF: IsCharAlphaNumericW+2A7j
    8. .text:7D947314                                         ; IsCharAlphaNumericW+2AFj
    9. .text:7D947314                 add     esp, 8
    10. .text:7D947317                 pop     ebx
    11. .text:7D947318                 pop     edi
    12. .text:7D947319                 pop     esi
    13. .text:7D94731A                 pop     ebp
    14. .text:7D94731B                 retn    14h
    как видно всё что тут делается это обнуляется SafeThunkCall в тэбе(хз где она используется, в в2к этого не делается) и проверяется стек затем регистры восстанавливаются т.е. нигде не используются, тоже можно сказать и про main функции в кторых ещё проще - по возврату сразу вызывается ExitThread и дело с концом
     
  15. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    rain
    Нельзя! Для кого конвенции придуманы? Сегодня на этой системе (см. твой код) это работает (callback'и / stdcall'ы без сохранения регистров) а завтра в Vista II нет (cм. пост #2). И анализ ядра на локальной системе не поможет другим пользователям программы, т.к. правила игры нарушены.
     
  16. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Процедура Thread-а - это CALLBACK.
    CALLBACK требует сохранения EBX, ESI и EDI.
     
  17. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    asmfan
    в посте номер 2, сорец никак ваще не инициализирует esi (я случайно его стёр когда копировал и свой программы в другую для демонстрации проблемы сабжа), так что тут конвенции ваще нипричём.
    да я же тоже говорю что по идее нада, в любом случае это офтоп, на всех системах которые у меня под рукой это можно и не делать (w2k, xp x64 sp1, w2k server sp1). Это я к тому что все мы (или многие по крайней маре) начинали учиться кодить на асме у Iczelion'а, он этого никогда не делал (случайность?), возьмём шаблоны в RadAsm'у там тоже оконные процедура вызывается без сохранения регистров (случайность?), 2 случайности закономерность, у кого есть виста проверьте код, я уверен что и там он работает без ошибок, и ваще я не понимаю о чём мы сейчас спорим? хотите идеала - сохраняйте, хотите не сохраняйте
    я наверн уже раза 2 говрил что этот тред запускается заходит в вечный цикл, и висит в нём до прибития приложения, так что там хоть ваще рет не пиши, от этого ничего не изменится
    Мне кажется тема исчерпана на посте №5