При нажатии на кнопку вызывается диалог, который должен самостоятельно выполнить функцию.
Эта функция выполняется в том случае, когда диалог отобразиться на экране. Все это я делаю в
фунции диалога OnActivate(...), где отслеживаю параметр nState. Но параллельно с этим
должна работать анимация, за что отвечает класс CAnimateCtrl. В итоге, после отображения
диалога на экране, анимация "стоит на месте" примерно 5 сек, а потом начинает работать.
Если перейти в другую программу и обратно, все повторяется. Пробовал функции открытия и
проигрывания анимации запихнуть в отдельный поток, ничего не помогает.
Подскажите, пожалуйста, как это сделать по-нормальному, чтобы все заработало.
Здравствуйте, mediv, Вы писали:
M> Подскажите, пожалуйста, как это сделать по-нормальному, чтобы все заработало.
Если я Вас правильно понял, то нечто подобное реализовано у меня в UpdateIt! на стадии обработки файлов — там и анимация и прогресс-бары. Правда, там это все на property-page'ах делается, но они суть диалоговые окна. "Ключевым" являются методы CBetterPropPage::OnSetActive() и CBetterPropPage::ActivationWatcher().
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
Я бы посоветовал не использовать OnActivate для запуска функции. Если конечно ты явно не хочешь, чтобы твоя функция и анимация выполнялись каждый раз, когда изменится активное окно (например по Alt-Tab)
Запускай сначала анимацию, а потом функцию. Ты же делаешь сейчас, насколько я понял, с точностью до наоборот.
Т.е.
BOOL CYourDialog::OnInitDialog()
{
m_AnimateCtrl.Open(IDR_YOURVIDEO);
m_AnimateCtrl.Play(0, (UINT)-1, 1);
//сюда мы попадаем не после окончания видеоролика, а сразу после его запуска.
YourLongFunction();
}
SDB>Если я Вас правильно понял, то нечто подобное реализовано у меня в UpdateIt! на стадии обработки файлов — там и анимация и прогресс-бары. Правда, там это все на property-page'ах делается, но они суть диалоговые окна. "Ключевым" являются методы CBetterPropPage::OnSetActive() и CBetterPropPage::ActivationWatcher().
Метод, о котором Вы написали, приминим в большей степени для страниц свойств. С "диалогами", как мне кажется, все по-другому.
Для наглядности и более полного восприятия привиду свой код (на недостатки внимание прошу не обращать, ведь этот код только для
выявления причины):
Объявление класса диалога:
class CMyDlg : public CDialog
{
...
// Dialog Data
//{{AFX_DATA(CSearchBluetoothDlg)enum { IDD = IDD_MY_DIALOG };
CAnimateCtrl m_AnimateCtrl;
//}}AFX_DATA
...
// Implementationprotected:
// Generated message map functions
//{{AFX_MSG(CMyDlg)virtual void OnCancel();
//}}AFX_MSG
afx_msg void OnActivate(UINT, CWnd*, BOOL);
DECLARE_MESSAGE_MAP()
// Эта переменная нужна ждя того, чтобы функция поиска вызывалась
// только один раз за время существования окна
BOOL m_bRunSearch;
void OnMyBeginEnd(WPARAM, LPARAM);
void SearchDevice();
};
Реализация:
static const UINT WM_MYBEGINEND = RegisterWindowMessage("IDD_MY_DIALOG");
HANDLE g_hThread;
DWORD __stdcall ThreadProc(LPVOID pVoid)
{
const HWND hWnd = reinterpret_cast<HWND> (pVoid);
if (IsWindow(hWnd)) SendMessage(hWnd, WM_MYBEGINEND, TRUE, 0);
return 0L;
}
/////////////////////////////////////////////////////////////////////////////
// CSearchBluetoothDlg dialog
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_bRunSearch = FALSE; // поиск не производился
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ACTIVATE, OnActivate)
ON_REGISTERED_MESSAGE(WM_MYBEGINEND, OnMyBeginEnd)
END_MESSAGE_MAP()
// В этом потоке запускается открытие и проигрывание avi-ресурса.
// НО НАЧИНАЯ С МОМЕНТА ПОЯВЛЕНИЯ ОКНА И НАЧАЛОМ АНИМАЦИИ
// ПРОХОДИТ 5 СЕКУНДvoid CMyDlg::OnMyBeginEnd(WPARAM wParam, LPARAM lParam)
{
if ((BOOL) wParam)
{
m_AnimateCtrl.Open(IDR_SEARCH);
m_AnimateCtrl.Play(0, -1, -1);
TRACE0("****** Run\n");
}
}
/////////////////////////////////////////////////////////////////////////////
// CSearchBluetoothDlg message handlersvoid CMyDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
if (nState == WA_ACTIVE && m_bRunSearch == FALSE)
{
m_bRunSearch = TRUE; // больше не запускать
// запускаем поток, который проигрывает avi-ресурс
g_hThread = CreateThread(NULL, 0, ThreadProc,(LPVOID) m_hWnd, 0, 0);
// начинаем поиск устройств
SearchDevice();
}
}
void CMyDlg::OnCancel()
{
m_AnimateCtrl.Stop();
m_AnimateCtrl.Close();
if (g_hThread) CloseHandle(g_hThread);
CDialog::OnCancel();
}
По идее вся анимация должна работать без тормозов, но как оказывается на практике........
Здравствуйте, febus, Вы писали:
F>Здравствуйте, mediv
F>Я бы посоветовал не использовать OnActivate для запуска функции. Если конечно ты явно не хочешь, чтобы твоя функция и анимация выполнялись каждый раз, когда изменится активное окно (например по Alt-Tab) F>Запускай сначала анимацию, а потом функцию. Ты же делаешь сейчас, насколько я понял, с точностью до наоборот.
Полностью с Вами согласен!!! Сдесь даже необязательно прописывать строку m_AnimateCtrl.Play(0, (UINT)-1, 1); если в ресурсах диалога для нанного элемента установить параметр ACS_AUTOPLAY. Но все равно проблема с тормознутостью воспроизведения остается: как было, при отображении диалога воспроизведение не начиналось сразу, а только после 5 сек, так и сейчас осталась.
Просматривал исходники Win2k... там ребята так же делали, как и в данном Вами примере. Пробовал компилить в Release-версии, таже ерунда.
Может эта тормознутость быть связана с тем, что программе приходиться открывать ресурс?
Здравствуйте, mediv, Вы писали: M>Но все равно проблема с тормознутостью воспроизведения остается: как было, при отображении диалога воспроизведение M>не начиналось сразу, а только после 5 сек, так и сейчас осталась. M>Может эта тормознутость быть связана с тем, что программе приходиться открывать ресурс?
А вот на этот вопрос Вы можете себе сами ответить и притом лучше меня, пройдя в отладчике строку
m_AnimateCtrl.Open(IDR_YOURVIDEO);
Тогда сразу и увидете, действительно ли вызов Open приводит к 5 секундной задержке.