![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Arks |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
В общих словах:
Требуется использовать двойную буферизацию. В буфере в памяти надо программно рисовать цветные примитивы (линии, треугольники). Вот таким образом я пытался реализовать двойную буферизацию по примеру с мсднки (с онлайна откуда-то):
Потом нашёл вот эту тему: CreateDIBSection - нужен пример юзания Попытался реализовать, как написано там. Вот что вышло:
Проблема в том, что CreateDIBSection возвращает NULL, т.е. ничего не создаёт. Надеюсь получить разяснения или хотя бы пример - полноценный рабочий код (ссылку на него) ![]() Это сообщение отредактировал(а) Arks - 17.9.2007, 19:50 |
||||
|
|||||
Mihhail |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 96 Регистрация: 13.9.2007 Репутация: 5 Всего: 9 |
Здесь полно мелких огрехов, они и бъют общий замысел.
Первое: почему static HDC cdc = NULL; объявляется локально? Так он при каждой перерисовке будет создаваться занова. Всё что в WM_DESTROY удаляется должно в WM_CREATE создаваться и объявляться глобально. Второе: Какая то свистопляска с указателем VOID *pvBits;. CreateDIBSection просто не получает нужного для работы. Без "наворотов" будет так: b = MyCreateDIBSection( hdc,bmp,width,height,24,pvBits,NULL ); --------------------------- BOOL MyCreateDIBSection(HDC hDC,HBITMAP m_hBitmap,UINT nWidth,UINT nHeight,WORD nBitCnt,LPVOID m_pBits,LPRGBQUAD pColors) --------------------------- m_hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,m_pBits,NULL,NULL); Третье:
Даю перевод из справки:
Т.е. EndPaint в самый конец манипуляций отрисовки, а hdc = GetDC(hWnd); это лишнее. Это сообщение отредактировал(а) Mihhail - 18.9.2007, 18:43 |
||||||
|
|||||||
Arks |
|
||||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
Нет, т.к. это статическая переменная. Впрочем, на всякий пожарный, я изменил код. Смотрите первый листинг.
Так в том то и дело, что CreateDIBSection имеет следующий прототип: HBITMAP CreateDIBSection( HDC hdc, CONST BITMAPINFO *pbmi, UINT iUsage, VOID **ppvBits, HANDLE hSection, DWORD dwOffset); Туда надо передавать void** иначе вообще не компилится. На счёт третьего, спасибо, что указали. Только один вопрос: а если рисуется за областью отсечения? Что будет? Просто не выведет на экран?
Итог: то что рисуется в cdc так и не рисуется. Нашёл странность: bmp= CreateDIBSection( ... ); if(!bmp) { MyGetLastError(hWnd); } if(!SelectObject(cdc,bmp)) { MyGetLastError(hWnd); } Вот здесь обе MyGetLastError выполняются! При этом оба раза GetLastError возвращает 0, т.е. "Операция завершена успешно". MyGetLastError:
|
||||||||
|
|||||||||
Mihhail |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 96 Регистрация: 13.9.2007 Репутация: 5 Всего: 9 |
Откуда эти сведения? Привожу выписки из справки о функции CreateDIBSection(перевод Сократа):
VOID *pvBits; тоже в глобальные!
Да, вывод осуществляется только в пределах существующих координат картинки(HBITMAP) контекста(HDC), отсекаются все попытки вывода за их пределами, как в плюс так и в минус, как в буфуре так и на экране. Можно буфер сделать больше нежели окно вывода, тогда можно будет обеспечить прокрутку изображения. Т.е. изменять координаты X и Y и вставляя их в BitBlt(hdc,0,0,width,height,cdc,X,Y,SRCCOPY) |
||||
|
|||||
Arks |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
1ый источник - компилятор, который ваш код не пропускает
![]() 2ой - МСДН:
http://msdn2.microsoft.com/en-us/library/ms532292.aspx Читать надо первоисточники. ![]() Это сообщение отредактировал(а) Arks - 19.9.2007, 14:41 |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
1) ppBits действительно должно быть указателем на LPVOID, т.е. на адрес переменной, куда положат адрес выделенного буфера.
2) Твоя MyCreateDIBSection в любом случае не будет работать (даже если секция внутри создастся).
Причина - ты передаешь возвращаемые параметры по-значению. И как ты собрался ими пользоваться?. Ты бы внимательно пост прочитал. Видмо, если CreateDIBSection возвращает 0, стало быть с параметрами что-то не так. -------------------- ... |
|||
|
||||
Arks |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
Ах, и вправду по значению. Правда, я использовал не её, а вызывал саму CreateDIBSection. Но исправил, попробовал через неё запустить. Не заработало.
Исправил, т.е. так:
Результат тот же (MyCreateDIBSection вернула 0), ничего не создалось. Меня одно смущает: почему MyGetLastError при коде ошибки 0 выводит "Операция успешно завершена." Она ведь не завершена, или по крайней мере не успешно! Если не сложно, посмотрите мою прогу сами. И не гневайтесь сильно, что туплю... Я в винапи ещё совсем плаваю. Лучше книжечку серьёзную (связанную с интерфейсом и GDI - очень нужно, т.к. весь семестр рисованием разным заниматься буду) посоветуйте. моя прога А Михаил и вправду неверные данные дал. Может конечно Сократ их покоцал? Впрочем, извиняюсь, если не очень корректно ответил. Это сообщение отредактировал(а) Arks - 19.9.2007, 20:25 |
|||
|
||||
Mihhail |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 96 Регистрация: 13.9.2007 Репутация: 5 Всего: 9 |
Действительно в справке ошибка с указателем, да и по названию переменной ppvBits можно догадаться о типе. Mea culpa! ![]() Нашёл я у себя объявление этой функции: WINGDIAPI HBITMAP WINAPI CreateDIBSection( IN HDC, IN CONST BITMAPINFO *, IN UINT, OUT VOID **, IN HANDLE, IN DWORD); Скачал я программку. У меня сначала была такая же ерунда с bmp, помогло изменение типа переменной. Вот ключевые моменты в коде:
Ещё один момент, перед заполнением структуры BITMAPINFO i; должны быть уже известны width и height! Arks у вас в задании сказано что нужна именно CreateDIBSection? А то ведь есть очень простая функция создания картинки: HBITMAP CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight ); Никаких дополнительных заморочек, только ширина и высота! ![]() Это сообщение отредактировал(а) Mihhail - 19.9.2007, 23:28 |
||||
|
|||||
Arks |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
Михаил, у меня в задания в принципе не указано, какими средствами и даже на каком языке я должен это делать. Надо чтобы программа задание выполняла, а остальное мои заботы.
![]() Кстати, с CreateCompatibleBitmap я тоже пытался написать. Только что получилось, основная ошибка и там и там, я в другом сообщении заполнял width и height. И при первом вызове WM_PAINT они были не инициализированы. Также здесь я создал VOID **m_pBits; как вы порекомендовали. Заработало. Прикол: Заработал именно вызов CreateDIBSection из WM_PAINT. При использовании же той, не моей функции, которая кучу всего делает при заполнении BITMAPINFO, она выполняется, но когда делаешь SelectObject(cdc,bmp), выкидывается ошибка "Недостаточно памяти". И это при моём гигабайте!!! ![]() Ну да ладно, главное разобрался и с CreateDIBSection, и с CreateCompatibleBitmap. Теперь остался только один вопрос: Какая разница между этими двумя функциями. Просто более широкие параметры настройки у первой? И всё? А остальное: читать, писать в созданные области памяти можно абсолютно одинаково. Так? И да, книжку по GDI (ну и ещё чему интересному) не порекомендуете? Это сообщение отредактировал(а) Arks - 20.9.2007, 07:48 |
|||
|
||||
Mihhail |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 96 Регистрация: 13.9.2007 Репутация: 5 Всего: 9 |
Да, не имеет значения какой функцией создавать область вывода. Просто CreateCompatibleBitmap использует настройки палитры и глубины цвта указанного контекста (в нашем случае экранные). В чём особенность CreateDIBSection - она даёт указатель на начало растровых данных, тот самый ppvBits, т.е. возможно менять значения байтов отдельных пикселей и их составляющих (RGB) непосредственно в памяти, что во много раз быстрее чем при вызове функций рисования, но мение удобно. К тому же с помощью этой функции есть возможность считывать изображения из файла. Моя любимая и единственная книжка по программированию - это справочная система Borland C++Builder 6! ![]() Шучу конечно, но так что бы где-то толково и полностью о GDI было написано я лично не встречал таких книг. |
|||
|
||||
Arks |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 197 Регистрация: 7.5.2006 Где: Барнаул Репутация: нет Всего: нет |
Всё ясно.
Спасибо вам за помощь. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |