![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: нет Всего: 12 |
Првиет. Рисую на форме с помощю мыши. Если я свора4иваю окно или ресайз, автомтически вызывается WM_PAINT у формы. Понятно форма перерисовывается. Вопрос в том как сохранить нарисованное? Загоняьт в лист или массив а потом в паинт выводить 4то было раньше нарисовано? Как правелно сделать ?
![]() |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
рисовать на совместимом memory DC, а потом копировать через BitBlt когда нужно перерисовать
подсказка чтоб не мучался - неочевидно из документации - совместимый DC надо создавать не к окну, а к экрану - с параметром NULL - CreateCompatibleDC(NULL) и не забудь создать битмап и выбрать его в DC |
|||
|
||||
Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: нет Всего: 12 |
Пока мало 4то понял, хотябы знаю куда теперь копать. Спасибо за ответ .
![]() |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Tony, пример проги:
--------------------
|
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
J0ker, интересно. Пробовал - не получилось.
--------------------
|
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
немного ошибся выше
CreateCompatibleDC(GetDC(NULL));
Это сообщение отредактировал(а) J0ker - 7.12.2008, 00:03 |
|||
|
||||
MenSem |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Это в WM_CREATE ? Переменные static?
Здесь WndDC = BeginPaint(hWnd, &ps) ? Это сообщение отредактировал(а) MenSem - 7.12.2008, 18:22 --------------------
|
||||
|
|||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
где угодно и как угодно memDC - объект существующий на протяжении всей жизни окна ессесна там нужны размеры битмапа - это можно делать по разному - можно сразу создать максимальный битмап, а можно пересоздавать битмап на WM_SIZE, перевыбирать его и перерисовавать на memDC содержимое
|
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 2 Всего: 110 |
судя по документации, надо бы запомнить результат GetDC(NULL) и вызвать для него ReleaseDC -------------------- qqq |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
maxim1000, без учета этого - появляется черный квадрат и рисование мышью не работает, с учетом - квадрата нет, но рисование не работает.
--------------------
|
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
да, совершенно правильно сорри забыл |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 2 Всего: 110 |
тут лучше бы привести код, а то вслепую сложно получается... -------------------- qqq |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
это не черный квадрат - битмап заполнен нулями - черный цвет
перед рисованием нарисуй белый квадрат на весь размер |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
В первом варианте работает Это сообщение отредактировал(а) MenSem - 16.12.2008, 19:55 --------------------
|
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
остальное не смотрел |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Заменил. Теперь белый квадрат есть.
А вот рисование мышью неаботает. --------------------
|
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 2 Всего: 110 |
т.к. все изменения происходят в памяти, нужно их периодически сбрасывать на экран т.е. делать отрисовку содержимого окна (InvalidateRect) ну или все действия в памяти дублировать на экране, но это кривее и без хороших причин (типа производительности), ИМХО, делать не стоит -------------------- qqq |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
делайте InvalidateRect на окно - тогда вызовется WM_PAINT, в котором должен быть BitBlt
|
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Проблема решилась добавлением в код
Большое спасибо. Только я так понимаю что тут не обязательно весь клиент перерисовывать? --------------------
|
|||
|
||||
J0ker |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
необязательно но в данном случае BitBlt очень быстрая и простая операция, поэтому можно перерисовывать все окно если хотите перерисовывать только то, что нужно, то на WM_PAINT надо сначала вызвать GetUpdateRect - если он вернет TRUE, можно воспользоваться квадратом, который он даст, а можно тем, который даст последующий вызов BeginPaint. Если GetUpdateRect вернет FALSE, то ничего делать не надо. так-же рекомендую перехватить WM_ERASEBKGND и просто возвращать TRUE - избежите мерцания при перерисовке, но тогда при обработке WM_PAINT бэкгроунд перерисовывать надо самому. |
||||
|
|||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Перехватил, добавил в WM_PAINT:
При изменении размером мерцание стало меньше. Но появилось мерцание при рисовании. Тогда добавил проверку флага в WM_PAINT и мерцание пропало. Еще одно спасибо за это. --------------------
|
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Замечен глюк "прозрачного фона" при активации . Я так понимаю просто при активации добавить перерисовку фона?
Кстати битмап рисую поцентру, и по этому надо кординаты корректировать. Я кординаты изменяю вручную. Или есть способы получше? --------------------
|
|||
|
||||
J0ker |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
если в memDC у вас полная клиентская зона - то в WM_PAINT не надо заполнять бэкграунд - просто копируете BitBlt и все - в memDC уже все есть
Добавлено через 3 минуты и 47 секунд
на любой WM_PAINT надо отрисовать все, что в инвалидном прямоугольнике
что значит вручную? перерасчитываете при WM_PAINT? другого способа насколько я знаю нет, но не вижу тут никаких проблем |
||||
|
|||||
MenSem |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Я имею в виду кординаты курсора при щелчке и движении.
Нет, битмап только на часть клиента.
Это по ходу потому что влаг после щелчка переходит в значение true. А у меня в WM_PAINT при рисовании мышкой фон заново не заливается... --------------------
|
||||||
|
|||||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
координаты приходят в координатах клиентской области правильная обработка следующая: case WM_LBUTTONDOWN: запомнить координаты в prev_position выставить флаг mouse_lock SetCapture(hWnd); break; case WM_LBUTTONUP: if(!mouse_lock) break; сбросить флаг mouse_lock ReleaseCapture(); break; case WM_MOUSEMOVE: if(!mouse_lock) break; if(координаты == prev_position) break; обработать новые координаты запомнить координаты в prev_position break; |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
J0ker, это и так понятно...
--------------------
|
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
обратите внимание на SetCapture/ReleaseCapture - многие этой фичи не знают
так-же многие не знают, что WM_MOUSEMOVE может генерироваться без реального перемещения мыши и координаты будут одни и те-же - поэтому нужна проверка |
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
И то и другое я знаю.
--------------------
|
|||
|
||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Только вот в моем случае сначало кординаты надо корректировать
--------------------
|
|||
|
||||
J0ker |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: -1 Всего: 14 |
|
||||
|
|||||
MenSem |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 10.7.2008 Репутация: нет Всего: нет |
Я прям америку для себя открыл
![]() Вижу Вы не поняли в чем дело.
--------------------
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |