![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| namervasek |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
Всем привет! Суть проги.... рисую в одном дочернем окне фигуру и пытаюсь перенести эту фигуру в другое дочернее окно путем перетаскивание... Но проблема втом что не знаю как в этом случае рисовать. Тоесть тоскать фигуру внутри окна где она рисуется получается а сделать так что фигура еще могла бы на другие области главного окна перестаскиваться неполучается.
Поскажите плиз как это реализовать. Код того что сделал снизу. Это сообщение отредактировал(а) namervasek - 20.7.2009, 16:17 Присоединённый файл ( Кол-во скачиваний: 7 )
poisk_pyti.cpp 9,32 Kb |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 1 Всего: 32 |
Очень много букаф в прикреплённом файле, читать ооочень не хочется. Я когда-то раньше рисовал прямо на форме, а потом плюнул на всё и для каждой картиночки, что мне нужна, создаю статик. На статике рисую всё, что надо. Соответственно ты можешь создать статик, на нём рисовать свою фигуру. Контекст, на котором рисуешь где-то определён, так, что к нему есть всегда доступ. Когда нужно перетащить статик на другое окно, то убиваешь его (статик) на текущем окне и создаёшь на нужном с контекстом, что сохранил. Не знаю на сколько это правильно, но это первое, что в голову пришло.
-------------------- ![]() |
|||
|
||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
тогда может: Дочерние окна и рисование между ними?
не получается рисовать фигуру (при таскании) на главном окне, или в соседнем дочернем окне? или не получается просто передать фигуру в соседнее окно? что конкретно не получается? код лучше оформить и показать в соответствующих тегах, еще лучше показать скриншоты (такие задачи плохо воспринимаются на словах без наглядных экспонатов) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| namervasek |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
Эм.. Ну на скринах так: Вот сначала я нарисовал фигуру(в правом маленьком окошке) ![]() Потом после клика мышкой по фигуре я её перетаскиваю(красным перемещеная фигура ) ![]() Но если область фигуры заходит за пределы маленького окна то она не прорисовыватеся полностью, прорисовывается только часть внутри маленького окна(опять же выделено красным) ![]() Нужно же что бы я мог таскать мышой фигуру по все области главного окна. По коду: там собствено показывать то не чего так как в нем сейчас только рисование фигуры и перетаскивание внутри маленького окна Ну на всякий случай вот главные процедуры(это процедуры обрабытывающие сообщения маленького окна):
|
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну вот, хорошее описание, все бы так делали,
больше бы получали ответов по-существу я не понял только одного: зачем создавать объект в маленьком окне, чтобы перенести его в большое? не проще создавать в большом окне? 1. "захват объекта" чтобы таскать объект независимо от того, в каком окне он находится, нужно на WM_LBUTTONDOWN (при захвате фигуры) вызвать SetCapture, тогда сообщение WM_MOUSEMOVE будет приходить в это окно независимо от того, в пределах окна находится курсор или нет это будет продолжаться, пока не будет вызван ReleaseCapture, либо кто-то другой не перехватил инициативу (пришел WM_CAPTURECHANGED) вызвать ReleaseCapture нужно в момент, когда объект сброшен, т.е. левая кнопка мыши отпущена подробные примеры использования этих функций можно найти, используя поиск на форуме 2. "отрисовка объекта" не совсем корректная модель отрисовки перемещаемого объекта: как я понимаю, он отрисовывается не на WM_PAINT, а на WM_MOUSEMOVE на WM_MOUSEMOVE ничего рисовать не надо, достаточно подать команду на перерисовку (InvalidateRect/Rgn) а отрисовывать движение в WM_PAINT (у тебя уже есть флаг состояния Mode, вот его и тестируй в WM_PAINT) 3. "перемещение объекта" можно использовать 3 способа перемещения объекта: - перемещение самого объекта, когда на WM_MOUSEMOVE меняются его координаты - перемещение дубля (временного объекта), когда создается копия объекта и перемещается вслед за мышкой, а установка координат оригинала производится в момент его сброса на окно, тут же производится уничтожение дубля - перемещение смещения: когда при перемещении мыши, фиксируется смещение объекта, на которое он должен быть сдвинут. но сам объект не затрагивается до момента сброса, а на WM_PAINT, производится рисование этой мнимой копии объекта первый и третий варианты наиболее корректные их плюсы и минусы зависят только от скорости отрисовки сложных объектов это уже вопрос оптимизации и GUI 4. "единое начало координат" рисование в двух окнах одновременно требует установки единого измерения, в которых отрисовываются все объекты т.е., к примеру: задать для объектов начало координат в левой верхней точке большого окна, и повесить соответствующие процедуры отрисовки объектов в эти окна, которые будут пересчитывать эти виртуальные координаты на свою клиентскую область после этого, уже не важно будет, через какое окно объект протягивается, рисоваться он будет одинаково в обоих 5. "форточки" еще один вариант отрисовки в нескольких окнах - это когда на единое пространство, в котором живут все объекты можно посмотреть из разных "форточек", т.е. когда мы сами задаем положение "форточки", через которую смотрим на объекты (можно даже скроллить) для этого, каждому окну нужно задать пару [x,y], которая определяет положение левого верхнего угла нашей "форточки" в координатах пространства объектов, тогда координаты любого объекта в данной "форточке" можно получить вычитая эту пару из его координат 6. "самое простое" не использовать единого пространства, не привязываться к единому хранилищу объектов, а просто фиксировать момент сброса объекта на главном окне, в который и создавать его заново (или копировать/перемещать из маленького окна), но рисовать "плавающий" объект нужно в обоих окнах (любым из трех способов) тут, чтобы отрисовать плавающий объект в большом окне, нужно просто знать, что объект схвачен именно из маленького окна, а не из большого (завести для этого флаг), тогда можно просто пересчитывать координаты из маленького - в большое
а Invalidate... вызывать для обоих окон 7. "самый кривой" рисовать объект на нулевом девайсе, используя двойной XOR, при этом объект при перемещении будет виден как в этих двух окнах, так и в любом другом окне (имитация некоторого подобия курсора в виде объекта) ps: пункты 1,2,3 - обязательны пункт 4 - частный случай пункта 5 пункт 6 - рекомендую пункт 7 - спорный, но актуальный, по прежнему -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| namervasek |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
GremlinProg,
Спасибо большо помогло |
|||
|
||||
| namervasek |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
Эх погаричился я закрывать тему((
Все вроде бы работало пока не нашел в проге ошибку. Вот собствено она
После недолгих эксперементов понял что так делать нелязя. Ошибку исправил но теперь опять фигура рисуется не так как надо(((( Если точнее фигура рисуется, но рисутеся она нормально только на главном окне. Вот код событий этого окна
Тоесть фигура рисуется но если какая то часть это фигуры находится внутри области какого либо дочернего окона то эта часть сразу закрывается этим окном Как показал метод "тыка" фигура рисуется там где и надо но после того как обработчик WM_PAINT главного окна завершается происходит перерисовка всех дочерних окон и таким оразом они закрывают собой часть фигуры. ![]() Пытался сделать так:
По логике функция должна работать так: 1) Запомнить старую позию фигуры 2)посчитал новые координаты 3)спомощью InvalidateRgn-та затереть старую фигу по старой позиции и потом нарисовать новую с помощью OnPaint-a Но опять же дочерние окна перекрывают фигуру.... и в добавок функция не стирает старый рисунок. ![]() Из этого вытикает вопрос: как же нормально рисвоать эту фигуру????????? Полный код снизу: Присоединённый файл ( Кол-во скачиваний: 3 )
ggg.rar 4,01 Kb |
||||||
|
|||||||
| GremlinProg |
|
||||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
на главном окне ее рисовать вообще не надо, если уж ты сам решил, что тебе нужно 2 окна я конечно понимаю, что это очень большой секрет, но когда неизвестно, откуда берется A, то совсем не важно, как ее использует B, т.к. вероятность того, что код, где может содержаться ошибка ты так и не показал, близка к 100% хорошо, давай сделаем так: 1. координаты фигуры будут всегда расчитываться относительно левого верхнего угла клиентской области главного окна (вчитайся в выделенный текст, каждое слово имеет смысл) 2. ставишь обработчик WM_PAINT на большое дочернее окно так:
3. ставишь обработчик WM_PAINT на маленькое дочернее окно так:
4. процедура создания фигуры в маленьком окне, т.е. добавление очередной точки в массив точек фигуры (подразумевается, что это происходит на событие WM_LBUTTONDOWN):
5. процедура захвата объекта из маленького окна, перед перемещением (подразумевается, что это происходит на событие WM_LBUTTONDOWN) (для большого - по аналогии):
6. процедура перемещения объекта по маленькому окну (подразумевается, что это происходит на событие WM_MOUSEMOVE) (для большого - по аналогии):
вот и все в примерах я использовал stl-контейнеры для наглядности и первый способ перемещения:
hwndSmall - дескриптор маленького окна hwndLarge - дескриптор большого окна hwndFrame - дескриптор главного окна mass - массив фигур index_of_new_figure - индекс фигуры в массиве mass, которая создается в данный момент captured_figure_index - индекс фигуры в массиве mass, которая "захвачена" и в данный момент переносится pt_in_figure - простой метод определения находится ли данная точка в пределах фигуры min_xy_of_figure - простой метод нахождения левого-верхнего угла фигуры (найти среди всех координат минимальные) fix_point - глобальная точка, хранящая смещение {x,y} относительно левого-верхнего угла фигуры (в этой точке находится курсор мыши над фигурой, относительно нее и расчитываются новые координаты) вроде бы ничего не забыл когда заставишь свой код "работать", можно будет уже отвязаться от левого верхнего угла клиентской области главного окна для этого достаточно будет провести рефакторинг по всем участкам кода, содержащим MapWindowPoints и выделить собственные методы преобразования координат, очевидно, здесь требуются только 4 вида таких преобразований: small_to_mass() large_to_mass() mass_to_small() mass_to_large() подумай, чем их наполнить, в крайнем случае, привязка к главному окну ничего страшного не несет Добавлено через 14 минут и 14 секунд так, перемешал я тут местами переменные: pt и point - это одно и то же код "с коленок", так что смотри суть -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||||||||
|
|||||||||||||||
| namervasek |
|
||||||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
Эм.. такс..
А как же тогда? Может я неправльно раньше просто обьяснил- Мне нужно перетащить фигуру из маленького окна в большое, причем чтобы когда я перетаскивал фигура двигалась за курсором по все области главного окна. Код который ты привел на stl, я на нем не песал поэтому могу ошибиться но как я понял ты привел мне пример расчета координат и отрисовки самих фигур внутри дочерних окон. А это как раз я зделал и все координаты у меня расчитываются правильно как мне и надо у меня не правильно рисуется образ перетасивоемой фигуры. Образ рисуется неправильно не изза плохих координат а изза некоректной отрисовки. На случай если не правильно понял... Вот как я сделал: hwnd_form-главное окно hwnd_image-маленькое hwnd_MImage-большое p_mas-это указатель на динам масив в котором хранятся точки фигуры расположеной в мелком окне p_mas1-это тоже указатель только он служит для координат передвигаемого образа p_massize-это размера обоих масивов old_point_a-эм..... это как я понял тоже самое что у тебя fix_point Mode- режим 1=фигура в маленьком окне не нарисовна 2-фигура перетаскивается(точнее её образ) 3= фигура в маленьком окне нарисована(я подрузомиваю под этим что она замкнута) 1. Процедура занесения точек фигуры в масив (то что красным выделено не относится к формированию фигуры)
2. Процедура рисования фигуры(в смысле рисуется фигура с нуля а не готовая ) повтарюсь здесь только рисование новой фигуры поэтому на это процедуру можно не смореть, разместил только для "ознакомления"
3. Обработчик OnPaint для маленького окна(если я правлино понял разницы тут никакой нет с твоим) Здесь просто отрисовывается фигура по p_mas в маленьком окне
Дальше у меня идут процедуры главного окна так там я делаю перасчет образа фигу и отрисовываю там. 4. Движенье мыщью на главном окне(сдесь только перерасчет и вызоов WM_PAINT)
5. Обработчик OnPaint для главного окна Здесь делается тоже самое что и в OnPaint мелкого окна с той лишь разницей что здесь отрисовывается образ той фигуры котороя находится в мелком окне.
Есть еще OnMouseUp для главного окна но там ни чего не пересчитвается и не рисуется только уничтожается p_mas1 а его содиржимое переход в линейный список содержащий все фигуры расположены на большом окне после этого вызывается перерисовка главного окна. Из тех пунктов в которых ты описывал общие понятия перетаскивания раньше я выполнил 1.2.3.4 Это сообщение отредактировал(а) namervasek - 23.7.2009, 20:57 |
||||||||||||
|
|||||||||||||
| GremlinProg |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
я тебе просто показывал вариант жизни объектов на одной плоскости за двумя окнами: представь, ты находишься в доме с 2-мя окнами, и смотришь через них как по улице движется машина сначала ты увидишь ее в одном окне, потом - в другом ты же не сказал, что тебя интересует подобие варианта №7, поэтому я выбрал сам
очень жаль, поскольку, как ты сам скорее всего заметил, очень мало людей рвутся расковыривать велосипеды, в поисках той самой причины, по которой ты к нам заглянул, нужно понимать, что от наглядности кода зависит результат, на который ты расчитываешь
подумай еще раз, что ты тут делаешь, допустим, x - old_point_a.x - это смещение на каждое движение движение мыши, к примеру вправо, это смещение будет постоянно расти, а ты его еще суммируешь с текущей координатой фигуры, что выходит: переместившись вправо на 1 пиксел, фигура переместится вправо на 1 пиксел, далее, переместившись вправо еще на 1 пиксел, фигура переместится вправо уже на 2 пиксела и т.д. а теперь скажи мне, при чем тут прорисовка? почему ты так настаиваешь на проблемах именно при рисовании? ведь координаты пересчитываются неправильно как правильно, я уже показал в данном случае нельзя при расчете координат повторно использовать координаты от предыдущего шага, найди константу в фигуре и опирайся на нее (у меня эта константа - расстояние каждой точки до левого верхнего угла фигуры) в любом случае, для перемещения между окнами, ни как не взаимодействующих между собой, я бы ни в коем случае не использовал XOR-технику, т.к. любое внешнее вмешательство будет являться источником нежелательных артефактов xor удобно для временного решения логичнее было бы создание прозрачного плавающего окна - переносчика объектов с эффектом HTTRANSPARENT -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||
|
|||||||||
| namervasek |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 3.12.2007 Репутация: нет Всего: нет |
БОЖЕ КАКОЙ Я ИДИОТ
Вот как надо было сделать(сразу говорю код сырой доделывать буду)
Тоесть достаточно было просто в Move очистить экран и внем же рисовать
Так я же вот так потом делаю old_point_a.x=x; old_point_a.y=y; Тоесть как ты и говорил я сделал эту точку "начала" но она просто у меня меняется. Согласен что у меня кривовато все сделано но это только пока так Еше раз спс за помощь Если интересно код с исходником прикрепил к посту. Присоединённый файл ( Кол-во скачиваний: 6 )
ggg.rar 30,92 Kb |
||||
|
|||||
![]()
|
| Правила форума "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. |