Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Visual C++/MFC/WTL > Позиционирование элементов |
Автор: Coocky 5.7.2006, 17:01 | ||
Хех. Столкнулся с проблемой. У меня есть диалог с битмапами на морде. Диалог имеет свойство resaizing- таскал я его туда-сюда до посинения. Все было хорошо пока таскал за правый край. Но стоило потащить за левый...как битмапы стали прыгать ![]() Да, именно прыгать ![]() ![]() А вот правый край радует сердце. Все Ок и влево и вправо.. Вот примерный код позиционирования битмапов в прорисовке окна.
Может поможет кто.. ![]() |
Автор: SergeCpp 6.7.2006, 07:30 |
Приведите весь код, связанный с bitmapinfo2, bitmapinfo3 и bitmapinfo4 А также memdc2, 3, 4 |
Автор: Coocky 6.7.2006, 09:48 | ||
SergeCpp, Не вижу смысла, но привожу ![]()
Все ![]() Это все происходит в OnInitDialog ![]() Добавлено @ 09:54 Хех. Это баг похоже от Мелких (никогда не сомневался в своем прфессионализме ![]() ![]() Откройте проводник в Винде (или любое окно). Таскайте за правый край ![]() Теперь за левый ![]() ![]() Теперь вопрос- почему это происходит и как же все таки от этого избавится? |
Автор: SergeCpp 6.7.2006, 11:21 |
Рисуйте на контексте памяти, стирая bitmap в нём при изменении размеров и копируйте в контекст устройства целиком — мерцания не будет. Правда, размер контекста памяти (и bitmap в нём) придётся выбирать с запасом — по максимальному размеру Вашего окна. Вот примерчик... Смотрите файл Interface\LifeView.cpp, BOOL LifeView::OnEraseBkgnd( CDC* ) и далее... Запустите ту программу и поменяйте размер окна — примерчик в действии... |
Автор: Coocky 6.7.2006, 11:55 | ||||||||||
SergeCpp, Dart, http://forum.vingrad.ru/index.php?showtopic=99226 ![]() Или я что-то не так понял? ![]() Да помоему из кода видно
Что рисую я на контексте памяти
|
Автор: SergeCpp 6.7.2006, 11:58 |
OnEraseBkgnd у Вас переопределена? |
Автор: vvpC 6.7.2006, 12:16 |
Можно запретить прорисовку в процессе ресайзинга настройкой винды. А можно и програмно - повесив флаг в начале ресайзинга(WM_SIZING) контролировать его в WM_SIZE, если TRUE -перерисовывать по минимуму или вообще ничего не рисовать. Конец ресайзинга контролировать в WM_NCHITTEST, висит флаг - полная перерисовка и снятие флага |
Автор: Dart 6.7.2006, 12:32 |
Да, но перед этим рисованием занимается стандартный обработчик Windows. А он-то похоже сначала сдвидает всё окно в новые координаты, а только потом отдает обработку в OnPaint Я-то как раз про это говорил. |
Автор: Coocky 6.7.2006, 12:46 |
Ну это как отче наш.. ![]() Ребята, поймите -у меня НЕТ мигания . У меня "прыганье кнопок". Т.е вроде как отрисовываются с одними координатами, а потом сразу же отрисовываются с другими ![]() vvpC, Dart, насколько я понял нажно поставить флаг разрешения моей отрисовки FALSE в обработчике MyDlg::OnSize() ПЕРЕД CDialog::OnSize и TRUE ПОСЛЕ него сразу? |
Автор: takedo 6.7.2006, 13:03 |
так то понять не могу как за левый - ок, а за правый - нет, но попробуй для ясности не рисовать битмап, а поставь dc.Rectangle, и по трасе смотри координаты. Если координаты реально прыгают - тогда пока хз, а если нет - то тоже хз, но все таки понятней будет. PS.: а микрософт конечно имеет косяки, но все на них валить не стоит. А при передвигании проводника я ничего подозрительного с флагом не заметил ![]() |
Автор: vvpC 6.7.2006, 13:13 | ||||
|
Автор: takedo 6.7.2006, 13:44 |
Coocky, да, проводник с флагом ведет себя именно так как ты и говорил. И это косяк микрософт (****). Получается видимо вот что: при резицинге приходит новый прямоугольник, они ему MoveWindow, а в этот момент довыполняется код OnPaint но со старыми координатами прямоугольника. Попробуй(я конечно не уверен, но могу предполагать) перехватить на родителе в PreTranslateMessage сообщение WM_Paint и посылай его по SendMessage - у нее приоритет выше PostMessage, что делает Invalidate(). Модератор: просьба не аппелировать к национальности, расе и т.д. |
Автор: takedo 6.7.2006, 17:18 |
подумал ещё и понял, что так как я предложил неполучится. А не получится потому, что в PreTranslateMessage приходит уже сообщение из очереди(WM_PAINT из очереди асинхронных сообщений). Я предполагаю, что WM_SIZE посылается синхронно, то есть выполнение WM_PAINT в это время прерывается и продолжается дальше при новых размерах окна, но со старыми параметрами. Делать надо видимо так: 1)ловить начало и конец резицинга как советовал vvpC, 2)в PreTranslateMessage ловить WM_SIZE и посылать WM_SIZE+WM_PAINT(но для всех необходимых контролов подряд, неудобно, но другого я не придумал) синхронно; также надо ловить и WM_PAINT, который игнорировать в случае, когда идет резицинг. 3)по окончанию резицинга надо бы очистить очередь с WM_PAINT - как это сделать не знаю(надо Рихтера почитать), а возможно будет достаточно для очистки послать всем окнам WM_PAINT? Думаю, что суть проблемы мне удалось ухватить ![]() ![]() напиши когда поборешь, плз. Добавлено @ 17:20 Earnest, так я просто немного зол на программистов микрософт за входящую очередь в com порте при асинхронной передаче, там также рассинхронизация действий!!! Пришлось самому писать свою очередь rx!!! Оно мне очень надо? ![]() |
Автор: Coocky 7.7.2006, 12:03 |
Ничего не выходит ![]() |