Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

Анимация в окне на WinApi

Привет всем.

Вопрос такой:

Дано: 1) Файл анимации (в любом удобном формате: GIF, AVI,
последовательность BMP etc.) размерами примерно
10x10 pix, от 10 до 100 кадров, продолжительностью
около 1 с.
2) Окно приложения типа Hello World с меню и фоном
3) чистенький Win API (т.е. без MFC, надстроек Builder,
DirectX etc.)

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

Как лучше всего можно такое сделать?

Ответить   Fri, 19 Mar 2004 13:34:23 +0500 (#106940)

 

Ответы:

Проще всего узать окно класса ANIMATE_CLASS (оконный класс)
далее - пара функций для примера.
Animate_Create, Animate_Play, и.т.д. - макросы, развертываемые
в вызовы CreateWindow.

// CreateAnimationCtrl - creates an animation control, positions it
// below the specified control in a dialog box,
// and opens the AVI clip for the animation control.
// Returns the handle to the animation control.
// hwndDlg - handle to the dialog box.
// nIDCtl - identifier of the control below which the animation
control
// is to be positioned.
//
// Constants
// IDC_ANIMATE - identifier of the animation control.
// CX_FRAME, CY_FRAME - width and height of the frames
// in the AVI clip.

HWND CreateAnimationCtrl(HWND hwndDlg, int nIDCtl)
{
HWND hwndAnim = NULL;
RECT rc;
POINT pt;

// Create the animation control.
hwndAnim = Animate_Create(hwndDlg, IDC_ANIMATE,
WS_BORDER | WS_CHILD, g_hinst);

// Get the screen coordinates of the specified control button.
GetWindowRect(GetDlgItem(hwndDlg, nIDCtl), &rc);

// Convert the coordinates of the lower-left corner to
// client coordinates.
pt.x = rc.left;
pt.y = rc.bottom;
ScreenToClient(hwndDlg, &pt);

// Position the animation control below the Stop button.
SetWindowPos(hwndAnim, 0, pt.x, pt.y + 20,
CX_FRAME, CY_FRAME,
SWP_NOZORDER | SWP_DRAWFRAME);

// Open the AVI clip, and show the animation control.
Animate_Open(hwndAnim, "SEARCH.AVI");
ShowWindow(hwndAnim, SW_SHOW);

return hwndAnim;
}

// DoAnimation - plays, stops, or closes an animation control's
// AVI clip, depending on the value of an action flag.
// hwndAnim - handle to an animation control
// nAction - flag that determines whether to play, stop, or close
// the AVI clip.

void DoAnimation(HWND hwndAnim, int nAction)
{
switch (nAction) {
case PLAYIT:
// Play the clip continuously starting with the
// first frame.
Animate_Play(hwndAnim, 0, -1, -1);
break;

case STOPIT:
Animate_Stop(hwndAnim);
break;

case CLOSEIT:
Animate_Close(hwndAnim);
break;

default:

break;

}

return;
}

--
С уважением, Вахтуров Виктор.
Информационный сайт для программистов http://SoftMaker.com.ru
Номер выпуска : 2646
Возраст листа : 180 (дней)
Количество подписчиков : 377
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/107785
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru

http://subscribe.ru/ mailto:ask@subscribe.ru

Ответить   Sat, 20 Mar 2004 08:00:21 +0300 (#107785)

 

Привет Victor,

Saturday, March 20, 2004, 10:00:21 AM, писали вы:

//Далее - текст примера.

А можно-ли как-нибудь отловить окончаение показа клипа, который вызвал
путем

Animate_Open(hAnim, "Media\\first.avi");
ShowWindow(hAnim, SW_SHOW);
Animate_Play(hAnim, 0, -1, 1);

чтобы потом сделать

Animate_Close(hAnim);

(
причем, желательно, чтобы можно было запустить таким образом сразу
несколько клипов...
Т.е. посылаются-ли какие-либо сообщения, чтоли?...
)

Ответить   Sat, 27 Mar 2004 22:39:09 +0500 (#113355)

 

Окно аниматора шлет 2 командных сообщения (сообщения WM_COMMAND) :
с кодом ACN_START, когда начинает проигрывать клип,
с кодом ACN_STOP, когда заканчивает проигрывать клип.
Собственно, это все. Больше никаких уведомлений он не шлет.

Насчет нескольких клипов - аниматор работает асинхронно.
Можно испоьлзовать несколько окон. Но, учтите - проигрываемые
AVI - файлы должны быт несжатые (full frames кадры там должны быть).
Если охота использовать сжатые AVI, можно использовать окна MCI.

--
С уважением, Вахтуров Виктор.
Информационный сайт для программистов http://SoftMaker.com.ru
Номер выпуска : 2717
Возраст листа : 188 (дней)
Количество подписчиков : 380
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/113510
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru

http://subscribe.ru/ mailto:ask@subscribe.ru

Ответить   Sun, 28 Mar 2004 01:06:59 +0300 (#113510)

 

Привет Victor,

Sunday, March 28, 2004, 4:06:59 AM, писали вы:

Тогда, как я понял, можно отловить сообщение таким образом:

switch(iMsg)
{
case WM_COMMAND :
switch(LOWORD(wParam))
{
case ID_ANIMATE :
if (lParam==ACN_STOP)
{
/* обрабатываем ... */
}
}

Но тогда не получится узнать хендл окна, в котором завершился клип :0(
То есть, если открыто несколько окон анимации, то по очереди их
закрыть не удастся :0((
Можно, конечно, попытаться использвать таймер, но это как-то надуманно
получается...
Можно как-нибудь узнать нендл окна, в котором завершилась анимация,
или как-нибудь по-другому задать, что при завершении анимации требуется
закрыть окно?

Ответить   Mon, 29 Mar 2004 16:11:08 +0600 (#114336)

 

Здравствуйте !

Гм... вроде, узнать дескриптор окна элемента управления, пославшего
командное сообщение - достаточно просто. В коде выше - небольшая ошибочка.
Следовало бы писать :

if (HIWORD(wParam)==ACN_STOP)
{
/* обрабатываем ... */
}

А в lParam - как раз и лежит дескриптор окна контрола (или NULL для случаев
меню или клавиатурных акселераторов, например).
То есть в общем случае (для WM_COMMAND):

UINT nID = LOWORD(wParam);
int nCode = HIWORD(wParam);
HWND hWndCtrl = (HWND)lParam;

--
С уважением, Вахтуров Виктор.
Информационный сайт для программистов http://SoftMaker.com.ru
Номер выпуска : 2745
Возраст листа : 192 (дней)
Количество подписчиков : 382
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/116113
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru

http://subscribe.ru/ mailto:ask@subscribe.ru

Ответить   Thu, 1 Apr 2004 01:20:08 +0400 (#116113)

 

Большое спасибо, все работает. :0)

Только иногда появляется маленькая странность:

Если окношко с анимацией перекрывается до того, как
анимация доигралась до конца, то клип опять переходит на первый кадр,
и начинает проигрываться только через несколько секунд после того, как
становится видимым.

То есть, если открыть последовательно несколько окон с анимацией,
уменьшить окно, а потом восстановить, то все окна с анимацией
оказываются на первом кадре, а потом, секунд через 5, дружно начинают
проигрываться одновременно.

Никто не знает, как можно заставить их проигрываться даже тогда, когда
они не видны?

Ответить   Mon, 5 Apr 2004 19:11:55 +0600 (#118883)