Самостоятельный диалог
От: mediv  
Дата: 23.09.06 08:47
Оценка:
Доброго времени суток, Уважаемые.

При нажатии на кнопку вызывается диалог, который должен самостоятельно выполнить функцию.
Эта функция выполняется в том случае, когда диалог отобразиться на экране. Все это я делаю в
фунции диалога OnActivate(...), где отслеживаю параметр nState. Но параллельно с этим
должна работать анимация, за что отвечает класс CAnimateCtrl. В итоге, после отображения
диалога на экране, анимация "стоит на месте" примерно 5 сек, а потом начинает работать.
Если перейти в другую программу и обратно, все повторяется. Пробовал функции открытия и
проигрывания анимации запихнуть в отдельный поток, ничего не помогает.
Подскажите, пожалуйста, как это сделать по-нормальному, чтобы все заработало.

Заранее большое спасибо!
Re: Самостоятельный диалог
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 23.09.06 08:58
Оценка:
Здравствуйте, mediv, Вы писали:

M> Подскажите, пожалуйста, как это сделать по-нормальному, чтобы все заработало.


Если я Вас правильно понял, то нечто подобное реализовано у меня в UpdateIt! на стадии обработки файлов — там и анимация и прогресс-бары. Правда, там это все на property-page'ах делается, но они суть диалоговые окна. "Ключевым" являются методы CBetterPropPage::OnSetActive() и CBetterPropPage::ActivationWatcher().
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий
Re: Самостоятельный диалог
От: febus Германия  
Дата: 23.09.06 09:12
Оценка:
Здравствуйте, mediv

Я бы посоветовал не использовать OnActivate для запуска функции. Если конечно ты явно не хочешь, чтобы твоя функция и анимация выполнялись каждый раз, когда изменится активное окно (например по Alt-Tab)
Запускай сначала анимацию, а потом функцию. Ты же делаешь сейчас, насколько я понял, с точностью до наоборот.
Т.е.
BOOL CYourDialog::OnInitDialog()
{
   m_AnimateCtrl.Open(IDR_YOURVIDEO);
   m_AnimateCtrl.Play(0, (UINT)-1, 1);
  
  //сюда мы попадаем не после окончания видеоролика, а сразу после его запуска.
   YourLongFunction();
}
Re[2]: Самостоятельный диалог
От: mediv  
Дата: 23.09.06 13:01
Оценка:
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

   ...

// Implementation
protected:
      // 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 handlers

void 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();
}


По идее вся анимация должна работать без тормозов, но как оказывается на практике........

Буду рад если появятся еще идеи
Re[2]: Самостоятельный диалог
От: mediv  
Дата: 23.09.06 15:47
Оценка:
Удалено избыточное цитирование. — SchweinDeBurg

Здравствуйте, febus, Вы писали:

F>Здравствуйте, mediv


F>Я бы посоветовал не использовать OnActivate для запуска функции. Если конечно ты явно не хочешь, чтобы твоя функция и анимация выполнялись каждый раз, когда изменится активное окно (например по Alt-Tab)

F>Запускай сначала анимацию, а потом функцию. Ты же делаешь сейчас, насколько я понял, с точностью до наоборот.

Полностью с Вами согласен!!! Сдесь даже необязательно прописывать строку m_AnimateCtrl.Play(0, (UINT)-1, 1); если в ресурсах диалога для нанного элемента установить параметр ACS_AUTOPLAY. Но все равно проблема с тормознутостью воспроизведения остается: как было, при отображении диалога воспроизведение не начиналось сразу, а только после 5 сек, так и сейчас осталась.
Просматривал исходники Win2k... там ребята так же делали, как и в данном Вами примере. Пробовал компилить в Release-версии, таже ерунда.

Может эта тормознутость быть связана с тем, что программе приходиться открывать ресурс?
Re[3]: Самостоятельный диалог
От: febus Германия  
Дата: 23.09.06 20:48
Оценка:
Здравствуйте, mediv, Вы писали:
M>Но все равно проблема с тормознутостью воспроизведения остается: как было, при отображении диалога воспроизведение M>не начиналось сразу, а только после 5 сек, так и сейчас осталась.
M>Может эта тормознутость быть связана с тем, что программе приходиться открывать ресурс?
А вот на этот вопрос Вы можете себе сами ответить и притом лучше меня, пройдя в отладчике строку
m_AnimateCtrl.Open(IDR_YOURVIDEO);

Тогда сразу и увидете, действительно ли вызов Open приводит к 5 секундной задержке.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.