Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Позиционирование элементов, страное поведение при ресайзе. 
:(
    Опции темы
Coocky
Дата 5.7.2006, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Хех. Столкнулся с проблемой.
У меня есть диалог с битмапами на морде.
Диалог имеет свойство resaizing- таскал я его туда-сюда до посинения.
Все было хорошо пока таскал за правый край.
Но стоило потащить за левый...как битмапы стали прыгать smile 
Да, именно прыгать  smile  Такое ощущение, что они идут за окном влево, но лишь на миг,потом кто-то дает им команду, и они возвращаются в исходное положение smile . Короче эффект еще хуже чем от мерцания.
А вот правый край радует сердце. Все Ок и влево и вправо..
Вот примерный код позиционирования битмапов в прорисовке окна.
Код

..................................
  GetClientRect(&rect);

  pDC1.BitBlt(0,0,bitmapinfo2.bmWidth,bitmapinfo2.bmHeight,&memDC2,0,0,SRCCOPY);

  pDC1.StretchBlt(bitmapinfo2.bmWidth,0,rect.Width()-bitmapinfo2.bmWidth-  bitmapinfo4.bmWidth,bitmapinfo2.bmHeight,&memDC3,0,0,bitmapinfo3.bmWidth,bitmapinfo3.bmHeight,SRCCOPY);

  pDC1.BitBlt(rect.right-bitmapinfo4.bmWidth,0,bitmapinfo4.bmWidth,bitmapinfo4.bmHeight,&memDC4,0,0,SRCCOPY);
..............................
 
 dc.BitBlt(0,0,rect.Width(),rect.Height(),&pDC1,0,0,SRCCOPY);

Может поможет кто.. smile  


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
SergeCpp
Дата 6.7.2006, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 5
Всего: 124



Приведите весь код, связанный с bitmapinfo2, bitmapinfo3 и bitmapinfo4

А также memdc2, 3, 4
 
PM MAIL WWW ICQ   Вверх
Coocky
Дата 6.7.2006, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



SergeCpp
Не вижу смысла, но привожу smile 
Код

bmp2.LoadBitmap(IDB_BITMAP17);
bmp3.LoadBitmap(IDB_BITMAP18);
bmp4.LoadBitmap(IDB_BITMAP19);
......................................................
bmp2.GetBitmap(&bitmapinfo2);
bmp3.GetBitmap(&bitmapinfo3);
bmp4.GetBitmap(&bitmapinfo4);
.......................................................
memDC2.CreateCompatibleDC(&dc);
memDC2.SelectObject(&bmp2);
memDC3.CreateCompatibleDC(&dc);
memDC3.SelectObject(&bmp3);
memDC4.CreateCompatibleDC(&dc);


Все smile 
Это все происходит в OnInitDialog smile

Добавлено @ 09:54 
Хех. Это баг похоже от Мелких (никогда не сомневался в своем прфессионализме smile  smile )..
Откройте проводник в Винде (или любое окно).  Таскайте за правый край smile .
Теперь за левый smile . Обратите внимание на поведение флажка в правом верхнем углу smile 
Теперь вопрос- почему это происходит и как же все таки от этого избавится? 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
Dart
Дата 6.7.2006, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 26.6.2006
Где: Саратов, РФ

Репутация: 2
Всего: 2



Цитата(Coocky @  6.7.2006,  09:48 Найти цитируемый пост)
Теперь вопрос- почему это происходит и как же все таки от этого избавится? 

Переписать OnSize в CWnd smile  smile 
А если серьезно, то проблема эта происходит по-моему от того, что в стандарте мелкомягкие, похоже, не утруждают себя стиранием бэкграунда перед рисованием при ресайзе. По-моему, так.
Если я прав, тогда достаточно переопределить OnEraseBkgnd в твоем классе и ручками стирать бэкграунд под всеми битмапами перед вызовом OnSize родителя. Правда, при этом эта зараза может начать мерцать, но как ты заметил,
Цитата(Coocky @  5.7.2006,  17:01 Найти цитируемый пост)
эффект еще хуже чем от мерцания

это все таки лучше, чем прыгание 
--------------------
ЦитатаЛюблю смотреть, как другие работают
 Дж. К. ДжеромСайт: www.ecosigma.ruПочта: [email protected] 
PM MAIL WWW ICQ   Вверх
SergeCpp
Дата 6.7.2006, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 5
Всего: 124



Рисуйте на контексте памяти, стирая bitmap в нём при изменении размеров и копируйте в контекст устройства целиком — мерцания не будет.
Правда, размер контекста памяти (и bitmap в нём) придётся выбирать с запасом — по максимальному размеру Вашего окна. 

Вот примерчик... Смотрите файл Interface\LifeView.cpp, BOOL LifeView::OnEraseBkgnd( CDC* ) и далее...

Запустите ту программу и поменяйте размер окна — примерчик в действии... 

Это сообщение отредактировал(а) SergeCpp - 6.7.2006, 11:32

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  Life.rar 97,29 Kb
PM MAIL WWW ICQ   Вверх
Coocky
Дата 6.7.2006, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



SergeCpp
Dart
http://forum.vingrad.ru/index.php?showtopic=99226
 smile 
Или я что-то не так понял? smile 
Да помоему из кода видно
Код

  GetClientRect(&rect);

  pDC1.BitBlt(0,0,bitmapinfo2.bmWidth,bitmapinfo2.bmHeight,&memDC2,0,0,SRCCOPY);

  pDC1.StretchBlt(bitmapinfo2.bmWidth,0,rect.Width()-bitmapinfo2.bmWidth-  bitmapinfo4.bmWidth,bitmapinfo2.bmHeight,&memDC3,0,0,bitmapinfo3.bmWidth,bitmapinfo3.bmHeight,SRCCOPY);

  pDC1.BitBlt(rect.right-bitmapinfo4.bmWidth,0,bitmapinfo4.bmWidth,bitmapinfo4.bmHeight,&memDC4,0,0,SRCCOPY);
..............................
 
 dc.BitBlt(0,0,rect.Width(),rect.Height(),&pDC1,0,0,SRCCOPY);

Что рисую я на контексте памяти

Цитата(Dart @  6.7.2006,  11:16 Найти цитируемый пост)
А если серьезно, то проблема эта происходит по-моему от того, что в стандарте мелкомягкие, похоже, не утруждают себя стиранием бэкграунда перед рисованием при ресайзе. По-моему, так.


Цитата(SergeCpp @  6.7.2006,  11:21 Найти цитируемый пост)
Рисуйте на контексте памяти, стирая bitmap в нём при изменении размеров и копируйте в контекст устройства целиком — мерцания не будет.
Правда, размер контекста памяти (и bitmap в нём) придётся выбирать с запасом — по максимальному размеру Вашего окна. 


Цитата(Coocky @  5.7.2006,  17:01 Найти цитируемый пост)
Все было хорошо пока таскал за правый край.


Цитата(Coocky @  5.7.2006,  17:01 Найти цитируемый пост)
Но стоило потащить за левый...как битмапы стали прыгать 


Цитата(Coocky @  6.7.2006,  09:48 Найти цитируемый пост)
Откройте проводник в Винде (или любое окно).  Таскайте за правый край


Цитата(Coocky @  6.7.2006,  09:48 Найти цитируемый пост)
Теперь за левый  . Обратите внимание на поведение флажка в правом верхнем углу 

 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
SergeCpp
Дата 6.7.2006, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 5
Всего: 124



OnEraseBkgnd у Вас переопределена? 
PM MAIL WWW ICQ   Вверх
vvpC
Дата 6.7.2006, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 68
Регистрация: 20.5.2006
Где: Москва

Репутация: нет
Всего: нет



Можно запретить прорисовку в процессе ресайзинга настройкой винды.

А можно и програмно - повесив флаг в начале ресайзинга(WM_SIZING) контролировать его в WM_SIZE, если TRUE -перерисовывать по минимуму или вообще ничего не рисовать. Конец ресайзинга контролировать в WM_NCHITTEST, висит флаг - полная перерисовка и снятие флага  

Это сообщение отредактировал(а) vvpC - 6.7.2006, 12:18
PM MAIL WWW   Вверх
Dart
Дата 6.7.2006, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 26.6.2006
Где: Саратов, РФ

Репутация: 2
Всего: 2



Цитата(Coocky @  6.7.2006,  11:55 Найти цитируемый пост)
Что рисую я на контексте памяти

Да, но перед этим рисованием занимается стандартный обработчик Windows. А он-то похоже сначала сдвидает всё окно в новые координаты, а только потом отдает обработку в OnPaint
Я-то как раз про это говорил. 
--------------------
ЦитатаЛюблю смотреть, как другие работают
 Дж. К. ДжеромСайт: www.ecosigma.ruПочта: [email protected] 
PM MAIL WWW ICQ   Вверх
Coocky
Дата 6.7.2006, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(SergeCpp @  6.7.2006,  11:58 Найти цитируемый пост)
OnEraseBkgnd у Вас переопределена?

Ну это как отче наш.. smile 
Ребята, поймите -у меня НЕТ мигания . У меня "прыганье кнопок". Т.е вроде как отрисовываются с одними координатами, а потом сразу же отрисовываются с другими smile 
vvpC
Dart
насколько я понял нажно поставить флаг разрешения моей отрисовки FALSE  в обработчике MyDlg::OnSize() ПЕРЕД CDialog::OnSize и TRUE ПОСЛЕ него сразу? 


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
takedo
Дата 6.7.2006, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



так то понять не могу как за левый - ок, а за правый - нет, но попробуй для ясности не рисовать битмап, а поставь dc.Rectangle, и по трасе смотри координаты. Если координаты реально прыгают - тогда пока хз, а если нет - то тоже хз, но все таки понятней будет.
PS.: а микрософт конечно имеет косяки, но все на них валить не стоит. А при передвигании проводника я ничего подозрительного с флагом не заметил smile  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
vvpC
Дата 6.7.2006, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 68
Регистрация: 20.5.2006
Где: Москва

Репутация: нет
Всего: нет



Цитата(Coocky @  6.7.2006,  12:46 Найти цитируемый пост)
насколько я понял нажно поставить флаг разрешения моей отрисовки FALSE  в обработчике MyDlg::OnSize() ПЕРЕД CDialog::OnSize и TRUE ПОСЛЕ него сразу?  
 Вот мои обработчики изменяющие состояние флага, но у меня несколько другой случай - я перепозиционирую контролы, а не просто рисую битмапы в нужном месте. Поэтому я проверяю флаг в OnSize, а тебе похоже это надо делать в OnPaint(). Но идея думаю понятна - исключить рисование не слишком важных(или громоздких) элементов в процессе изменения размеров окна.
Код

void CCalculatorDlg::OnSizing(UINT fwSide, LPRECT pRect)
{
    m_SizingFlag=TRUE;
    CDialog::OnSizing(fwSide, pRect);
}

UINT CCalculatorDlg::OnNcHitTest(CPoint point)
{
    if(m_SizingFlag)
    {
        m_SizingFlag=FALSE;
        Invalidate();
    }
    return CDialog::OnNcHitTest(point);
}


  

Это сообщение отредактировал(а) vvpC - 6.7.2006, 13:17
PM MAIL WWW   Вверх
takedo
Дата 6.7.2006, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Coocky, да, проводник с флагом ведет себя именно так как ты и говорил. И это косяк микрософт (****). Получается видимо вот что: при резицинге приходит новый прямоугольник, они ему MoveWindow, а в этот момент довыполняется код OnPaint но со старыми координатами прямоугольника. Попробуй(я конечно не уверен, но могу предполагать) перехватить на родителе в PreTranslateMessage сообщение WM_Paint и посылай его по SendMessage - у нее приоритет выше PostMessage, что делает Invalidate().

Модератор: просьба не аппелировать к национальности, расе и т.д.   

Это сообщение отредактировал(а) Earnest - 6.7.2006, 14:22


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
takedo
Дата 6.7.2006, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



подумал ещё и понял, что так как я предложил неполучится. А не получится потому, что в PreTranslateMessage приходит уже сообщение из очереди(WM_PAINT из очереди асинхронных сообщений). Я предполагаю, что WM_SIZE посылается синхронно, то есть выполнение WM_PAINT в это время прерывается и продолжается дальше при новых размерах окна, но со старыми параметрами.
Делать надо видимо так: 
1)ловить начало и конец резицинга как советовал vvpC
2)в PreTranslateMessage ловить WM_SIZE и посылать WM_SIZE+WM_PAINT(но для всех необходимых контролов подряд, неудобно, но другого я не придумал) синхронно; также надо ловить и WM_PAINT, который игнорировать в случае, когда идет резицинг.
3)по окончанию резицинга надо бы очистить очередь с WM_PAINT - как это сделать не знаю(надо Рихтера почитать), а возможно будет достаточно для очистки послать всем окнам WM_PAINT?

Думаю, что суть проблемы мне удалось ухватить smile , если это так, то решение должно со временем прийти(если моё кривое smile ).
напиши когда поборешь, плз.

Добавлено @ 17:20 
Earnest, так я просто немного зол на программистов микрософт за входящую очередь в com порте при асинхронной передаче, там также рассинхронизация действий!!! Пришлось самому писать свою очередь rx!!! Оно мне очень надо? smile  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
Coocky
Дата 7.7.2006, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Ничего не выходит  smile  


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1035 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.