Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Обработка нажатия кнопки и обновление экрана  (Прочитано 11089 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« : 28-02-2011 11:37 » 

Подскажите,пожалуйста, как разрулить стандартную ситуацию.
Visual C++ 6. Используется простой диалог.
При нажатии кнопки выполняются какие-то действия и пока они выполняются надо выдать на экран что-то типа "ЖДИТЕ...Выполняется".

Пыталась использовать
 this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_HIDE); при инициализ.диалога
 this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_SHOW); в обработке события НАЖАТИЕ клавиши.

Но, не получилось. Похоже из-за того, что пока не закончится обработка НАЖАТИЯ клавиши, экран не обновляется.
Подскажите другой способ.
Создать другой поток,в кот. и будет это "ЖДИТЕ"  или как, мб что-то проще?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 28-02-2011 13:05 » 

А чуть конкретней? Каким образом выполняются действия? В цикле?

зы Обычно это происходит из-за того, что сообщения обновления окна "застаиваются" в очереди. Чтобы её "пропихнуть" делается след.:

Код: (C++)
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
     AfxGetApp()->PumpMessage();
}

например в конце цикла.
« Последнее редактирование: 28-02-2011 13:09 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #2 : 28-02-2011 13:45 » 

Джон, я попыталась эту операцию воспроизвести в тестовой задачке:
 стандартный диалог
 кнопка ПРОДОЛЖИТЬ
 эл-т STATIC ЖДИТЕ

BOOL CMyWaitDlg::OnInitDialog()
{
   CDialog::OnInitDialog();
.........
      // TODO: Add extra initialization here
   this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_HIDE); //не видна надпись Ждите (она и не видна)
   
   return TRUE;  // return TRUE  unless you set the focus to a control
}
 
А вот обработка нажатия клавиши:

void CMyWaitDlg::OnBcontinue()
{
this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_SHOW);   // должна стать видной надпись  (не становится)

Sleep(9000);                                           // на такое кол-во времени
this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_HIDE); // потом опять выключаем
}

Но, ничего не получилось. Что не так?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 28-02-2011 20:56 » 

Улыбаюсь

Понимаешь, ты посылаешь сообщение окну, и тут же замораживаешь абсолютно всё. Происходит след.: сообщение "показать" отправлено, но не обрабатывается в течении 9 секунд. как-только "заморозка" выключается, сообщение обрабатывается, надпись показывается на тысячные доли секунды, те на то время, которое нужно чтобы пришло и обработалось сообщение "выключить".
Если честно, то я не совсем понимаю цель данного кода, но, как говорится, если очень хочется, то можно.
Для этого нужно обновить окно, перед тем как усыпить процесс. Для этого существует ф-я UpdateWindow().

Код: (C++)
void CMyWaitDlg::OnBcontinue()
{
       this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_SHOW);   // должна стать видной надпись  (не становится)
       this->UpdateWindow();                           // сразу обновляем окно
       Sleep(9000);                                           // на такое кол-во времени
       this->GetDlgItem(IDC_STATICwait)->ShowWindow(SW_HIDE);      // потом опять выключаем
}

« Последнее редактирование: 28-02-2011 20:58 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 28-02-2011 21:39 » 

Джон, а есть API аналог AfxGetApp()->PumpMessage? а то я что то не впилил что именно оно делает)
или это просто TranslateMessage+DispatchMessage... или как?
« Последнее редактирование: 28-02-2011 21:42 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 28-02-2011 23:55 » 

Да, совершенно верно, она делает именно это:

GetMessage
TranslateMessage
DispatchMessage

Правда в MFC в неё добавлена широко известная и нежно любимая PreTranslateMessage, ну и к тому же она является виртуальной. Те можно переписать на досуге. Ага

Код: (C++)
BOOL AFXAPI AfxInternalPumpMessage()
{
        _AFX_THREAD_STATE *pState = AfxGetThreadState();

        if (!::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL))
        {
#ifdef _DEBUG
                TRACE(traceAppMsg, 1, "CWinThread::PumpMessage - Received WM_QUIT.\n");
                        pState->m_nDisablePumpCount++; // application must die
#endif
                // Note: prevents calling message loop things in 'ExitInstance'
                // will never be decremented
                return FALSE;
        }

#ifdef _DEBUG
  if (pState->m_nDisablePumpCount != 0)
        {
          TRACE(traceAppMsg, 0, "Error: CWinThread::PumpMessage called when not permitted.\n");
          ASSERT(FALSE);
        }
#endif

#ifdef _DEBUG
        _AfxTraceMsg(_T("PumpMessage"), &(pState->m_msgCur));
#endif

  // process this message

        if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur)))
        {
                ::TranslateMessage(&(pState->m_msgCur));
                ::DispatchMessage(&(pState->m_msgCur));
        }
  return TRUE;
}

Стандартно она вызывается в цикле ф-ции Run

Код: (C++)
// main running routine until thread exits
int CWinThread::Run()
{
        ASSERT_VALID(this);
        _AFX_THREAD_STATE* pState = AfxGetThreadState();

        // for tracking the idle time state
        BOOL bIdle = TRUE;
        LONG lIdleCount = 0;

        // acquire and dispatch messages until a WM_QUIT message is received.
        for (;;)
        {
                // phase1: check to see if we can do idle work
                while (bIdle &&
                        !::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
                {
                        // call OnIdle while in bIdle state
                        if (!OnIdle(lIdleCount++))
                                bIdle = FALSE; // assume "no idle" state
                }

                // phase2: pump messages while available
                do
                {
                        // pump message, but quit on WM_QUIT
                        if (!PumpMessage())
                                return ExitInstance();

                        // reset "no idle" state after pumping "normal" message
                        //if (IsIdleMessage(&m_msgCur))
                        if (IsIdleMessage(&(pState->m_msgCur)))
                        {
                                bIdle = TRUE;
                                lIdleCount = 0;
                        }

                } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
        }
}

Но может быть использована и для принудительного освобождения очереди сообщений.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #6 : 01-03-2011 05:51 » 

Джон, спасибо.
В тестовой программке смысла нет никакого. В голову просто не пришло, кроме Sleep, чтобы изобразить, что прибор проверяется 3-5 минут , а в это время надо выдать сообщение на экран ЖДИТЕ.
Вообще-то в этот промежуток работает PROGRESS, но мой начальник решил, что этого мало.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 01-03-2011 22:36 » 

ann_nef, тогда в реальном случае вместо UpdateWindow лучше использовать:

Код: (C++)
        MSG msg;
        while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
                 AfxGetApp()->PumpMessage();
        }

Это гарантирует обработку всех пришедших за время "застоя" сообщений.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines