AnimateWindow

Тема в разделе "WASM.BEGINNERS", создана пользователем Sturgeon, 5 ноя 2006.

  1. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Привет всем!
    У меня снова чайниковский вопрос. Осваиваю функцию AnimateWindow и есть кое-какие вопросы. (Блин, я наверное никогда не перестану задавать вопросы:dntknw:)

    Как я понял из МSDN функция AnimateWindow используется, когда необходимо изобразить анимацию при закрытиии или отображении окна. Из того же MSDN прочитал что при открытии окна для появления анимации вместо ShowWindow необходимо использовать AnimateWindow. Лады, пробуем...

    Был кусок в проге:
    invoke ShowWindow,hWnd, 1
    invoke UpdateWindow,hWnd
    Насколько я понимаю этот код и используется для отображения созданного окна. Так, дальше... меняем ShowWindow на AnimateWindow:

    invoke AnimateWindow,hWnd,1000,AW_CENTER
    invoke UpdateWindow,hWnd

    Получаем...
    Косяк! Окно отбражается сразу, а не так как положено (разворачиваясь из центра)

    Гонял под отладчиком. Оказалось, что окно каким-то неведомым образом отображается раньше, чем выполняется функция AnimateWindow.
    При этом, если AnimateWindow использовать со следующими параметрами, то все происходит как надо

    invoke AnimateWindow,hWnd,1000,AW_BLEND+AW_HIDE
    invoke UpdateWindow,hWnd

    Окно постепенно исчезает.
    Подскажите пожалуйста, как использовать эту функцию, и где я ошибся?
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Чтобы окно не отображалось сразу после создания нужно чтобы в CreateWindowEx не было флага WS_VISIBLE - возможно дело в этом.
     
  3. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Слушай, да, действительно!!
    Все получилось.
    Только опять остались непонятки. Написано же везде, что функция CreateWindowEx служит для создания окна. А для отображения окна на экране используют функцию ShowWindow (или соответственно AnimateWindow)?
     
  4. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Только все равно праблы. Теперь рисунок в окне, который я выводил с помощью BitBlt не отображается:dntknw:. Наверное как-то перестроить порядок вызова функций?
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    CreateWindowEx может создавать окно видимым или невидимым на усмотрение программера, в последнем случае его нужно показывать самому (как раз для AnimateWindow или когда между созданием и показом окна нужно что нибудь настроить).
    А BitBlt надеюсь используешь в WM_PAINT, а не просто после создания окна ?:))
     
  6. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    То есть полчается, что ShowWindow можно и не использовать, если в свойствах окна указывать WS_VISIBLE?
    BitBlt вызываю таким образом:

    Код (Text):
    1. WndProc proc hWin   :DWORD,
    2.              uMsg   :DWORD,
    3.              wParam :DWORD,
    4.              lParam :DWORD
    5. ...............
    6. ...............
    7.     .elseif uMsg == WM_PAINT
    8.         invoke Paint_Proc1,hWin
    9. ...............
    10. ...............
    11. WndProc endp
    12. ...............
    13.  
    14. ...............
    15. Paint_Proc1 proc hWin:DWORD
    16.  
    17.     LOCAL hDC1   :DWORD
    18.     LOCAL hOld1  :DWORD
    19.     LOCAL memDC1 :DWORD
    20.     LOCAL ps1    :PAINTSTRUCT
    21.  
    22.     invoke BeginPaint,hWnd,ADDR ps1
    23.     mov hDC1, eax
    24.  
    25.     invoke CreateCompatibleDC,hDC1
    26.     mov memDC1, eax
    27.    
    28.     invoke SelectObject,memDC1,hBmp1
    29.     mov hOld1, eax
    30.  
    31.     invoke BitBlt,hDC1,50,54,550,175,memDC1,0,0,SRCCOPY
    32.  
    33.     invoke SelectObject,memDC1,hOld1
    34.     invoke DeleteDC,memDC1
    35.  
    36.     invoke EndPaint,hWin,ADDR ps1
    37.  
    38.     ret
    39.  
    40. Paint_Proc1 endp
    Вот, приаттачил асмовский листинг, посмотри, если не сложно. Буду премного благодарен.
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Совершенно точно, но есть случаи (например, DirectDraw окна) когда такой подход уронит прогу :)))
    В коде крамолы не увидел (правда я вместо UpdateWindow предпочитаю InvalidateRect, hWnd, 0, False - может быть в данном случае это поможет), еще тяжелые команды CreateCompatibleDC, SelectObject, DeleteDC стоит размещать в WM_CREATE, WM_DESTROY, но это больше для красоты на работоспособность влиять не должно :)
     
  8. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Y_Mur
    Да. Это помогло. Хотя я бы даже не подумал так сделать.

    За погляд и совет большое спасибо! Хочется научиться писать не просто работающие проги, а правильно и грамотно составленные, чтобы хоть самому не путаться.
    Большое спасибо еще раз!!!
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Раз уж
    то грабли тут такие:
    В WM_CREATE делаем:
    Код (Text):
    1. invoke GetDC, [hwnd]
    2. mov edi, eax            ; edi = временный h_DC
    3. invoke CreateCompatibleDC, eax
    4. mov [h_memDC], eax
    5. invoke ReleaseDC, [hwnd], edi   ; h_DC больше не нужен
    6. invoke BitmapFromResource, [h_proc], ID_BitMap  ; грузим изображение из ресурсов
    7. mov edi, eax            ; edi = временный h_BitMap
    8. invoke SelectObject, [h_memDC], edi ; Это КОПИРОВАНИЕ + ПРЕОБРАЗОВАНИЕ BitMap (потому и медленно)
    9. invoke DeleteObject, eax    ; вытесненный BitMap не понадобится
    10. invoke DeleteObject, edi    ; временный h_BitMap скопирован в memDC и больше не нужен
    Временные Handle можно размещать в регистрах ebx, edi, esi (API их сохраняют)
    [h_memDC] соответсвенно не должен быть в локальной (стековой) переменной
    Теперь BitMap оформленный как контекст можно BitBlt, пока его не убъёт invoke DeleteDC, [h_memDC] в WM_DESTROY