Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

"Дышащее" окно

1.8K
17 марта 2005 года
SeregaLBN
62 / / 03.10.2003
Есть диалог. Мне надо сделать чтобы окно 'дышало', т.е. чтобы плавненько, почти незаметно для пользователя, увеличивалось/умньшалось в размерах.
Я то сделал, но этот вариант никуда не годится - всё дёргано и ... некрасиво в общем.
Может кто-то предложит алгоритмик лучше этого:
Код:
#define ID_TIMER_CHANGE_RESPIRE 335

void CDialogWait::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   // ...
   SetTimer(ID_TIMER_CHANGE_RESPIRE, 300, NULL);
}

void CDialogWait::OnTimer(UINT nIDEvent)
{
   switch (nIDEvent) {
   case ID_TIMER_CHANGE_RESPIRE:
      {
         CRect rc; GetWindowRect(&rc);
         static CSize sizeOrig = rc.Size();
         static CSize sizeMax(sizeOrig.cx*130/100, sizeOrig.cy*130/100);
         static BOOL bIncrement = TRUE;
         if (bIncrement) {
            rc.InflateRect(1,1);
            if ((rc.Width() >= sizeMax.cx) || (rc.Height() >= sizeMax.cy)) bIncrement = FALSE;
         } else {
            rc.InflateRect(-1,-1);
            if ((rc.Width() <= sizeOrig.cx) || (rc.Height() <= sizeOrig.cy)) bIncrement = TRUE;
         }
         ::MoveWindow(m_hWnd, rc, TRUE);
      }
      break;
   }
   
   CDialog::OnTimer(nIDEvent);
}
425
17 марта 2005 года
sq_deep
498 / / 18.02.2005
Если приведённый текст действительно такой и не содержит перемещений окон-детей относительно окна CDialogWait, то вам надо после MoveWindow как-то хитро сделать ValidateRgn, чтобы перерисовывалось не всё окно, а только изменённая часть. Это может сильно помочь.
1.8K
17 марта 2005 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by sq_deep
... чтобы перерисовывалось не всё окно, а только изменённая часть


Не в моём случае....
У меня на диалоге размещена HTML страница с анимированной флешкой. И за её перерисовку я, естественно, никак не отвечаю.

425
18 марта 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by SeregaLBN

Не в моём случае....
У меня на диалоге размещена HTML страница с анимированной флешкой. И за её перерисовку я, естественно, никак не отвечаю.

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

Хотя не уверен. Может быть, ваша MoveWindow выдаст Invalidate и на детей, включая и страницу с флешкой, — тогда не знаю, что делать. Прошу прощения.

Но всё равно попробуйте дать ValidateRect хотя бы на область, занимаемую окном html страницы. Это ведь не сложно. Может быть, будет лучше.

368
18 марта 2005 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by SeregaLBN

Можно поменять MoveWindow на

 
Код:
HDWP hdwp = BeginDeferWindowPos(1);

hdwp = DeferWindowPos(hdwp, this->m_hWnd, NULL, rc.left, rc.top,
                                    rc.Width(), rc.Height(),
                                    SWP_NOACTIVATE | SWP_NOZORDER);
EndDeferWindowPos(hdwp);
Но все равно окно дергается. Более похоже на "дышание", если установить время срабатывания таймера в 100, и вместо InflateRect(), менять только rc.right и rc.bottom.
1.8K
19 марта 2005 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by sq_deep
Хотя не уверен. Может быть, ваша MoveWindow выдаст Invalidate и на детей, включая и страницу с флешкой, — тогда не знаю, что делать. Прошу прощения


Именно так. HTML страничка занимает всю клиентскую область диалога... Поэтому я 'повесился' ещё на сообщение WM_SIZE, обработчик которого вызывается после MoveWindow; и в обработчике меняю координаты хтмлки, что и приводит к перерисовки всей её области...

1.8K
19 марта 2005 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by rostyslav
Можно поменять MoveWindow на
 
Код:
BeginDeferWindowPos(...);
DeferWindowPos(...);
EndDeferWindowPos(...);
Но все равно окно дергается...


Вот именно...

Лучшее что мне пока предложили - это:

Цитата:
Тайлер
Код:
#define ID_TIMER_CHANGE_RESPIRE 335

void CDialogWait::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //...
   ::MoveWindow(m_hWnd, rectWin, TRUE);
}

void CDialogWait::OnTimer(UINT nIDEvent)
{
   switch (nIDEvent) {
   case ID_TIMER_CHANGE_RESPIRE:
      {
         CRect rc; GetWindowRect(&rc);
         static CSize sizeOrig = rc.Size();

         static double d = 2;
         static double dd = 0.5;
         d = rc.Width() > sizeOrig.cx ? d-dd : d+dd;
         int intd = (int) d; //Короче округлили d, чтобы менять на целое число - возможно в C это делается иначе =)
         rc.InflateRect(intd, intd);

         ::MoveWindow(m_hWnd, rc, TRUE);
      }
      break;
   }
   
   CDialog::OnTimer(nIDEvent);
}

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог